1、嘻哈說
這首歌還沒寫不能發
因為本節的工廠方法模式與抽象工廠模式存在關聯度,所以會在下一節《抽象工廠模式》中混成一首歌發。
2、簡單工廠模式的定義
現實中的工廠,是用來生產產品的,而程式碼中的工廠,則是建立物件的,
用來建立物件,那肯定就是建立型模式了。
我們經常會用到三種和工廠相關的設計模式:簡單工廠模式、工廠方法模式、抽象工廠模式。
這節我們們要說的是——工廠方法模式。
不過,再說工廠方法之前,我們要先說下簡單工廠模式。我們從簡單的開始入手,由簡入繁。
簡單工廠模式呢,它不屬於Gof23種設計模式之一,但它在實際的專案中經常被用到,所以我們還是很有必要學習,並且它的思想也非常簡單,可以說是工廠方法模式的一個引導。
我們來看一下簡單工廠方法的定義。
又稱為靜態工廠模式,由一個工廠物件決定建立出哪一種產品類的例項。
注意這裡的定義,是一個工廠物件。
怎麼實現呢?實現的套路是什麼?
定義一個工廠類,可以根據引數的不同返回不同類的例項,被建立的例項通常有共同的父類。
3、場景
場景與建造者模式有點類似,還是熟悉的餃子,還是熟悉的配方,還是熟悉的味道,扯遠了...
美食餃子
番茄餐廳的後廚。
廚師長:老闆,我聽說隔壁餐廳買來了一個機器,包餃子神器,一輸入引數,餃子直接出鍋,高科技呀,跟餃子工廠似的。
老闆:你的意思是我們們也去買個?
廚師長:嗯,我是想提這個建議的,一鍵出餃子,想想心裡還有點小激動呢。
老闆:你不會是為了圖省事吧?
求生欲極強的廚師長:當然不是,我是覺得餃子神器效率高,能夠給我們飯店帶來更大的價值。
老闆:嗯,那我同意了,錢從你工資里扣。
委屈的廚師長:老闆,這樣不合適吧?我上有老,下有...
老闆:打住,逗你的,看把你給嚇得。效率提高但味道降低,這種神器我們們飯店不會用的。
我們今天的例子,就是餃子工廠,可以生產各種餃子餡、皮。
4、簡單工廠模式
簡單工廠模式的UML類圖。
package com.fanqiekt.factory.simple;
/**
* 餃子餡
*
* @Author: 番茄課堂-懶人
*/
public interface IStuffing {
void make();
}
複製程式碼
IStuffing:產品(餃子餡)的介面,共有的父類。
make()就是製造餃子皮的方法。
package com.fanqiekt.factory.simple;
/**
* 豬肉大蔥餡
* @Author: 番茄課堂-懶人
*/
public class PorkStuffing implements IStuffing {
@Override
public void make() {
System.out.println("製作豬肉大蔥餡");
}
}
複製程式碼
package com.fanqiekt.factory.simple;
/**
* 茴香雞蛋餡
* @Author: 番茄課堂-懶人
*/
public class FoeniculumVulgareStuffing implements IStuffing {
@Override
public void make() {
System.out.println("製作茴香雞蛋餡");
}
}
複製程式碼
package com.fanqiekt.factory.simple;
/**
* 韭菜雞蛋餡
* @Author: 番茄課堂-懶人
*/
public class ChineseChivesStuffing implements IStuffing {
@Override
public void make() {
System.out.println("製作韭菜雞蛋餡");
}
}
複製程式碼
具體的產品類,餃子餡中的大戶:豬肉大蔥餡、茴香雞蛋餡、韭菜雞蛋餡。
package com.fanqiekt.factory.simple;
/**
* 餃子餡工廠類
* @Author: 番茄課堂-懶人
*/
public class StuffingFactory {
public static IStuffing getStuffing(String key){
IStuffing stuffing = null;
switch (key){
case "豬肉大蔥":
stuffing = new PorkStuffing();
break;
case "韭菜雞蛋":
stuffing = new ChineseChivesStuffing();
break;
case "茴香雞蛋":
stuffing = new FoeniculumVulgareStuffing();
break;
}
return stuffing;
}
}
複製程式碼
StuffingFactory:餃子餡工廠類。
簡單工廠中只有一個工廠類,並且提供了一個靜態公有方法,可以根據引數的不同返回不同類的例項。
這也是簡單方法為什麼要被稱之為靜態工廠模式的原因。
package com.fanqiekt.factory.simple;
/**
* 客戶端
* @Author: 番茄課堂-懶人
*/
public class Client {
public static void main(String args[]){
IStuffing stuffing = StuffingFactory.getStuffing("豬肉大蔥");
stuffing.make();
System.out.println("------------");
stuffing = StuffingFactory.getStuffing("韭菜雞蛋");
stuffing.make();
System.out.println("------------");
stuffing = StuffingFactory.getStuffing("茴香雞蛋");
stuffing.make();
}
}
複製程式碼
客戶端類。
我們可以看出,簡單工廠不愧為簡單工廠,就是赤裸裸的簡單。
但簡單並不普通,它完美的展現了工廠方法的思想,讓工廠建立物件,而不是物件A去建立物件B。
這樣可以避免物件A與物件B之間的耦合。
我們執行一下,看結果。
製作豬肉大蔥餡
------------
製作韭菜雞蛋餡
------------
製作茴香雞蛋餡
複製程式碼
5、工廠方法模式的定義
如果按照簡單工廠的寫法,在不使用java的反射的前提下,擴充套件性是很差的。
如果新增一種餃子餡,必須修改工廠中的判斷。
所以我們來介紹一下另外一種工廠模式——工廠方法模式,下面,我們有請男主出場。
我們先來看看,工廠方法模式的官方定義:
定義一個用於建立物件的介面,讓子類決定例項化哪一個類。
從定義中,我們可以看出實現的套路:定一個建立物件的介面,然後每個工廠去實現該介面例項化特定的物件,這樣就使一個類的例項化延遲到其子類。
每一個產品都有相應的工廠,這就是與簡單工廠模式最大的區別。
然後,呼叫者可以自由的 選擇使用哪個工廠去建立物件。
6、工廠方法模式
工廠方法模式的UML類圖。
產品(餃子餡)與簡單工廠模式的程式碼一致,這裡就不貼出來了。
package com.fanqiekt.factory.method;
/**
* 工廠介面
* @Author: 番茄課堂-懶人
*/
public interface IFactory {
IStuffing getStuffing();
}
複製程式碼
IFactory:工廠的介面。
定義一個用於建立物件的介面。
getStuffing()獲得產品(餃子餡)的方法,交給具體的子類來實現。使一個類的例項化延遲到其子類。
package com.fanqiekt.factory.method;
/**
* 豬肉大蔥餡工廠
* @Author: 番茄課堂-懶人
*/
public class PorkFactory implements IFactory {
@Override
public IStuffing getStuffing() {
return new PorkStuffing();
}
}
複製程式碼
package com.fanqiekt.factory.method;
/**
* 茴香雞蛋餡工廠
* @Author: 番茄課堂-懶人
*/
public class FoeniculumVulgareFactory implements IFactory {
@Override
public IStuffing getStuffing() {
return new FoeniculumVulgareStuffing();
}
}
複製程式碼
package com.fanqiekt.factory.method;
/**
* 韭菜雞蛋餡工廠
* @Author: 番茄課堂-懶人
*/
public class ChineseChivesFactory implements IFactory {
@Override
public IStuffing getStuffing() {
return new ChineseChivesStuffing();
}
}
複製程式碼
具體的工廠類。
為每個產品(餃子餡)提供一個工廠類:豬肉大蔥餡工廠、茴香雞蛋餡工廠、韭菜雞蛋餡工廠。
這樣的設計,擴充套件起來也非常的方便,例如增加三鮮餡,只需要增加產品類(三鮮餡)、工廠類(三鮮餡)就可以了。不會影響其他。
7、區別
簡單工廠模式,只有一個工廠類,根據引數的不同返回不同類的例項。
工廠方法模式,定義一個建立物件的介面,存在實現該介面的多個工廠類。呼叫者選擇使用哪個工廠。
8、END
從下一節課程開始,《嘻哈說——設計模式》系列的課程將不在其他渠道釋出,改為公眾號《番茄課堂》獨家釋出,期待大家的關注。
今天就先說到這裡,下一節說《抽象工廠模式》,感謝大家支援。