設計模式學習筆記(3) --工廠方法
1.定義:
工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多型工廠(Polymorphic Factory)模式,它屬於類建立型模式。在工廠方法模式中,工廠父類負責定義建立產品物件的公共介面,而工廠子類則負責生成具體的產品物件,這樣做的目的是將產品類的例項化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該例項化哪一個具體產品類。工廠方法是對簡單工廠的改進版。
2.UML圖:
3.程式碼:
package com.skiff.www.factory.factorymethod.producetv; /** * @author 一葉扁舟(skiff) * @ClassName: TV * @Description: * @create 2018-08-03 15:22 **/ //Product:抽象產品 public interface TV { public void play(); }
package com.skiff.www.factory.factorymethod.producetv; /** * @author 一葉扁舟(skiff) * @ClassName: HaierTV * @Description: * @create 2018-08-03 15:23 **/ //ConcreteProduct:具體產品 public class HaierTV implements TV { @Override public void play() { System.out.println("正在觀看海爾電視機。。。。。"); } }
package com.skiff.www.factory.factorymethod.producetv;
/**
* @author 一葉扁舟(skiff)
* @ClassName: TVFactory
* @Description:
* @create 2018-08-03 15:22
**/
//Factory:抽象工廠
public interface TVFactory {
public TV produceTV();
}
package com.skiff.www.factory.factorymethod.producetv; /** * @author 一葉扁舟(skiff) * @ClassName: HaierFactory * @Description: * @create 2018-08-03 15:24 **/ //ConcreteFactory:具體工廠 public class HaierFactory implements TVFactory { @Override public TV produceTV() { return new HaierTV(); } }
package com.skiff.www.factory.factorymethod.producetv;
import org.junit.Test;
/**
* @author 一葉扁舟(skiff)
* @ClassName: TestFactoryMethod
* @Description:
模式結構
工廠方法模式包含如下角色:
Product:抽象產品
ConcreteProduct:具體產品
Factory:抽象工廠
ConcreteFactory:具體工廠
* @create 2018-08-03 15:25
**/
public class TestFactoryMethod {
@Test
public void testTV(){
TVFactory haierFactory = new HaierFactory();
TV tv = haierFactory.produceTV();
tv.play();
}
}
當有新的產品,只需要實現TV介面,新的工廠實現TVFactory介面就可以了,滿足了開閉原則
4.優缺點:
(1)、工廠方法模式的優點
在工廠方法模式中,工廠方法用來建立客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被例項化
這一細節,使用者只需要關心所需產品對應的工廠,無須關心建立細節,甚至無須知道具體產品類的類名。
基於工廠角色和產品角色的多型性設計是工廠方法模式的關鍵。它能夠使工廠可以自主確定建立何種產品物件,而如何建立這個物件的細節則完全封裝在具體工廠內部。工廠方法模式之所以又被稱為多型工廠模式,是因為所有的具體工廠類都具有同一抽象父類。 使用工廠方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的介面,無須修改客戶端,也無須修改其他的具體工廠和具體產品,而只要新增一個具體工廠和具體產品就可以了。這樣,系統的可擴充套件性也就變得非常好,完全符合“開閉原則”。
(2)、工廠方法模式的缺點
在新增新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和執行,會給系統帶來一些額外的開銷。
5.應用:
模式適用環境 在以下情況下可以使用工廠方法模式:
一個類不知道它所需要的物件的類:在工廠方法模式中,客戶端不需要知道具體產品類的類名,只需要知道所對應的工廠即可,具體的產品物件由具體工廠類建立;客戶端需要知道建立具體產品的工廠類。
一個類通過其子類來指定建立哪個物件:在工廠方法模式中,對於抽象工廠類只需要提供一個建立產品的介面,而由其子類來確定具體要建立的物件,利用面向物件的多型性和里氏代換原則,在程式執行時,子類物件將覆蓋父類物件,從而使得系統更容易擴充套件。
將建立物件的任務委託給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類建立產品子類,需要時再動態指定,可將具體工廠類的類名儲存在配置檔案或資料庫中。
(1)、 java.util.Collection介面的iterator()方法
(2)、Java訊息服務JMS(Java Messaging Service) :
//使用上下文和JNDI得到連線工廠的引用,ctx是上下文Context型別的物件 QueueConnectionFactory qConnFact=(QueueConnectionFactory)ctx.lookup("cfJndi"); //使用連線工廠建立一個連線 QueueConnection qConn=qConnFact.createQueueConnection(); //使用連線建立一個會話 QueueSession qSess=qConn.createQueueSession(false,javax.jms.QueueSession. AUTO_ACKNOWLEDGE); //使用上下文和JNDI得到訊息佇列的引用 Queue q=(Queue)ctx.lookup("myQueue"); //使用連線建立一個需要傳送的訊息型別的例項 QueueSender qSend=qSess.createSender(q); System.out.println("開始傳送訊息......"); |
(3)、JDBC的工廠方法:
Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=DB;user=sa;password="); Statement statement=conn.createStatement(); ResultSet rs=statement.executeQuery("select * from UserInfo"); |
6.總結:
(1)、工廠方法模式又稱為工廠模式,它屬於類建立型模式。在工廠方法模式中,工廠父類負責定義建立產品物件的公共介面,而工廠子類則負責生成具體的產品物件,這樣做的目的是將產品類的例項化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該例項化哪一個具體產品類。
(2)、工廠方法模式包含四個角色:
抽象產品是定義產品的介面,是工廠方法模式所建立物件的超型別,即產品物件的共同父類或介面;
具體產品實現了抽象產品介面,某種型別的具體產品由專門的具體工廠建立,它們之間往往一一對應;
抽象工廠中聲明瞭工廠方法,用於返回一個產品,它是工廠方法模式的核心,任何在模式中建立物件的工廠類都必須實現該介面;
具體工廠是抽象工廠類的子類,實現了抽象工廠中定義的工廠方法,並可由客戶呼叫,返回一個具體產品類的例項。
(3)、工廠方法模式是簡單工廠模式的進一步抽象和推廣。由於使用了面向物件的多型性,工廠方法模式保持了簡單工廠模式的優點,而且克服了它的缺點。在工廠方法模式中,核心的工廠類不再負責所有產品的建立,而是將具體建立工作交給子類去做。這個核心類僅僅負責給出具體工廠必須實現的介面,而不負責產品類被例項化這種細節,這使得工廠方法模式可以允許系統在不修改工廠角色的情況下引進新產品。
(4)、工廠方法模式的主要優點是增加新的產品類時無須修改現有系統,並封裝了產品物件的建立細節,系統具有良好的靈活性和可擴充套件性;其缺點在於增加新產品的同時需要增加新的工廠,導致系統類的個數成對增加,在一定程度上增加了系統的複雜性。
(5)、工廠方法模式適用情況包括:一個類不知道它所需要的物件的類;一個類通過其子類來指定建立哪個物件;將建立物件的任務委託給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類建立產品子類,需要時再動態指定。