Java與設計模式-抽象原廠模式解析
首先說明,文章較長,保證你有耐心看完肯定能懂,沒耐心直接點×即可。
抽象原廠模式,是建立型設計模式之一。抽象型原廠模式適合產品確定,產品線不確定的類型,怎麼講?通過一個具體例子來講一下吧。例如某電腦廠商要生產電腦,也就是電腦這個產品確定,而電腦配置不確定,這種情況可以用抽象原廠模式來解決。
代碼實現完全結合UML類圖,結合圖就可以完成系統建立。
本執行個體裡是抽象類別ComputerFactory(對應UML類圖中的AbstractFactory):
package com.factory.demo;public abstract class ComputerFactory {public abstract CPU createCPU();public abstract MainBoard createMainBoard();public abstract RAM createRAM();}有三個方法,生產CPU,生產主板和生產記憶體。
產品抽象介面,CPU(對應UML類圖中的ProductA):
package com.factory.demo;public interface CPU {void cpu();}產品抽象介面,主板(對應UML類圖中的ProductB):
package com.factory.demo;public interface MainBoard { void mainboard(); }產品抽象介面,記憶體((對應UML類圖中的ProductC)):
package com.factory.demo;public interface RAM {void ram();}
下面是具體產品,CPU的I3(對應UML類圖中的ProductA1):
package com.factory.demo;public class I3CPU implements CPU {public void cpu() {System.out.println("i3處理器");}}具體產品,CPU的I5(對應UML類圖中的ProductA2):
package com.factory.demo;public class I5CPU implements CPU {public void cpu() {System.out.println("i5處理器");}}
具體產品,主板 聯想主板(對應UML類圖中的ProductB1):
package com.factory.demo;public class LenovoMainBoard implements MainBoard {@Overridepublic void mainboard() {System.out.println("華碩主板");}}
具體產品,主板 華碩主板(對應UML類圖中的ProductB2):
package com.factory.demo;public class ASUSMainBoard implements MainBoard {@Overridepublic void mainboard() {System.out.println("聯想主板");}}具體產品 記憶體 三星記憶體(對應UML類圖中的ProductC1):
package com.factory.demo;public class SamsungRAM implements RAM {public void ram() {System.out.println("三星記憶體");}}具體產品,記憶體 金士頓記憶體(對應UML類圖中的ProductC2):
package com.factory.demo;public class KingStoneRAM implements RAM {public void ram() {System.out.println("金士頓記憶體");}}
具體工廠類1,Computer1繼承抽象工廠類(對應UML類圖中的Factory1):
package com.factory.demo;public class Computer1 extends ComputerFactory {/** * 組裝電腦1,用的i3處理器、聯想的主板和三星的記憶體 * @return */@Overridepublic CPU createCPU() {return new I3CPU();}@Overridepublic MainBoard createMainBoard() {return new LenovoMainBoard();}@Overridepublic RAM createRAM() {return new SamsungRAM();}}
具體工廠類2,Computer2繼承抽象工廠類(對應UML類圖中的Factory2):
package com.factory.demo;public class Computer2 extends ComputerFactory {/** * 組裝電腦2,用的i5處理器、華碩的主板和金士頓的記憶體 * @return */@Overridepublic CPU createCPU() {return new I5CPU();}@Overridepublic MainBoard createMainBoard() {return new ASUSMainBoard();}@Overridepublic RAM createRAM() {return new KingStoneRAM();}}
這時建立一個測試類別:
package com.factory.demo;public class TestFactory {public static void main(String[] args) {//電腦1ComputerFactory computer1=new Computer1();System.out.println("組裝產品類型1:");computer1.createCPU().cpu();computer1.createMainBoard().mainboard();computer1.createRAM().ram();//電腦2ComputerFactory computer2=new Computer2();System.out.println("組裝產品類型2:");computer2.createCPU().cpu();computer2.createMainBoard().mainboard();computer2.createRAM().ram();}}
總結一下:上面每一個類或介面都對應了UML類圖中的每一個元素,可以參照UML類圖構建系統。本系統好處是分離了介面和實現,實現產品下種類切換時十分靈活容易(也就是再製作一條產品Computer3的生產線很容易)。缺點也是顯而易見,會造成類爆炸性增長。
還有一個缺點就是不容易增加其他產品類,增加一個產品類就需要修改抽象工廠,那麼所有具體工廠類也必須被修改。
下面我們看一下如何增加一條Computer3的生產線:
Computer3的配置是i7 CPU+華碩主板+金士頓記憶體。這時我們首先要實現一個i7的CPU(對應UML類圖中的ProductA3):
package com.factory.demo;public class I7CPU implements CPU {public void cpu() {System.out.println("i7處理器");}}
然後是具體工廠類3,Computer3繼承抽象工廠類(對應UML類圖中的Factory3):
package com.factory.demo;public class Computer3 extends ComputerFactory {/** * 組裝電腦3,i7 CPU+華碩主板+金士頓記憶體 * @return */@Overridepublic CPU createCPU() {return new I7CPU();}@Overridepublic MainBoard createMainBoard() {return new ASUSMainBoard();}@Overridepublic RAM createRAM() {return new KingStoneRAM();}}
測試類別增加Computer3的代碼,增加後如下:
package com.factory.demo;public class TestFactory {public static void main(String[] args) {//電腦1ComputerFactory computer1=new Computer1();System.out.println("組裝產品類型1:");computer1.createCPU().cpu();computer1.createMainBoard().mainboard();computer1.createRAM().ram();//電腦2ComputerFactory computer2=new Computer2();System.out.println("組裝產品類型2:");computer2.createCPU().cpu();computer2.createMainBoard().mainboard();computer2.createRAM().ram();//電腦3ComputerFactory computer3=new Computer3();System.out.println("組裝產品類型3:");computer3.createCPU().cpu();computer3.createMainBoard().mainboard();computer3.createRAM().ram();}}
可以看出來擴充生產線變得很容易,系統擴充性大大增強。