1、定義
工廠方法模式(FACTORY METHOD)是一種常用的類創(chuàng)建型設(shè)計(jì)模式,此模式的核心精神是封裝類中變化的部分,提取其中個性化善變的部分為獨(dú)立類,通過依賴注入以達(dá)到解耦、復(fù)用和方便后期維護(hù)拓展的目的。它的核心結(jié)構(gòu)有四個角色,分別是抽象工廠;具體工廠;抽象產(chǎn)品;具體產(chǎn)品
2、模式簡介
工廠方法(Factory Method)模式的意義是定義一個創(chuàng)建產(chǎn)品對象的工廠接口,將實(shí)際創(chuàng)建工作推遲到子類當(dāng)中。核心工廠類不再負(fù)責(zé)產(chǎn)品的創(chuàng)建,這樣核心類成為一個抽象工廠角色,僅負(fù)責(zé)具體工廠子類必須實(shí)現(xiàn)的接口,這樣進(jìn)一步抽象化的好處是使得工廠方法模式可以使系統(tǒng)在不修改具體工廠角色的情況下引進(jìn)新的產(chǎn)品。
工廠方法模式是簡單工廠模式的衍生,解決了許多簡單工廠模式的問題。首先完全實(shí)現(xiàn)‘開-閉 原則’,實(shí)現(xiàn)了可擴(kuò)展。其次更復(fù)雜的層次結(jié)構(gòu),可以應(yīng)用于產(chǎn)品結(jié)果復(fù)雜的場合。
工廠方法模式對簡單工廠模式進(jìn)行了抽象。有一個抽象的Factory類(可以是抽象類和接口),這個類將不再負(fù)責(zé)具體的產(chǎn)品生產(chǎn),而是只制定一些規(guī)范,具體的生產(chǎn)工作由其子類去完成。在這個模式中,工廠類和產(chǎn)品類往往可以依次對應(yīng)。即一個抽象工廠對應(yīng)一個抽象產(chǎn)品,一個具體工廠對應(yīng)一個具體產(chǎn)品,這個具體的工廠就負(fù)責(zé)生產(chǎn)對應(yīng)的產(chǎn)品。
工廠方法模式(Factory Method pattern)是最典型的模板方法模式(Template Method pattern)應(yīng)用。
3、角色結(jié)構(gòu)
抽象工廠(Creator)角色
是工廠方法模式的核心,與應(yīng)用程序無關(guān)。任何在模式中創(chuàng)建的對象的工廠類必須實(shí)現(xiàn)這個接口。
具體工廠(Concrete Creator)角色
這是實(shí)現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建產(chǎn)品對象。
抽象產(chǎn)品(Product)角色
工廠方法模式所創(chuàng)建的對象的超類型,也就是產(chǎn)品對象的共同父類或共同擁有的接口
具體產(chǎn)品(Concrete Product)角色
這個角色實(shí)現(xiàn)了抽象產(chǎn)品角色所定義的接口。某具體產(chǎn)品有專門的具體工廠創(chuàng)建,它們之間往往一一對應(yīng)。
4、模式應(yīng)用
工廠方法經(jīng)常用在以下兩種情況中:
第一種情況是對于某個產(chǎn)品,調(diào)用者清楚地知道應(yīng)該使用哪個具體工廠服務(wù),實(shí)例化該具體工廠,生產(chǎn)出具體的產(chǎn)品來。Java Collection中的iterator() 方法即屬于這種情況。
第二種情況,只是需要一種產(chǎn)品,而不想知道也不需要知道究竟是哪個工廠為生產(chǎn)的,即最終選用哪個具體工廠的決定權(quán)在生產(chǎn)者一方,它們根據(jù)當(dāng)前系統(tǒng)的情況來實(shí)例化一個具體的工廠返回給使用者,而這個決策過程這對于使用者來說是透明的。
--以上概念摘抄自百度百科,方便自己學(xué)習(xí)--
-----------------------------------------------------------------------------------
--開始自己擼--
5、實(shí)例講解
背景:比如說我現(xiàn)在有這么個需求,就是我要對面粉進(jìn)行加工,從而得到饅頭、掛面
首先我需要抽象產(chǎn)品(Product)角色
/**
* 首先無論是做饅頭還是掛面,他們都有一個加工方法,可以抽象出來
* Machine:機(jī)器
*/
public interface MachineApi {
//process:加工 material:材料
public void process(String material);
}
然后我需要拿到具體產(chǎn)品
/**
* 饅頭機(jī)器
* steamed bun : 饅頭
*/
public class SteamedBunMachine implements MachineApi {
@Override
public void process(String material) {
System.out.println("我把" + material + "加工成了饅頭");
}
}
/**
* 面條機(jī)器
* noodle : 面條
*/
public class BoodleMachine implements MachineApi {
@Override
public void process(String material) {
System.out.println("我把" + material + "加工成了面條");
}
}
這個時候我需要一個 抽象工廠角色
public abstract class Factory{
/**
* 讓子類(具體工廠)來實(shí)例化具體對象(機(jī)器)
*/
public abstract MachineApi newMachine();
/**
* 加工材料
*/
public void process(String material){
MachineApi machine = newMachine();
machine.process(material);
}
}
然后我需要兩家工廠,分別幫我生成饅頭和面條
//饅頭工廠
public class SteamedBunFactory extends Factory{
//饅頭工廠,只需要提供饅頭機(jī)器就行
@Override
public MachineApi newMachine() {
return new SteamedBunMachine();
}
}
//面條工廠
public class NoodleFactory extends Factory{
//面條工廠,只需要提供面條機(jī)器就行
@Override
public MachineApi newMachine() {
return new BoodleMachine();
}
}
最后我作為老板,只需要操作工廠就可以進(jìn)行生成
SteamedBunFactory mSteamedBunFactory = new SteamedBunFactory ();
mSteamedBunFactory.process("面粉");//我把面粉加工成了饅頭
總結(jié)
其實(shí)這個時候,我作為老板,我又想開一家餅干廠,那么我只需要弄一臺餅干機(jī)器(繼承機(jī)器),再弄一個餅干廠(繼承工廠)就可以了,根本不需要動之前的代碼,這個過程唯一變化的就是做饅頭和做面條的流程工藝不同,提取其中個性化善變的部分為獨(dú)立類,通過依賴注入以達(dá)到解耦、復(fù)用和方便后期維護(hù)拓展的目的。
版權(quán)聲明:個人原創(chuàng),若轉(zhuǎn)載,請注明出處