天天看點

設計模式——工廠模式工廠模式

工廠模式,對于大部分的開發者來講,可能并不陌生,但是可能并非所有人都能完全了解,尤其是對于初學者。有的初學者經常會問:

工廠模式有什麼用?有什麼好處?什麼時候用工廠模式?

網絡上也有很多解答,諸如:可以更好的封裝、子產品化、還有的書上寫着<code>在生成複雜對象的地方,可以使用工廠模式</code>。那麼如何衡量一個對象的複雜的?這些解釋都是對的,但是對于一個初學者并不好了解。

對于初學者,最大的疑惑可能就在于:通過工廠<code>create</code>出來的對象和<code>new</code>出來的對象相比,優勢在哪裡?直接<code>new</code>不就好了嗎,還要寫個工廠類這麼麻煩?

筆者也是一直處于學習過程,梳理了一下工廠模式的使用場景和解決的痛點,通俗的聊一聊,如有錯誤,歡迎指正!

抛開前面抽象的定義,舉一個通俗的例子,帶你自然而然的應用上工廠設計模式。

某團隊有如下兩位開發人員:

移動端 : 小張

算法 : 小李

小張負責終端應用的開發,小李根據具體的業務邏輯寫一些算法,封裝成SDK提供給小張使用。

某天,産品提出了需求,需要開發某功能,算法小李根據需求,封裝了一個類,提供了一個1.0版本的SDK給終端小張使用。具體如下

小張可以在程式裡直接調用方法而不用管小李是如何實作的

兩人各司其職,合作非常愉快。如果你也覺得,恩,他們配合的不錯,那麼你可以繼續往下看。

直到有一天,産品又提出了新的需求,以前的算法邏輯不用了,有了新的邏輯。

算法小李最開始想到的就是,OK,改一下<code>FunctionA</code>的<code>method()</code>方法,改為新的。但是小李一想,如果某一天萬惡的産品又要改回去怎麼辦?想想不行,之前的算法不能删,于是乎,算法小李又重新定義了一個類,實作了第二套業務邏輯,生成了1.1版本的SDK給終端小張使用,果然高明。

終端小張收到算法小李給的SDK以後發現,根據需求,以前的<code>FunctionA</code>不能再用了,于是乎,終端小張也開始改程式,使用<code>FunctionB</code>

終端小張開始有點不爽,你改你的算法,和我有什麼關系?增加我的工作量!

(試想一下,如果你使用了某第三方SDK,SDK每次更新,你在本地都要改代碼,是不是得瘋掉?)

産品又來了,改改改……

改了好多次,小張和小李打了起來……

算法小李應該怎樣做,可以避免這種情況?這裡就可以使用到工廠方法。

算法<code>FunctionA</code>和算法<code>FunctionB</code>都是為了實作同一個功能,隻不過實作過程不一樣。

終端小張想要的是:

你改你的算法,你改完算法,我可以替換新的SDK,但是不要影響到我本地的程式。 我隻要調用<code>function.method();</code>就好了。 我不管你<code>function</code>是算法A還是算法B。

那麼,這裡小張想要的<code>function</code>就涉及到了Java的多态了,它即可能是<code>FunctionA</code>也可能是<code>FunctionB</code>。

算法小李就可以這樣改,定義一個抽象的<code>Function</code>,有一個抽象的<code>method()</code>方法,然後讓算法<code>FunctionA</code>和算法<code>FunctionB</code>都繼承<code>Function</code>,分别實作<code>method()</code>方法。

像這樣

Function

FunctionA

FunctionB

然後再提供一個工廠類,可以傳回一個多态的<code>Function</code>對象

這樣一來,終端小張爽了,可以通過工廠擷取<code>Function</code>

以後算法不管怎樣改,他都不需要再擔心,如果産品再想改算法,算法小李隻需要再定義一個<code>FunctionC</code>,在<code>createFunction</code>方法裡傳回即可。

這也展現了為什麼說工廠模式是依賴于抽象架構的,他們都有屬于一類事物,都有相同的方法,隻是實作不同,由此可見,通過工廠模式,可以實作<code>解耦</code>,對于算法小李,還有一定的<code>可擴充性</code>。

又有一天,産品又來新需求了,希望使用者可以自己選擇使用哪種邏輯算法。

終端小張希望可以提供相應接口,對應提供不同的邏輯。

算法小李首先想到的就是再多寫幾個create方法,諸如createFunctionA(),createFunctionB()……

雖然不是不行,但是假如你有成百上千套算法,難道要寫成百上千個create方法麼,這顯然是碼農的做法,作為工程師,我想隻用一個方法,指哪打哪,要啥給啥!這就用到了反射。

可以這樣實作

FuncFactory

FunctionFactory

這樣一來,終端小張就可以盡情玩耍了,

想用A算法,就傳一個<code>FunctionA</code>

想用算法B,就傳一個<code>FunctionB</code>

這裡用到了抽象工廠類<code>FuncFactory</code>,同樣也是為了友善擴充,現在小張和小李隻用到了一種邏輯,可有可無,如果以後還有多種邏輯要實作,可以在抽象工廠裡添加對應的create方法,友善擴充。

簡單的了解到這裡,歡迎指正!

繼續閱讀