工廠方法模式

定義

工廠方法模式的作用就是封裝對象的創(chuàng)建攻柠,由子類決定要創(chuàng)建的對象是什么隔显。

適用范圍

工廠方法模式特別適合與需要創(chuàng)建復雜對象的場景

實現

首先可以看一下,工廠方法模式的UML類圖

FactoryPattern.png

這樣一個圖看起來可能有點暈躏惋,下面就結合時下最流行的共享單車泣懊,寫一個工廠方法模式的通用模式代碼。

/**
 * 抽象單車產品
 *簡單起見煤墙,單車的制造方式(外觀)和計費方式 作為單車類的兩個方法
 */

public interface Bicycle {
    /**
     * 單車生產方式
     */
    String manufacture();

    /**
     * 單車計費方式
     */
    String billing();
}

/**
 * Bicycle 抽象單車生產工廠
 */

public interface BicycleFactory {

    Bicycle makeBicycle();
}


public class Mobike implements Bicycle {
    @Override
    public String manufacture() {
        System.out.print("摩拜單車---橙色---有定位功能");
        return "摩拜單車---橙色---有定位功能";
    }

    @Override
    public String billing() {
        System.out.print("Mobike每30分鐘收費1元");
        return "Mobike每30分鐘收費1元";
    }
}

public class MobikeFactory implements BicycleFactory {
    @Override
    public Bicycle makeBicycle() {
        return new Mobike();
    }
}

public class Ofo implements Bicycle {
    @Override
    public String manufacture() {
        System.out.print("ofo單車---黃色---密碼不變");
        return "ofo單車---黃色---密碼不變";
    }

    @Override
    public String billing() {
        System.out.print("ofo單車: 師生認證用戶0.5元/小時梅惯,非師生用戶1元/小時");
        return "ofo單車: 師生認證用戶0.5元/小時顾患,非師生用戶1元/小時";
    }
}

public class OfoFactory implements BicycleFactory {
    @Override
    public Bicycle makeBicycle() {
        return new Ofo();
    }
}

在上面的代碼中:

  • Bicycle 抽象產品
  • Mobike 和 Ofo 具體產品
  • BicycleFactory 抽象工廠
  • MobikeFactory 和 OfoFactory 具體的工廠

這就是工廠模式。所有的產品(Mobike和Ofo)有共同的父類 Bicycle个唧,而每一個產品又有各自的工廠(MobikeFactory和
OfoFactory)去負責創(chuàng)建自己江解;當然這里所有的產品可以有公共的工廠,在公共的工廠里通過參數負責生成不同的產品徙歼。如下方式:

/**
 * 所有產品共用一個工廠
 */
public class CommonFactory {
    public static Bicycle makeBicycle(String type) {
        switch (type) {
            case "mobike":
                return new Mobike();
            case "ofo":
                return new Ofo();
            default:
                return null;

        }

    }
}

個人感覺犁河,每個產品使用各自的工廠是一種更有設計模式的做法,也就是更符合開閉原則魄梯;如果有了新產品桨螺,就不必去修改原有的工廠,增加新的產品和工廠即可酿秸。

有個工廠灭翔,就非常方便我們去創(chuàng)建不同的對象了。

public class FactoryPatternActivity extends AppCompatActivity {
    private TextView bike_result;
    private BicycleFactory factory;
    private Bicycle mBicycle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_factory_pattern);
        bike_result = V.f(this, R.id.bike_result);
    }


    public void MobikeClick(View view) {
        factory = new MobikeFactory();
        mBicycle = factory.makeBicycle();
        updateView(mBicycle);
    }

    public void OfoClick(View view) {
        factory = new OfoFactory();
        mBicycle = factory.makeBicycle();
        updateView(mBicycle);
    }
    private void updateView(Bicycle mBicycle) {
        bike_result.setText("");
        StringBuilder sb = new StringBuilder();
        sb.append(mBicycle.manufacture())
                .append("\n")
                .append(mBicycle.billing());
        bike_result.setText(sb.toString());
    }
}

在這里使用工廠模式辣苏,BicycleFactory 封裝了Bicycle 對象具體生成的過程肝箱;當需要具體的對象時,調用每個對象各自的工廠生成對象即可稀蟋。試想煌张,如果沒有使用工廠模式,那么這里FactoryPatternActivity 將包含大量的代碼去負責創(chuàng)建復雜的Bicycle對象退客,但是從MVP的角度來說骏融,這是完全不屬于Activity(View)的工作。

Android 中的Factory

BitmapFactory

在Android 系統(tǒng)中萌狂,說道Factory大家第一個想到的可能就是BitmapFactory了档玻。研究過Bitmap的同學應該清楚,BitmapFactory 為了方便開發(fā)者茫藏,提供了一系列的方法方便大家通過各種途徑創(chuàng)建Bitmap误趴。

BitmapFactoryApi.png

這里可以看一下decodeStream(InputStream is) 方法:

    public static Bitmap decodeStream(InputStream is) {
        return decodeStream(is, null, null);
    }

可以看到,這里又會去調用別的方法刷允;最終上述的所有方法冤留,殊途同歸都會調用到一些native的方法去真正的完成Bitmap的創(chuàng)建。其實按照上面的UML圖來說树灶,嚴格來說BitmapFactory 的實現并不是工廠方法模式;只能說是簡單工廠糯而。在BitmapFactory類中對于唯一的產品Bitmap只有唯一的工廠BitmapFactory天通,它所有的生產方法都是靜態(tài)的;如果要新增一種生產Bitmap的方式熄驼,就得修改唯一的工廠(BitmapFactory)像寒。因此烘豹,從設計模式的角度來說,完全不符合開閉原則诺祸。

這里并不是說BitmapFactory這個類的寫法不好携悯,只是剛好從工廠方法模式的角度找了一個大家熟悉的類做了一個分析,Android系統(tǒng)的代碼其實寫的很好筷笨。BitmapFactory 這個類里包含的方法已經夠大家使用憔鬼,因此它設計成這個樣子是完全合理的。

onCreate 方法

《Android 源碼設計模式解析于實戰(zhàn)》這本書中提到 onCreate 方法是的實現可以說是工廠模式胃夏,的確從廣義角度來說轴或,通過不同的參數(R.layout.acitity) 創(chuàng)建出了不同的View;的確是可以算是工廠模式仰禀。至于具體代碼的實現邏輯照雁,這里就不拾人牙慧了。

總結

總的來說答恶,工廠模式就是種瓜得瓜饺蚊,種豆得豆;根據不同的輸入創(chuàng)建不同類型的對象悬嗓。通過上面的實例其實可以總結出規(guī)律卸勺,當我們在代碼中寫了很多if-else或者是switch時,是不是可以考慮以下使用工廠模式烫扼,也許我們就是在創(chuàng)建不通過的對象曙求,也許只是自己沒有發(fā)現。


工廠方法模式真的感覺只能意會映企,不能言傳悟狱。看別人寫的東西總是忘掉堰氓,這樣自己寫一遍才算理解了挤渐。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市双絮,隨后出現的幾起案子浴麻,更是在濱河造成了極大的恐慌,老刑警劉巖囤攀,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件软免,死亡現場離奇詭異,居然都是意外死亡焚挠,警方通過查閱死者的電腦和手機膏萧,發(fā)現死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人榛泛,你說我怎么就攤上這事蝌蹂。” “怎么了曹锨?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵孤个,是天一觀的道長。 經常有香客問我沛简,道長齐鲤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任覆享,我火速辦了婚禮佳遂,結果婚禮上,老公的妹妹穿的比我還像新娘撒顿。我一直安慰自己丑罪,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布凤壁。 她就那樣靜靜地躺著吩屹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拧抖。 梳的紋絲不亂的頭發(fā)上煤搜,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音唧席,去河邊找鬼擦盾。 笑死,一個胖子當著我的面吹牛淌哟,可吹牛的內容都是我干的迹卢。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼徒仓,長吁一口氣:“原來是場噩夢啊……” “哼腐碱!你這毒婦竟也來了?” 一聲冷哼從身側響起掉弛,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤症见,失蹤者是張志新(化名)和其女友劉穎勒庄,沒想到半個月后骗奖,有當地人在樹林里發(fā)現了一具尸體芙粱,經...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡本姥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了赁温。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片界牡。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡冈欢,死狀恐怖秒咐,靈堂內的尸體忽然破棺而出谬晕,到底是詐尸還是另有隱情,我是刑警寧澤携取,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布攒钳,位于F島的核電站,受9級特大地震影響雷滋,放射性物質發(fā)生泄漏不撑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一晤斩、第九天 我趴在偏房一處隱蔽的房頂上張望焕檬。 院中可真熱鬧,春花似錦澳泵、人聲如沸实愚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腊敲。三九已至,卻和暖如春维苔,著一層夾襖步出監(jiān)牢的瞬間碰辅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工介时, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留没宾,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓沸柔,卻偏偏與公主長得像循衰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子勉失,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容