關注公衆號 JavaStorm 獲取更多精彩java
工廠方法(Factory Method)模式的意義是定義一個建立產品對象的工廠接口,將實際建立工做推遲到子類當中。核心工廠類再也不負責產品的建立,這樣核心類成爲一個抽象工廠角色,僅負責具體工廠子類必須實現的接口,這樣進一步抽象化的好處是使得工廠方法模式可使系統在不修改具體工廠角色的狀況下引進新的產品。spring
看下 GOF爲工廠模式的定義:數據庫
「Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.」(在基類中定義建立對象的一個接口,讓子類決定實例化哪一個類。工廠方法讓一個類的實例化延遲到子類中進行。)設計模式
其實這個並不算設計模式,適合建立簡單對象,建立的對象較少。客戶端不關心對象的建立過程。微信
建立發送器接口,也就是產品角色ide
public interface Sender { /** * 發送信息 * @param to 收件人 * @param msg 消息 * @return */ boolean send(String to, String msg); }
建立具體產品,分別是郵件發送器、短信發送器。單元測試
public class MailSender implements Sender { @Override public boolean send(String to, String msg) { System.out.println("MailSender:收件人:" + to + ",消息爲:" + msg); return true; } } public class SmsSender implements SenderService { @Override public boolean send(String to, String msg) { System.out.println("SmsSender:收件人:" + to + ",消息爲:" + msg); return true; } }
建立簡單工廠測試
/** * 工廠類,建立實例對象。缺點當字符串輸錯則得不到對象 * @author unique * */ public class SendFactory { public Sender getObject(String type) { Sender sender = null; switch (type) { case "mail": senderService = new MailSender(); break; case "sms": senderService = new SmsSender(); break; default: System.out.println("請輸入正確類型"); break; } return sender; } }
單元測試this
public class SimpleFactoryTest { public static void main(String[] args) { SendFactory factory = new SendFactory(); Sender sender = factory.getObject("mail"); sender.send("大兄弟", "你是最棒的!"); } }
當咱們新增產品類的時候,就須要修改工廠類中的 getObject() 方法,不符合 開放-封閉原則。設計
工廠模式中使用最多的一種。
與簡單公差個模式最大的區別就是咱們再也不提供一個統一的工廠來建立全部的產品,二十針對不一樣的產品提供不一樣的工廠。也就是每一個產品都有一個與之對應的工廠。
基於上面的簡單工廠,咱們改造下。新建一個抽象工廠角色
public interface SenderFactory { /** * 生成對象 * @return */ public Sender getObject(); }
增長短信、郵件工廠類,實現抽象工廠接口。
public class SendMailFactory implements SenderFactory { @Override public Sender getObject() { return new MailSender(); } } public class SendSmsFactory implements SenderFactory { @Override public Sender getObject() { return new SmsSenderServiceImpl(); } }
測試代碼
public class Test { public static void main(String[] args) { SenderFactory senderFactory = new SendMailFactory(); Sender sender = senderFactory.getObject(); sender.send("大兄弟", "你是最棒的!"); } }
在工廠方法模式中,其實咱們有一個潛在乎識的意識。那就是咱們生產的都是同一類產品。抽象工廠模式是工廠方法的僅一步深化,在這個模式中的工廠類不僅僅能夠建立一種產品,而是能夠建立一組產品。這個產品會依賴多個合成一個。好比咱們的電腦廠商 有因特爾和AMD 生產的主板與CPU。這個產品族有CPU跟主板。
抽象工廠模式和工廠方法模式同樣,都符合開放-封閉原則。可是不一樣的是,工廠方法模式在增長一個具體產品的時候,都要增長對應的工廠。可是抽象工廠模式只有在新增一個類型的具體產品時才須要新增工廠。也就是說,工廠方法模式的一個工廠只能建立一個具體產品。而抽象工廠模式的一個工廠能夠建立屬於一類類型的多種具體產品。工廠建立產品的個數介於簡單工廠模式和工廠方法模式之間。
抽象工廠方法模式的角色與工廠方法模式一致
咱們的電腦有主板、CPU、內存…組成。這些都是產品,如今提供一個工廠,直接同時生產出 CPU與對應的主板,避免單獨去建立。也就是所謂的一套,一個系列。
好比 有因特爾工廠出品的 CPU 與 主板,AMD 工廠出品的 CPU 與主板。
定義CPU 與主板兩個產品
public interface CPU { void calculate(); } public interface Mainboard { void installCPU(); }
以及產品的具體實現,好比 AMD 公司出品的、因特爾公司出品的 CPU 與主板
public class AmdCpu implements CPU { /** * CPU的針腳數 */ private int pins = 0; public AmdCpu(int pins) { this.pins = pins; } @Override public void calculate() { System.out.println("AMD CPU的針腳數:" + pins); } } public class IntelCPU implements CPU { /** * CPU的針腳數 */ private int pins = 0; public IntelCPU(int pins) { this.pins = pins; } @Override public void calculate() { System.out.println("Intel CPU的針腳數:" + pins); } } public class AmdMainboard implements Mainboard { /** * CPU插槽的孔數 */ private int cpuHoles = 0; /** * 構造方法,傳入CPU插槽的孔數 * * @param cpuHoles */ public AmdMainboard(int cpuHoles) { this.cpuHoles = cpuHoles; } @Override public void installCPU() { // TODO Auto-generated method stub System.out.println("AMD主板的CPU插槽孔數是:" + cpuHoles); } } public class IntelMainboard implements Mainboard { /** * CPU插槽的孔數 */ private int cpuHoles = 0; /** * 構造方法,傳入CPU插槽的孔數 * * @param cpuHoles */ public IntelMainboard(int cpuHoles) { this.cpuHoles = cpuHoles; } @Override public void installCPU() { System.out.println("Intel主板的CPU插槽孔數是:" + cpuHoles); } }
接着咱們先建立一個抽象工廠角色,能生產 CPU 與主板系列產品的工廠方法定義。
public interface MainboardCPUFactory { /** * 建立CPU對象 * * @return CPU對象 */ public CPU createCpu(); /** * 建立主板對象 * * @return 主板對象 */ public Mainboard createMainboard(); }
因特爾工廠定義
public class IntelFactory implements MainboardCPUFactory { @Override public CPU createCpu() { return new IntelCPU(755); } @Override public Mainboard createMainboard() { return new IntelMainboard(755); } }
AMD 工廠
public class AmdFactory implements MainboardCPUFactory { @Override public CPU createCpu() { return new AmdCpu(938); } @Override public Mainboard createMainboard() { return new AmdMainboard(938); } }
最後咱們來測試
public class AbstactFactoryTest { public static void main(String[] args) { //使用因特爾工廠生產 MainboardCPUFactory intelFactory = new IntelFactory(); CPU cpu = intelFactory.createCpu(); Mainboard mainboard = intelFactory.createMainboard(); mainboard.installCPU(); cpu.calculate(); } }
打印
Intel主板的CPU插槽孔數是:755 Intel CPU的針腳數:755
關注公衆號 JavaStorm 給你更多精彩。