前言
在此前的設計模式(四)簡單工廠模式中我們介紹了簡單工廠模式,在這篇文章中我們來介紹下工廠方法模式,它同樣是創建型設計模式,而且又有些類似,文章的末尾會介紹他們之間的不同。
1.工廠方法模式簡介
定義一個用於創建對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到其子類。
找了下網上的UML圖,都畫的醜醜的,自己畫吧,結果就出來這麼一個更醜的UML圖:
- Product:抽象產品類。
- ConcreteProduct:具體產品類,實現Product接口。
- Factory:抽象工廠類,該方法返回一個Product類型的對象。
- ConcreteFactory:具體工廠類,返回ConcreteProduct實例。
2.工廠方法模式簡單實現
參考設計模式(四)簡單工廠模式這篇文章,我接着舉電腦生產的例子。
電腦產品類,它有一個start方法用於啓動電腦:
public abstract class Computer{
public abstract void start();
}
具體的電腦產品分別是聯想、惠普和華碩電腦:
public class LenovoComputer extends Computer {
@Override
public void start() {
System.out.println("聯想電腦啓動");
}
}
public class HpComputer extends Computer {
@Override
public void start() {
System.out.println("惠普電腦啓動");
}
}
public class AsusComputer extends Computer{
@Override
public void start() {
System.out.println("華碩電腦啓動");
}
}
裏面有一個createComputer方法,想生產哪個品牌的電腦就生產那個:
public abstract class ComputerFactory {
public abstract <T extends Computer> T createComputer(Class<T> clz);
}
廣達代工廠是一個具體的工廠,他繼承抽象工廠,通過反射來生產不同廠家的電腦:
/**
* 廣達代工廠
*/
public class GDComputerFactor extends ComputerFactory {
@Override
public <T extends Computer> T createComputer(Class<T> clz) {
Computer computer=null;
String classname=clz.getName();
try {
//通過反射來生產不同廠家的電腦
computer= (Computer) Class.forName(classname).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) computer;
}
}
public class Client {
public static void main(String[]args) {
ComputerFactory computerFactory = new GDComputerFactor();
LenovoComputer mLenovoComputer=computerFactory.createComputer(LenovoComputer.class);
mLenovoComputer.start();
HpComputer mHpComputer=computerFactory.createComputer(HpComputer.class);
mHpComputer.start();
AsusComputer mAsusComputerr=computerFactory.createComputer(AsusComputer.class);
mAsusComputerr.start();
}
}
結構很簡單,看看下面的UML圖就更加容易理解了:
3.工廠方法與簡單工廠
簡單工廠模式我們都知道,在工廠類中包含了必要的邏輯判斷,根據不同的條件來動態實例化相關的類,對客戶端來說,去除了與具體產品的依賴,與此同時也會帶來一個問題:如果我們去增加產品,比如我們要生產蘋果電腦,那我們就需要在工廠類中在添加一個Case分支條件,這違背了開放封閉原則,我們對修改也開放了,不理解開放封閉的原則的同學可以查看設計模式(一)設計六大原則 這篇文章。而工廠方法模式就沒有違背這個開放封閉原則,如果我們需要生產蘋果電腦,並不需要去修改工廠類,直接創建產品就好了。