工廠模式是JAVA中
最經常使用的設計模式之一
,使用工廠模式後,建立對象的時候不在將建立邏輯暴露給客戶端,而是經過實現接口的方式建立對象,這種設計模式也是對象實例化的最佳方式。html
<!-- more -->java
工廠模式的三種形態git
簡單工廠模式屬於工廠模式的小弟
,未被收納進GOF 23
中,可是也被頻繁使用編程
1.建立一個Animal
接口設計模式
interface Shape { void draw(); }
2.建立Dog
和Pig
實現Animal
接口微信
class Circle implements Shape { public Circle() { System.out.println("建立圓形模型"); } @Override public void draw() { System.out.println("畫了一個圓形"); } } class Square implements Shape { public Square() { System.out.println("建立了方形模型"); } @Override public void draw() { System.out.println("畫了一個方形"); } }
3.建立工廠類SimpleFactory
,定義一個基於參數信息實例化具體對象的方法ide
public class SimpleFactory { private final static String CIRCLE = "CIRCLE"; private final static String SQUARE = "SQUARE"; public static Shape getFactory(String type) { switch (type) { case CIRCLE: return new Circle(); case SQUARE: return new Square(); default: throw new NullPointerException("未描繪任何圖形"); } } public static void main(String[] args) { Shape circle = SimpleFactory.getFactory(CIRCLE); circle.draw(); Shape square = SimpleFactory.getFactory(SQUARE); square.draw(); } }
4.日誌測試
建立圓形模型 畫了一個圓形 建立了方形模型 畫了一個方形
分析: 從上述代碼中能夠發現,簡單工廠
擁有必定判斷能力,構建結果取決於入參,使用起來也十分的方便,也正由於使用太過方便
而致使高耦合
的狀況,全部對象實例化都須要依賴它,一旦出問題,影響的會是整個系統spa
使用場景: 建立簡單,無複雜業務邏輯的對象操作系統
前面說到過簡單工廠模式
存在耦合,且違反了開閉原則
,那麼這一問題在工廠方法模式
中能夠很容易的解決掉,它能夠作到添加新的產品而不破壞已有代碼
工廠方法模式
:定義一個建立對象的接口,由它的實現類來決定具體實現,其模式又被稱爲工廠模式(Factory Pattern)
。
1.新增ImageReaderFactory
抽象工廠接口,用來構建具體的對象
interface ImageReader { void read(); } interface ImageReaderFactory { ImageReader create(); }
2.相比單一實例化的簡單工廠模式
而言,方法工廠模式
更加的靈活,針對不一樣的產品(圖片讀取器)
提供不一樣的工廠。
class JpgReader implements ImageReader { public JpgReader() { System.out.println("建立Jpg讀取器"); } @Override public void read() { System.out.println("讀取Jpg文件"); } } class PngReader implements ImageReader { public PngReader() { System.out.println("建立Png讀取器"); } @Override public void read() { System.out.println("讀取Png文件"); } } class JpgFactory implements ImageReaderFactory { @Override public ImageReader create() { System.out.println("實例化Jpg文件工廠"); return new JpgReader(); } } class PngFactory implements ImageReaderFactory { @Override public ImageReader create() { System.out.println("實例化Png文件工廠"); return new PngReader(); } }
3.建立測試類,固然實際使用過程當中,實現工廠方法
除了能夠實例化具體對象,還能夠初始化某些資源配置,好比鏈接池、建立文件等
public class MethodFactory { public static void main(String[] args) { ImageReaderFactory png = new PngFactory(); ImageReader pngReader = png.create(); pngReader.read(); ImageReaderFactory jpg = new JpgFactory(); ImageReader jpgReader = jpg.create(); jpgReader.read(); } }
4.日誌
實例化Png文件工廠 建立Png讀取器 讀取Png文件 實例化Jpg文件工廠 建立Jpg讀取器 讀取Jpg文件
優勢:
產品(圖片讀取器)
,無需更改現有代碼,提升系統擴展性,符合開閉原則
多態性
,又被稱爲多態工廠模式
缺點: 每次須要編寫新的對象和對象工廠類
,隨業務發展,必定程度上增長了系統複雜度
抽象工廠模式
是爲建立一組對象提供提供的解決方案,與工廠方法模式相比
,抽象工廠模式中的具體工廠不僅是建立某一種產品,而是負責一組(產品族)。抽象工廠模式(Abstract Factory Pattern)
:提供了建立一系列相互依賴對象的接口,無需指定具體類抽象工廠模式
是圍繞着一個超級工廠工做,創造其它的工廠類,也被稱爲工廠的工廠
,這種類型的設計模式是創造性的模式,由於這種模式提供了建立對象的最佳方法之一。抽象工廠模式
的起源或者最先的應用,是用於建立分屬於不一樣操做系統的視窗構建。好比:命令按鍵(Button)與文字框(Text)都是視窗構建,在UNIX操做系統的視窗環境和Windows操做系統的視窗環境中,這兩個構建有不一樣的本地實現,它們的細節有所不一樣。
在每個操做系統中,都有一個視窗構建組成的構建家族。在這裏就是Button和Text組成的產品族。而每個視窗構件都構成本身的等級結構,由一個抽象角色給出抽象的功能描述,而由具體子類給出不一樣操做系統下的具體實現。
能夠發如今上面的產品類圖中,有兩個產品的等級結構,分別是Button等級結構和Text等級結構。同時有兩個產品族,也就是UNIX產品族和Windows產品族。UNIX產品族由UNIX Button和UNIX Text產品構成;而Windows產品族由Windows Button和Windows Text產品構成。
系統對產品對象的建立需求由一個工程的等級結構知足,其中有兩個具體工程角色,即UnixFactory和WindowsFactory。UnixFactory對象負責建立Unix產品族中的產品,而WindowsFactory對象負責建立Windows產品族中的產品。這就是抽象工廠模式的應用,抽象工廠模式的解決方案以下圖:
顯然,一個系統只可以在某一個操做系統的視窗環境下運行,而不能同時在不一樣的操做系統上運行。因此,系統實際上只能消費屬於同一個產品族的產品。
在現代的應用中,抽象工廠模式的使用範圍已經大大擴大了,再也不要求系統只能消費某一個產品族了。所以,能夠沒必要理會前面所提到的原始用意。
摘抄自《JAVA與模式》之抽象工廠模式:http://www.cnblogs.com/java-my-life/archive/2012/03/28/2418836.html
需求: 開發一款《王者榮耀》,支持多操做系統和多控制方式操做控制
和界面控制
,並提供相應的工廠類來封裝這些類的初始化過程
1.建立不一樣的操做系統接口
interface Linux { void controller(); } interface Windows { void controller(); }
2.基於不一樣操做系統實現控制邏輯
class LinuxController implements Linux { @Override public void controller() { System.out.println("Linux 控制 《王者榮耀》"); } } class WindowsController implements Windows { @Override public void controller() { System.out.println("Windows 控制 《王者榮耀》"); } }
3.建立一個工廠類,基於接口分別實現操做控制
和界面控制
兩種方式的工廠
interface AbstractFactory { Linux installLinux(); Windows installWindows(); } class OperationFactory implements AbstractFactory { @Override public Linux installLinux() { System.out.println("安裝Linux操做控制系統"); return new LinuxController(); } @Override public Windows installWindows() { System.out.println("安裝Windows操做控制系統"); return new WindowsController(); } } class InterfaceFactory implements AbstractFactory { @Override public Linux installLinux() { System.out.println("安裝Linux界面控制系統"); return new LinuxController(); } @Override public Windows installWindows() { System.out.println("安裝Windows界面控制系統"); return new WindowsController(); } }
4.建立《王者榮耀》進行測試
public class KingGlory { public static void main(String[] args) { AbstractFactory operationFactory = new OperationFactory(); operationFactory.installLinux().controller(); operationFactory.installWindows().controller(); System.out.println("========================================================"); AbstractFactory interfaceFactory = new InterfaceFactory(); interfaceFactory.installLinux().controller(); interfaceFactory.installWindows().controller(); } }
5.日誌
安裝Linux操做控制系統 Linux 控制 《王者榮耀》 安裝Windows操做控制系統 Windows 控制 《王者榮耀》 ======================================================== 安裝Linux界面控制系統 Linux 控制 《王者榮耀》 安裝Windows界面控制系統 Windows 控制 《王者榮耀》
使用抽象工廠模式
來定義的一系列對象一般是相關或相互依賴的,這些產品對象就構成了一個產品族
,也就是抽象工廠定義了一個產品族
。這就帶來很是大的靈活性,切換產品族的時候,只要提供不一樣的抽象工廠實現就能夠了,也就是說如今是以一個產品族做爲一個總體被切換,從上文中能夠發現,若是咱們須要切換控制方式
,只須要變動下對應的工廠類便可
優勢:
開閉原則
,只須要增長具體產品並對應增長一個新的具體工廠,對已有代碼無須作任何修改(如:新增一種手柄操做支持)。缺點:
Factory
代碼須要所有修改)。使用場景:
全文代碼:https://gitee.com/battcn/design-pattern/tree/master/Chapter1/battcn-factory
微信公衆號:battcn
(歡迎調戲)