工廠方法模式的定義
工廠方法模式(FACTORY METHOD)是一種常用的物件建立型設計模式,此模式的核心精神是封裝類中不變的部分,提取其中個性化善變的部分為獨立類,通過依賴注入以達到解耦、複用和方便後期維護擴充的目的。它的核心結構有四個角色,分別是抽象工廠;具體工廠;抽象產品;具體產品。
從上面的圖可以看出:Product為抽象產品類,負責產品的共性;Creator為抽象建立類;而具體的產品(ConcreteProduct)是由實現工廠ConcreteCreator完成的。 工廠方法模式詳解及舉例一.首先先用程式碼解釋一下上面的圖:
1.抽象產品類
public abstract class Product {
//所有產品類的公共業務方法
public void method1() {
//公共方法的實現
}
//宣告抽象業務方法
public abstract void method2();
}
複製程式碼
2.具體產品類
public class ConcreteProduct1 extends Product{
//實現業務方法
public void method2() {
//業務方法的實現
}
}
public class ConcreteProduct2 extends Product{
//實現業務方法
public void method2() {
//業務方法的實現
}
}
複製程式碼
3.抽象工廠類
public abstract class Creator{
// public abstract Product createProduct(String arg);
public abstract <T extends Product> T createProduct(Class<T> c);
}
複製程式碼
4.具體工廠類
public class ConcreteCreator extends Creator{
public <T extends Product> T createProduct(class<T> c){
Product product=null;
try{
product =(T)Class.forName(c.getName()).newInstance();
}catch (Exception e){
}
return (T)product;
}
}
複製程式碼
5呼叫:
Creator creator=new ConcreteCreator();
Product product=creator.createProduct(ConcreteProduct1.class);
// product.method2();
複製程式碼
根據上面的程式碼應該看懂了吧?如果不懂下面我具體舉個例子:
二.舉例
我們拿手機舉例,一個手機工廠生產兩種手機,分別是華為手機和小米手機。過程就是在工廠經過一系列的加工製作生產出這兩種手機,下面用程式碼來演示一下:
1.抽象產品類,也就是兩種手機的共性:
定義了兩個方法,一個是打電話,一個是手機的品牌,兩種手機的品牌是不同的,所以是抽象的。
public abstract class Phone {
//兩種手機都可以打電話
public void Call() {
//公共方法的實現
}
//兩種手機都有品牌,但是品牌不同,所以是抽象的
public abstract void PhoneBrand();
}
複製程式碼
2.具體的產品類, 就是華為手機和小米手機兩個產品
public class HUAWEIPhone extends Phone {
//品牌
@Override
public void PhoneBrand() {
Log.e("qzs","我的品牌是華為");
}
}
public class MIPhone extends Phone {
//品牌
@Override
public void PhoneBrand() {
Log.e("qzs","我的品牌是小米");
}
}
複製程式碼
3.抽象工廠類,要想生產手機就必須要有工廠,所以先要定義生產手機的抽象方法。
public abstract class PhoneFactory {
public abstract <T extends Phone> T createPhone(Class<T> c);
}
複製程式碼
4.具體工廠類,具體的生產手機的方法
public class ConcretePhoneFactory extends PhoneFactory {
@Override
public <T extends Phone> T createPhone(Class<T> c) {
Phone phone=null;
try{
phone =(Phone)Class.forName(c.getName()).newInstance();
Log.e("qzs","生產了一個手機");
phone.PhoneBrand();
}catch (Exception e){
}
return (T) phone;
}
}
複製程式碼
呼叫:
PhoneFactory phoneFactory=new ConcretePhoneFactory();
Phone huaiweiphone=phoneFactory.createPhone(HUAWEIPhone.class);
Phone miphone=phoneFactory.createPhone(MIPhone.class);
複製程式碼
執行的結果如下,可以看到生產了兩種手機,這次工廠方法模式是不是有了更為清楚的認識。
工廠方法模式不同形式
1.簡單工廠模式
就是把抽象工廠類去掉,具體工廠類的方法上加上static,拿上面的例子說明:
public class ConcretePhoneFactory {
public static <T extends Phone> T createPhone(Class<T> c) {
Phone phone=null;
try{
phone =(Phone)Class.forName(c.getName()).newInstance();
Log.e("qzs","生產了一個手機");
phone.PhoneBrand();
}catch (Exception e){
}
return (T) phone;
}
}
複製程式碼
2.多工廠方法模式
從名字就可以看出來,是有多個具體工廠類,上面的例子是兩種手機都放在了一個工廠了,現實的話應該在兩個工廠生產,也就是多工廠方法模式。
分成兩個工廠後,抽象工廠類就不用傳參了,因為每種手機都有自己工廠了。
修改後的抽象工廠類:
public abstract class PhoneFactory {
public abstract Phone createPhone();
}
複製程式碼
修改的具體工廠類:
public class ConcreteHUAWEIFactory extends PhoneFactory {
@Override
public Phone createPhone() {
Log.e("qzs","生產了一個華為手機");
return new HUAWEIPhone();
}
}
public class ConcreteMIFactory extends PhoneFactory {
@Override
public Phone createPhone() {
Log.e("qzs","生產了一個小米手機");
return new MIPhone();
}
}
複製程式碼
3.工廠方法模式來實現單例模式
單例模式的核心要求就是在記憶體中只有一個物件,通過工廠方法模式也可以只在記憶體中生產一個物件。
public class Singleton {
private Singleton() {
}
public void doSomething() {
System.out.println("具體邏輯");
}
}
複製程式碼
通過獲得類構造器,然後設定訪問許可權,生成一個物件,然後提供外部訪問,保證記憶體中的物件唯一。
public class SingletonFactory {
private static Singleton singleton;
static {
try {
Class clazz = Class.forName(Singleton.class.getName());
Constructor constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
singleton = (Singleton) constructor.newInstance();
} catch (Exception e) {
}
}
public static Singleton getSingleton() {
return singleton;
}
}
複製程式碼
呼叫:
Singleton singleton = SingletonFactory.getSingleton();
Singleton singleton2 = SingletonFactory.getSingleton();
System.out.println(singleton);
System.out.println(singleton2);
複製程式碼
列印後發現物件是相同的。
4.延遲初始化
一個物件被消費完畢後,並不立刻釋放,工廠類保持其初始狀態,等待再次被使用。
工廠方法模式優缺點
1.優點
工廠方法模式是完全符合開閉原則的;
工廠模式是一種典型的解耦模式,可以降低物件之間的耦合度;
工廠模式是依靠抽象架構的,它把例項化產品的任務交由實現類完成,擴充套件性比較好。
可以使程式碼結構清晰,有效地封裝變化。
對呼叫者遮蔽具體的產品類。如果使用工廠模式,呼叫者只關心產品的介面就可以了,至於具體的實現,呼叫者根本無需關心。即使變更了具體的實現,對呼叫者來說沒有任何影響。
複製程式碼
2.缺點
簡單的物件應用時,不適合工廠方法模式。
模式應用
工廠方法經常用在以下兩種情況中:
第一種情況是對於某個產品,呼叫者清楚地知道應該使用哪個具體工廠服務,例項化該具體工廠,生產出具體的產品來。Java Collection中的iterator() 方法即屬於這種情況。
第二種情況,只是需要一種產品,而不想知道也不需要知道究竟是哪個工廠為生產的,即最終選用哪個具體工廠的決定權在生產者一方,它們根據當前系統的情況來例項化一個具體的工廠返回給使用者,而這個決策過程這對於使用者來說是透明的。
複製程式碼
文章學習參考了《設計模式之禪》#
歡迎大家關注我的微信公眾號:安卓乾貨鋪