iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 2
1
自我挑戰組

初探設計模式系列 第 2

[ Day 2 ] 初探設計模式 - 工廠方法模式 (Factory Method Pattern)

前言

今天才算是正式進入鐵人賽啦~
果然要在工作中還每天生出一篇文章是需要意志力的...
今天研討會被講者們轟炸(推銷?)了整天,頭真是有點昏,
但是鐵人賽的大家都還在奮鬥,
技術不如人但是意志力可不能輸,
就靠這個氣勢啦!/images/emoticon/emoticon18.gif

進入正題...

物件導向、設計模式,
這些寫code的風格,
有些人不屑一顧認為實現功能就好,
有些人卻認為是基礎中的基礎。

工廠模式

今天要介紹的工廠模式,
其實概念非常的簡單,
在其中主要的角色只有兩個商品工廠

真的只有這麼簡單嗎?其實有一些隱藏在背後的東西...

當我們在使用工廠模式時,
你跟工廠說你想要的那種規格的商品
而工廠負責製造你想要的那種規格的商品
當中可能需要某些組裝或是特殊步驟
但是作為消費者你不知道這些組裝方式和步驟
你還是可以買到你想要的東西。

定義

工廠方法模式( Factory Method ),定義一個用於建立物品的介面,讓子類決定實體化哪一個類別。工廠方法使一個類別的實例化延遲到其子類別。
-- 大話設計模式 p.105

UML

工廠方法模式類別之間的關係像是下面這樣
 Factory Method Pattern

  • Creator:創造者經由FactoryMethod創造產品
  • Product:被創造的產品類別

舉個例子來說吧!

假設我們去速食店麥當勞無鹽的薯條

首先我們要有一個商品和工廠的介面...

用java來當範例

public interface Product {
    //敘述自己是什麼商品
    public void describe();
}
public interface Factory {
    //工廠返回商品
    public Product getProduct();
}

接下來實現薯條

public class FrenchFries implements Product{

    //預設有鹽巴的
    String state = "有鹽巴";
    //預設的建構
    protected FrenchFries(){}
    //帶入狀態的建構
    protected FrenchFries(String state){
        this.state = state;
    }

    @Override
    public void describe() {
        System.out.println("我是"+ state +"薯條");
    }
}

和薯條工廠

public class FrenchFriesFactory implements Factory {

    //返回一般的薯條
    @Override
    public Product getProduct() {
        return new FrenchFries();
    }

    //返回我們想要的狀態的薯條..
    public Product getProduct(String state) {
        return new FrenchFries(state);
    }
}

嘗試調用薯條工廠做出顧客想要的薯條

        Factory friesFac = new FrenchFriesFactory();
        Product fries = friesFac.getProduct();
        Product myfries = ((FrenchFriesFactory) friesFac).getProduct("無鹽的");

        fries.describe();//我是有鹽巴薯條
        myfries.describe();//我是無鹽的薯條

成功做出顧客想要的薯條

藉由工廠模式,
我們可以在調用的時候才決定我們想要的物品狀態,
在商品中加入大中小包等等的參數,
我們可以決定要哪種份量的商品,
甚至可以決定我們要幾根薯條,
用方法或是各種方式把物件的創造包裝起來,
工廠模式的實現方式很多,
但工廠有個重點會返回我們想要的商品
掌握這個重點碰到類似的創建模式相信都可以很快掌握喔!

最後,如果發現有什麼問題可以寄信或留言給我~


上一篇
[ Day 1 ] 我為什麼想學設計模式 ( Design Pattern )
下一篇
[ Day 3 ] 初探設計模式 - 策略模式 (Strategy Pattern)
系列文
初探設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

1
alantsui
iT邦新手 5 級 ‧ 2019-10-28 09:49:16

我認為你可以在tag中加上 Java,這樣比較好找

Daniel Wu iT邦新手 4 級 ‧ 2019-10-28 11:42:48 檢舉

已經在第一天的文章加上囉,謝謝提供意見!/images/emoticon/emoticon41.gif

0
leochang658
iT邦新手 5 級 ‧ 2023-08-18 13:42:19

有2個問題想要請教您

  1. 請問 FrenchFries 這個類別中,選擇 protected 的建構子是為了讓後續的 FrenchFries 物件都只能從 FrenchFriesFactory 建立嗎?

  2. 這邊為甚麼要把 friesFac 轉換成 FrenchFriesFactory? friesFac 在宣告的時候就不就是FrenchFriesFactory這個類別了嗎?
    Product myfries = ((FrenchFriesFactory) friesFac).getProduct("無鹽的");

Daniel Wu iT邦新手 4 級 ‧ 2023-08-20 22:53:37 檢舉

Hi,沒想到5年前的文章還有人回饋,非常感謝。
這邊回應你的問題

  1. 是的,是這個目的沒錯。
  2. 宣告時雖然是用FrenchFriesFactory建構子,但變數Type是使用Factory接所以要作轉換,才能使用getProduct(String state)這個函數。

提問的時候,我也很擔心5年前的文章可能無法得到解答,現在我懂了,感謝你的說明!

我要留言

立即登入留言