首先說明,文章較長,保證你有耐心看完肯定能懂,沒耐心直接點×即可。
抽象工廠模式,是創建型設計模式之一。抽象型工廠模式適合產品確定,產品線不確定的類型,怎麼講?通過一個具體例子來講一下吧。例如某電腦廠商要生產電腦,也就是電腦這個產品確定,而電腦配置不確定,這種情況可以用抽象工廠模式來解決。
代碼實現完全結合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();
}
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處理器");
}
}
package com.factory.demo;
public class LenovoMainBoard implements MainBoard {
@Override
public void mainboard() {
System.out.println("華碩主板");
}
}
package com.factory.demo;
public class ASUSMainBoard implements MainBoard {
@Override
public 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("金士頓內存");
}
}
package com.factory.demo;
public class Computer1 extends ComputerFactory {
/**
* 組裝電腦1,用的i3處理器、聯想的主板和三星的內存
* @return
*/
@Override
public CPU createCPU() {
return new I3CPU();
}
@Override
public MainBoard createMainBoard() {
return new LenovoMainBoard();
}
@Override
public RAM createRAM() {
return new SamsungRAM();
}
}
具體工廠類2,Computer2繼承抽象工廠類(對應UML類圖中的Factory2):
package com.factory.demo;
public class Computer2 extends ComputerFactory {
/**
* 組裝電腦2,用的i5處理器、華碩的主板和金士頓的內存
* @return
*/
@Override
public CPU createCPU() {
return new I5CPU();
}
@Override
public MainBoard createMainBoard() {
return new ASUSMainBoard();
}
@Override
public RAM createRAM() {
return new KingStoneRAM();
}
}
這時創建一個測試類:
package com.factory.demo;
public class TestFactory {
public static void main(String[] args) {
//電腦1
ComputerFactory computer1=new Computer1();
System.out.println("組裝產品類型1:");
computer1.createCPU().cpu();
computer1.createMainBoard().mainboard();
computer1.createRAM().ram();
//電腦2
ComputerFactory 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處理器");
}
}
package com.factory.demo;
public class Computer3 extends ComputerFactory {
/**
* 組裝電腦3,i7 CPU+華碩主板+金士頓內存
* @return
*/
@Override
public CPU createCPU() {
return new I7CPU();
}
@Override
public MainBoard createMainBoard() {
return new ASUSMainBoard();
}
@Override
public RAM createRAM() {
return new KingStoneRAM();
}
}
package com.factory.demo;
public class TestFactory {
public static void main(String[] args) {
//電腦1
ComputerFactory computer1=new Computer1();
System.out.println("組裝產品類型1:");
computer1.createCPU().cpu();
computer1.createMainBoard().mainboard();
computer1.createRAM().ram();
//電腦2
ComputerFactory computer2=new Computer2();
System.out.println("組裝產品類型2:");
computer2.createCPU().cpu();
computer2.createMainBoard().mainboard();
computer2.createRAM().ram();
//電腦3
ComputerFactory computer3=new Computer3();
System.out.println("組裝產品類型3:");
computer3.createCPU().cpu();
computer3.createMainBoard().mainboard();
computer3.createRAM().ram();
}
}
可以看出來擴展生產線變得很容易,系統擴展性大大增強。