這首歌還沒寫不能發java
由於本節的工廠方法模式與抽象工廠模式存在關聯度,因此會在下一節《抽象工廠模式》中混成一首歌發。設計模式
現實中的工廠,是用來生產產品的,而代碼中的工廠,則是建立對象的,bash
用來建立對象,那確定就是建立型模式了。ide
咱們常常會用到三種和工廠相關的設計模式:簡單工廠模式、工廠方法模式、抽象工廠模式。學習
這節我們要說的是——工廠方法模式。ui
不過,再說工廠方法以前,咱們要先說下簡單工廠模式。咱們從簡單的開始入手,由簡入繁。spa
簡單工廠模式呢,它不屬於Gof23種設計模式之一,但它在實際的項目中常常被用到,因此咱們仍是頗有必要學習,而且它的思想也很是簡單,能夠說是工廠方法模式的一個引導。設計
咱們來看一下簡單工廠方法的定義。code
又稱爲靜態工廠模式,由一個工廠對象決定建立出哪種產品類的實例。cdn
注意這裏的定義,是一個工廠對象。
怎麼實現呢?實現的套路是什麼?
定義一個工廠類,能夠根據參數的不一樣返回不一樣類的實例,被建立的實例一般有共同的父類。
場景與建造者模式有點相似,仍是熟悉的餃子,仍是熟悉的配方,仍是熟悉的味道,扯遠了...
美食餃子
番茄餐廳的後廚。
廚師長:老闆,我據說隔壁餐廳買來了一個機器,包餃子神器,一輸入參數,餃子直接出鍋,高科技呀,跟餃子工廠似的。
老闆:你的意思是我們也去買個?
廚師長:嗯,我是想提這個建議的,一鍵出餃子,想一想內心還有點小激動呢。
老闆:你不會是爲了圖省事吧?
求生欲極強的廚師長:固然不是,我是以爲餃子神器效率高,可以給咱們飯店帶來更大的價值。
老闆:嗯,那我贊成了,錢從你工資里扣。
委屈的廚師長:老闆,這樣不合適吧?我上有老,下有...
老闆:打住,逗你的,看把你給嚇得。效率提升但味道下降,這種神器我們飯店不會用的。
咱們今天的例子,就是餃子工廠,能夠生產各類餃子餡、皮。
簡單工廠模式的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之間的耦合。
咱們運行一下,看結果。
製做豬肉大蔥餡
------------
製做韭菜雞蛋餡
------------
製做茴香雞蛋餡
複製代碼
若是按照簡單工廠的寫法,在不使用java的反射的前提下,擴展性是不好的。
若是添加一種餃子餡,必須修改工廠中的判斷。
因此咱們來介紹一下另一種工廠模式——工廠方法模式,下面,咱們有請男主出場。
咱們先來看看,工廠方法模式的官方定義:
定義一個用於建立對象的接口,讓子類決定實例化哪個類。
從定義中,咱們能夠看出實現的套路:定一個建立對象的接口,而後每一個工廠去實現該接口實例化特定的對象,這樣就使一個類的實例化延遲到其子類。
每個產品都有相應的工廠,這就是與簡單工廠模式最大的區別。
而後,調用者能夠自由的 選擇使用哪一個工廠去建立對象。
工廠方法模式的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();
}
}
複製代碼
具體的工廠類。
爲每一個產品(餃子餡)提供一個工廠類:豬肉大蔥餡工廠、茴香雞蛋餡工廠、韭菜雞蛋餡工廠。
這樣的設計,擴展起來也很是的方便,例如增長三鮮餡,只須要增長產品類(三鮮餡)、工廠類(三鮮餡)就能夠了。不會影響其餘。
簡單工廠模式,只有一個工廠類,根據參數的不一樣返回不一樣類的實例。
工廠方法模式,定義一個建立對象的接口,存在實現該接口的多個工廠類。調用者選擇使用哪一個工廠。
從下一節課程開始,《嘻哈說——設計模式》系列的課程將不在其餘渠道發佈,改成公衆號《番茄課堂》獨家發佈,期待你們的關注。
今天就先說到這裏,下一節說《抽象工廠模式》,感謝你們支持。