設計模式之工廠模式

2021-10-22 00:08:43 字數 3772 閱讀 8873

簡單工廠就是將物件的實現細節放到了乙個工廠類中,呼叫方只需要向該工廠類傳入特定引數就可以得到指定的物件,而不需要關心該物件具體是怎麼建立出來的。

舉例來說:假如建立書本是乙個非常複雜的操作,比如可能需要呼叫外部服務獲取作者、獲取字數、出版社等資訊,如果每次需要建立一本書籍都需要呼叫方去獲取這些資訊手動new出來,那麼對呼叫方來說工作量巨大,而且會充斥著大量的類似的建立書籍的**,這時考慮使用簡單工廠模式建立,呼叫方只需要告知工廠書籍的名字,具體的建立細節由工廠類去實現。

書籍頂級介面:

public inte***ce book
英語書:

public class englishbook implements book

@override

public string getname()

}

數學書:

public class mathbook implements book

@override

public string getname()

}

工廠類:

public class bookfactory 

switch (name)

}}

呼叫方:

@springboottest

public class factorytest

}

執行結果:

mathbook

englishbook

注意使用簡單工廠模式的關鍵點就是「把一類物件複雜的建立過程放在乙個工廠類中」,這樣帶來的好處顯而易見:1、呼叫方不再需要寫複雜的物件建立邏輯;2、物件建立邏輯放在同乙個類中,如果建立邏輯需要修改,只需要改乙個地方。但是隨著「一類物件」的數量增加,比如有幾百種書,此時bookfactory就會變得非常龐大且複雜,難以維護,這時候就可以考慮工廠方法模式。

上面提到當書籍數量增加,每種書籍的建立邏輯放在乙個工廠類中維護會使得該工廠類難以維護,為了降低工廠類的複雜度,將每種書籍的建立封裝在不同的工廠類中,每個工廠類都對外暴露乙個相同的建立介面,這樣,呼叫方只需要持有乙個父類工廠的引用,而具體的建立工作由具體的子類工廠去實現,這就是工廠方法模式。

頂層的工廠介面:

public inte***ce ibookfactory
英語書工廠實現:

public class englishbookfactory implements ibookfactory 

}

數學書工廠實現:

public class mathbookfactory implements ibookfactory 

}

呼叫方: 

@test

void methodfactory()

執行結果:

englishbook

mathbook

使用工廠方法模式的關鍵點在於「一類物件的數量過多,需要不同的子類工廠封裝不同的建立邏輯」,與簡單工廠比的好處是:工廠中對於不同物件的複雜建立邏輯拆分到各個子類工廠中,便於維護與擴充套件。

看完工廠方法模式似乎已經可以滿足大部分的需求,但是對於一些更一般的情況,比如:數學書有小學數學、中學數學,英語書有小學英語、中學英語,此時按照工廠方法模式需要維護4個子類工廠物件分別對應4種不同的資料,假設不同年級的同一種書籍的建立邏輯有類似部分,那麼維護這麼多的工廠物件是比較浪費的,此時可以考慮將一系列有共性的物件的建立放到相同的子類工廠中,這就是抽象工廠模式。

小學中學

數學英語

抽象工廠模式通常有兩個概念:產品樹與產品族,同乙個產品樹認為是有較大的共性,這種共性指的是建立邏輯上的共性,同乙個產品族被認為有相同的行為方式,這種相同的行為方式體現在**中就是實現了相同的介面。不同的產品樹的工廠是不同的,同乙個產品樹的不同的產品族在同乙個工廠中,但工廠方法不同。比如上述的例子,假如不同年級的數學書的建立邏輯是有共性的,比如他們的出版社相同,而相同年級的不同書籍有相同行為方式,比如小學書籍都教授簡單知識,中學書籍都教授較難知識,那麼就可以認為數學和英語是兩個不同的產品樹,而小學和中學是不同的產品族。當然,產品樹與產品族的劃分要結合應用實際,這裡僅僅是舉個例子,基於這個例子的假設,抽象工廠模式有以下實現:

頂層工廠介面:規約了子類工廠都要有生產產品族中所有產品的能力以及不同產品樹(子類工廠)中對於不同產品的建立方法

// 不同的子類工廠都要實現該介面

// 表示的是每個產品樹都應該有產品族的全部產品

public inte***ce imultibookfactory

英語產品樹:

public class multienglishbookfactory implements imultibookfactory 

@override

public middlebook getmiddlebook()

}

數學產品樹:

public class multimathbookfactory implements imultibookfactory 

@override

public middlebook getmiddlebook()

}

小學產品族:

public inte***ce primarybook
中學產品族:

public inte***ce middlebook
4種具體的產品:

public class englishprimarybook implements primarybook 

}

public class englishmiddlebook implements middlebook 

}

public class mathprimarybook implements primarybook 

}

public class mathmiddlebook implements middlebook 

}

呼叫方:

@test

void abstractfactory()

執行結果:

englishprimarybook

englishmiddlebook

mathprimarybook

mathmiddlebook

使用抽象工廠模式的關鍵點在於「需要建立的物件種類很多,能夠分析出有建立共性的產品樹和有相同行為方式的產品族,乙個產品樹對應乙個子類工廠,乙個產品族對應乙個工廠方法」,好處是邏輯清晰,子類工廠數量不會**,產品樹的擴充套件很容易,缺點也很明顯,產品族的擴充套件會很困難,每增加乙個產品族意味著頂級介面增加乙個方法,那麼所有的子類工廠都需要實現這個方法。

工廠模式是建立型模式,往往建立的是有狀態的物件,如果是無狀態的物件可以使用單例或者策略模式,在實際的應用中,如果工廠建立的類種類少,可以考慮使用簡單工廠或者工廠方法模式,如果物件種類很多且可以輕易的進行產品樹、產品族的劃分且產品族相對穩定(在短時間內增減的可能性很小)則可以考慮使用抽象工廠模式。

設計模式 設計模式之工廠模式

工廠方法模式 建立模式 使用場景?作用?形態?場景 大量類似的實體類 要建立的實體類都是同一本質的東西 披薩 有部分類似功能 準備 烘烤 切法 實現方式不一樣 準備的材料不同 烘烤時間不同 切法不同 將繁瑣複雜的建立類的過程聚集在一起,有序清晰 把具體例項化的過程從客戶 中抽離 作用 1 將建立物件...

c 設計模式 之 工廠模式之 工廠模式

1 uml類圖 實現和依賴關係 實現 sportfactory jeepfactory hatchbackfactory 實現 ifactory 介面 sportcar jeepcar hatchbackcar 實現 icar 介面 依賴 ifactory 依賴 icar sportfactory ...

設計模式 工廠模式之簡單工廠模式

定義 由乙個工廠物件 工廠類 來指定建立某乙個產品類的例項。使用場景 客戶端只需傳入指定的引數即可,工廠類負責建立的物件較少 因為指定了傳入的引數 介面類 本想用iphone命名的,見諒 public inte ce phone實現介面類 public class huaweiphone imple...