5月一個酷熱的中午,我跟剛來不久的小兄弟,小當閒聊起了公司用的的設計模式。
我侃侃而談道:“咱們公司,使用的設計模式不多,也就是 策略,門面,簡單工廠,工廠,單例,命令,組合,模板等。”
小當:“什麼是簡單工廠啊?,跟工廠模式有區別嗎?”
我一聽,便雙手交叉於胸前,略有深意的說:“你瞭解的工廠模式是什麼?”
小當非常流利的說:“將創建的對象方法,抽取到一個類中,根據類型不同創建相應的對象。”
我嘆了口氣:“小當,你瞭解的工廠模式有誤哦,這個是簡單工廠”
小當充滿疑惑的說:“那什麼是工廠模式,什麼又是簡單工廠呢?”
我喝了一口水,娓娓道來:“
簡單工廠不是設計模式,而是一種編程習慣。
將創建對象的方法,抽取到一個公共類中,根據類型不同創建相應的對象。
不屬於23種GOF設計模式之一。
就拿獲取算獎器的例子來說吧,PL3,DLT等都有自己的算獎器。簡單工廠實現方式如下:
package factory;
public class SimpleCalculatorFactoryDemo {
public static abstract class Calculator{
private String type;
public Calculator(String type) {
this.type = type;
}
public void calculate(){
System.out.println(" This "+type+" calculate is done");
}
}
public static class PL3Calculator extends Calculator{
public PL3Calculator() {
super("PL3");
}
}
public static class DLTCalculator extends Calculator{
public DLTCalculator() {
super("DLT");
}
}
public static class SimpleCalculatorFactory{
public Calculator createCalculator(String type){
if ("PL3".equals(type)) { return new PL3Calculator(); }
else if ("DLT".equals(type)){ return new DLTCalculator(); }
return null;
}
}
public static class PrizeTicketHandler{
SimpleCalculatorFactory factory;
public PrizeTicketHandler(SimpleCalculatorFactory factory){
this.factory=factory;
}
public Calculator getCalculator(String type){
return factory.createCalculator(type);
}
}
public static void main(String[] args) {
SimpleCalculatorFactoryDemo. SimpleCalculatorFactory factory=new SimpleCalculatorFactory();
PrizeTicketHandler prizeTicketHandler=new PrizeTicketHandler(factory);
prizeTicketHandler.getCalculator("DLT").calculate();
}
}
其類圖如下:
我正準備往下說簡單工廠的缺點的時候,小當嚼着蘋果不耐煩的說:"這個你不用細說的,我早就爛熟於心了。"
抿了抿嘴,一笑說道:“那這種方式存在什麼問題?”
小當停止嚼蘋果,思考了10幾秒說:“每新增一個類,工廠中的if判斷語句也相應增加,對系統的維護和擴展非常不利。”
我點頭表示認可的說道:
“確實,隨着具體的產品類增加,簡單工廠的邏輯需要修改,逐漸變得不易擴展和維護,並沒有做的對修改關閉,對擴展開發。”
小當吃了一大口蘋果後,若有所思的說道:“咱們系統中可不是這樣寫的,獲取算獎器是分數字彩和競彩的。”
我喝了口水後,嘗試引導小當,問道:“你還記得咱們系統是如何實現的嗎?”
小當扔掉蘋果核,擦擦手說道:“ 當然,其實現大致如下 ”
(注意:工廠模式的實現)
package factory;
public class FactoryCalculatorDemo {
public static abstract class Calculator{
private String type;
public Calculator(String type) {
this.type = type;
}
public void calculate(){
System.out.println(" This "+type+" calculate is done");
}
}
public static class PL3Calculator extends Calculator {
public PL3Calculator() {
super("PL3");
}
}
public static class DLTCalculator extends Calculator {
public DLTCalculator() { super("DLT"); }
}
public static class BSKCalculator extends Calculator {
public BSKCalculator() {
super("BSK");
}
}
public static class FTCalculator extends Calculator {
public FTCalculator() {
super("FT");
}
}
public static abstract class CalculatorFactory{
public abstract Calculator createCalculator(String type);
}
public static class NumberLotteryCalculatorFactory extends CalculatorFactory {
@Override
public Calculator createCalculator(String type){
if ("PL3".equals(type))
{ return new PL3Calculator(); }
else if ("DLT".equals(type))
{ return new DLTCalculator(); }
return null;
}
}
public static class JCCalculatorFactory extends CalculatorFactory {
@Override
public Calculator createCalculator(String type){
if ("BSK".equals(type))
{ return new BSKCalculator(); }
else if ("FT".equals(type))
{ return new FTCalculator(); }
return null;
}
}
public static void main(String[] args) {
//調用者,知悉使用的子類
CalculatorFactory calculatorFactory=new NumberLotteryCalculatorFactory();
calculatorFactory.createCalculator("PL3").calculate();
calculatorFactory=new JCCalculatorFactory();
calculatorFactory.createCalculator("FT").calculate();
}
}
其類圖如下:
我看後很欣慰他掌握的挺好,我可以放心的走了。隨後不等小當說話,強行總結說道:
“這個就是工廠模式了,定義了一個創建對象的接口,但由子類覺得要實例化的類是哪一個,即由NumberLotteryCalculatorFactory 和JCCalculatorFactory 決定實例化的類”。
小當搶着說:“NumberLotteryCalculatorFactory 和JCCalculatorFactory也實現了平行層級關係,若果有新加入的類,加入一個對應的工廠子類就好,不需要修改原來的代碼”。
“是的” 我點頭說道。
小當摸了摸下巴,又問道:“工廠模式瞭解了,那爲什麼系統中還會使用簡單工廠呢?”
我一笑說道:“咱們校驗器部分就是使用的簡單工廠,校驗器只有3個:注數,格式,金額,基本上不會變。所以使用簡單工廠就好,記住實現功能越簡單越好,Keep it Simple is best”
總結:
工廠模式:定義了一個創建對象的接口,但由子類覺得要實例化的類是哪一個。
至於選擇具體選擇簡單工廠還是工廠模式,完全看業務需要,實現功能越簡單越好。
Keep it Simple is best。
---溫安適,20180525
寫在最後:
預計29號,就要離開這家公司了,這篇文章最後也道個別。這家公司給的工資不高,但是積累了很多經驗,無論是技術,還是管理,又提升了逆商,非常感謝,再見彩福達。