Java设计模式-工厂模式(1)简单工厂模式
Java設計模式-工廠模式(1)簡單工廠模式
- 一、前言
- 1)例子
- 2)類圖關系
- 3)代碼實現(xiàn)
- 二、簡單工廠模式
- 2.1、概述:
- 2.2、類圖關系:
- 2.3、代碼修改:
- 2.4、優(yōu)缺點
- 2.5、擴展-簡單靜態(tài)工廠
- 2.6、擴展-簡單工廠+配置文件解除耦合
- 三、結語
Java設計模式-工廠模式(1)簡單工廠模式)
一、前言
我們先別急著想工廠模式是什么樣的啊
先看看下面這個例子啊,怎么設計,如何寫,才能更好。
一步一步引出Java工廠模式。
1)例子
需求:設計一個咖啡店點餐系統(tǒng)。
設計一個咖啡類(Coffee),并定義其兩個子類(美式咖啡【AmericanCoffee】和拿鐵咖啡【LatteCoffee】);再設計一個咖啡店類(CoffeeStore),咖啡店具有點咖啡的功能。
代碼是比較簡單的,我這是采取一步一步引入的,如果不喜歡,可以直接看下文。
我們先用曾經(jīng)的方式來設計和進行代碼的編寫。
2)類圖關系
3)代碼實現(xiàn)
我們先用以前的方式來實現(xiàn)一遍哈。
1、先寫好Coffee這個抽象類
public abstract class Coffee {public abstract void addMilk();public abstract void addSugar();public abstract String getName(); }2、再寫好美式咖啡和拿鐵咖啡繼承Coffee抽象類
public class AmericanCoffee extends Coffee {@Overridepublic void addMilk() { System.out.println("給咖啡加奶"); }@Overridepublic void addSugar() { System.out.println("給咖啡加糖"); }@Overridepublic String getName() { return "美式咖啡"; } } public class LatteCoffee extends Coffee {@Overridepublic void addMilk() { System.out.println("給咖啡加奶"); }@Overridepublic void addSugar() { System.out.println("給咖啡加糖"); }@Overridepublic String getName() { return "拿鐵咖啡"; } }3、咖啡店
public class CoffeeStore {public Coffee createCoffee(String type){Coffee coffee = null;if("americano".equals(type)) {coffee = new AmericanCoffee();} else if("latte".equals(type)) {coffee = new LatteCoffee();}coffee.addMilk();coffee.addSugar();return coffee;} }4、寫個客戶端來測試點咖啡哈
public class Client {public static void main(String[] args) {CoffeeStore coffeeStore = new CoffeeStore();Coffee coffee = coffeeStore.createCoffee("americano");System.out.println(coffee.getName());/*** 輸出:* 給咖啡加奶* 給咖啡加糖* 美式咖啡*/} }其實乍一看沒啥問題,但是如果我這個需要增加幾種咖啡,你說該如何才合適勒?
是不是需要修改CoffeeStore的代碼。又如果要開設美團外賣點單呢?又如何改呢?
在java中,萬物皆對象。
如果創(chuàng)建的時候直接new該對象,就會對該對象耦合嚴重,假如我們要更換對象,所有new對象的地方都需要修改一遍,這顯然違背了軟件設計的開閉原則。(而且這種重復工作簡直想死)
如果我們使用工廠來生產(chǎn)對象,我們就只和工廠打交道就可以了,徹底和對象解耦,如果要更換對象,直接在工廠里更換該對象即可,達到了與對象解耦的目的;所以說,工廠模式最大的優(yōu)點就是:解耦。
接下來就出現(xiàn)了簡單工廠模式(簡單工廠模式并非23種經(jīng)典模式之內(nèi),更像是一種編程習慣吧)。😁
二、簡單工廠模式
2.1、概述:
簡單工廠模式是屬于創(chuàng)建型模式,又叫做靜態(tài)工廠方法(Static Factory Method)模式,但不屬于23種GOF設計模式之一。簡單工廠模式是由一個工廠對象決定創(chuàng)建出哪一種產(chǎn)品類的實例。簡單工廠模式是工廠模式家族中最簡單實用的模式,可以理解為是不同工廠模式的一個特殊實現(xiàn)。
簡單工廠包含如下角色:
- 抽象產(chǎn)品 :定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能。 (例子中的咖啡)
- 具體產(chǎn)品 :實現(xiàn)或者繼承抽象產(chǎn)品的子類 (例子中的美式咖啡、拿鐵咖啡等)
- 具體工廠 :提供了創(chuàng)建產(chǎn)品的方法,調(diào)用者通過該方法來獲取產(chǎn)品。 (一個來創(chuàng)建對象的工廠)
使用場景
工廠類負責創(chuàng)建的對象比較少;
客戶只知道傳入工廠類的參數(shù),對于如何創(chuàng)建對象(邏輯)不關心;
2.2、類圖關系:
簡單來說就是在原有的設計上加了一層(沒有什么是加一層解決不了的,不行就加兩層(狗頭保命))😁
2.3、代碼修改:
就在原有基礎上做了一些修改:
增加一個SimpleCoffeeFactory類,在這個地方進行對象的創(chuàng)建。😀
public class SimpleCoffeeFactory {public Coffee createCoffee(String type) {Coffee coffee = null;if("americano".equals(type)) {coffee = new AmericanCoffee();} else if("latte".equals(type)) {coffee = new LatteCoffee();}return coffee;} }再修改一下CoffeeStore類
public class CoffeeStore {public Coffee createCoffee(String type){SimpleCoffeeFactory factory = new SimpleCoffeeFactory();Coffee coffee = factory.createCoffee(type);coffee.addMilk();coffee.addSugar();return coffee;} }看起來好像只是把創(chuàng)建對象的權力給到了SimpleCoffeeFactory,沒有什么其他操作,但是就是這個SimpleCoffeeFactory工廠類,已經(jīng)將CoffeeStore類和Coffee對象解耦了,CoffeeStore不再需要管具體產(chǎn)品對象是如何創(chuàng)建的,只需要負責自己的事情就可以了,明確了各自的職責和權利,有利于整個軟件體系結構的優(yōu)化
總結:
工廠(factory)處理創(chuàng)建對象的細節(jié),有了SimpleCoffeeFactory,CoffeeStore類中的orderCoffee()就變成此對象的客戶,后期如果需要Coffee對象直接從工廠中獲取即可。這樣也就解除了和Coffee實現(xiàn)類的耦合,但同時又產(chǎn)生了新的耦合,CoffeeStore對象和SimpleCoffeeFactory工廠對象的耦合,工廠對象和商品對象的耦合。
后期如果再加新品種的咖啡,我們勢必要需求修改SimpleCoffeeFactory的代碼,違反了開閉原則。
工廠類的客戶端可能有很多,比如創(chuàng)建美團外賣等,這樣只需要修改工廠類的代碼,省去其他的修改操作。
2.4、優(yōu)缺點
優(yōu)點:
封裝了創(chuàng)建對象的過程,可以通過參數(shù)直接獲取對象。把對象的創(chuàng)建和業(yè)務邏輯層分開,這樣以后就避免了修改客戶代碼,如果要實現(xiàn)新產(chǎn)品直接修改工廠類,而不需要在原代碼中修改,這樣就降低了客戶代碼修改的可能性,更加容易擴展。
工廠類是整個模式的關鍵.包含了必要的邏輯判斷,根據(jù)外界給定的信息,決定究竟應該創(chuàng)建哪個具體類的對象.通過使用工廠類,外界可以從直接創(chuàng)建具體產(chǎn)品對象的尷尬局面擺脫出來,僅僅需要負責“消費”對象就可以了。而不必管這些對象究竟如何創(chuàng)建及如何組織的.明確了各自的職責和權利,有利于整個軟件體系結構的優(yōu)化。
缺點:
當系統(tǒng)中的具體產(chǎn)品類不斷增多時候,可能會出現(xiàn)要求工廠類根據(jù)不同條件創(chuàng)建不同實例的需求.這種對條件的判斷和對具體產(chǎn)品類型的判斷交錯在一起,很難避免模塊功能的蔓延,對系統(tǒng)的維護和擴展非常不利,違背了“開閉原則”。
2.5、擴展-簡單靜態(tài)工廠
在開發(fā)中也有一部分人將工廠類中的創(chuàng)建對象的功能定義為靜態(tài)的,這個就是靜態(tài)工廠模式,它也不是23種設計模式中的。代碼如下
public class SimpleCoffeeFactory {public static Coffee createCoffee(String type) {Coffee coffee = null;if("americano".equals(type)) {coffee = new AmericanoCoffee();} else if("latte".equals(type)) {coffee = new LatteCoffee();}return coffe;} }2.6、擴展-簡單工廠+配置文件解除耦合
可以通過工廠模式+配置文件的方式解除工廠對象和產(chǎn)品對象的耦合。
在工廠類中加載配置文件中的全類名,并創(chuàng)建對象進行存儲,客戶端如果需要對象,直接進行獲取即可。
定義一個配置文件 my.properties
american=com.crush.factory.simple_factory_properties.AmericanCoffee latte=com.crush.factory.simple_factory_properties.LatteCoffee改進工廠類
public class CoffeeFactory {private static Map<String,Coffee> map = new HashMap();static {Properties p = new Properties();InputStream is = CoffeeFactory.class.getClassLoader().getResourceAsStream("my.properties");try {p.load(is);//遍歷Properties集合對象Set<Object> keys = p.keySet();for (Object key : keys) {//根據(jù)鍵獲取值(全類名)String className = p.getProperty((String) key);//獲取字節(jié)碼對象Class clazz = Class.forName(className);Coffee obj = (Coffee) clazz.newInstance();map.put((String)key,obj);}} catch (Exception e) {e.printStackTrace();}}public static Coffee createCoffee(String name) {return map.get(name);} }靜態(tài)成員變量用來存儲創(chuàng)建的對象(鍵存儲的是名稱,值存儲的是對應的對象),而讀取配置文件以及創(chuàng)建對象寫在靜態(tài)代碼塊中,目的就是只需要執(zhí)行一次。
這種方式用的也很多,常見也很簡單。
三、結語
這個簡單工廠并不完善,增加新產(chǎn)品時還是需要修改工廠類的代碼,違背了“開閉原則”,所以才有了后文的工廠模式、抽象工廠模式。
持續(xù)更新中哦。
總結
以上是生活随笔為你收集整理的Java设计模式-工厂模式(1)简单工厂模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你给你的Typore配置图床了吗?没有的
- 下一篇: Java设计模式-工厂模式(2)工厂方法