學習筆記-設計模式-創建型模式-工廠模式

来源:https://www.cnblogs.com/Andl-Liu/archive/2023/09/06/17681898.html
-Advertisement-
Play Games

### 工廠模式 工廠模式是一種創建者設計模式,細分之下可以分成三類`簡單工廠模式`,`工廠方法模式`和`抽象工廠模式`。 #### 簡單工廠模式 最簡單的工廠模式,它採用靜態方法的方式來決定應該應該生產什麼商品。 ```java public class StoreFactory { public ...


工廠模式

工廠模式是一種創建者設計模式,細分之下可以分成三類簡單工廠模式工廠方法模式抽象工廠模式

簡單工廠模式

最簡單的工廠模式,它採用靜態方法的方式來決定應該應該生產什麼商品。

public class StoreFactory {

    public static ICommodity getCommodityService(Integer commodityType) {
        if (null == commodityType) {
            return null;
        }

        switch (commodityType) {
            case 1:
                return new CouponCommodityService();
            case 2:
                return new GoodsCommodityService();
            case 3:
                return new CardCommodityService();
        }

        throw new RuntimeException("不存在的商品服務類型");
    }

}

它的優點在於

  • 將創建實例的工作與使用實例的工作分開,使用者不必關心類對象如何創建,實現瞭解耦
  • 把初始化實例時的工作放到工廠里進行,使代碼更容易維護,更符合面向對象的原則面向介面編程,而不是面向實現編程

它的缺點在於

  • 工廠類集中了所有實例的創建邏輯,一旦這個工廠不能正常工作,整個系統都會受到影響
  • 違背開閉原則,一旦添加新的產品就不得不修改工廠類的邏輯,這樣就會造成工廠邏輯過於複雜
  • 簡單工廠模式使用了靜態工廠方法,靜態方法不能被繼承和重寫,會造成工廠角色無法形成基於繼承的等級結構

它適用於

  • 客戶只知道傳入工廠類的參數,對於如何創建對象的邏輯不關心時;
  • 當工廠類負責創建的對象比較少時。

工廠方法模式

工廠方法模式中,工廠父類負責定義創建對象的公共介面,而子類則負責生成具體的對象。

它把類的實例化延遲到工廠類的子類中,由子類來決定應該實例化哪個類。

由此,它解決了簡單工廠模式違背了開閉原則的問題。

000.png

它的優點在於

  • 更符合開閉原則
  • 符合單一責任原則,每個具體工廠類只負責創建對應的產品
  • 不使用靜態工廠方法,可以形成基於繼承的等級結構

它的缺點在於

  • 需要的類的數量非常多,每添加一個新產品,就要相應的添加一個新的工廠。
  • 雖然保證了工廠方法內的對修改關閉,但對於使用工廠方法的類,如果要更換另一種產品,仍然需要修改實例化的具體工廠類
  • 一個工廠只能創建一種具體產品

它適用於:

  • 當一個類不需要知道它所需要的對象的類時
  • 當一個類希望通過其子類來指定創建對象時
  • 將創建對象的任務委托給多個工廠子類中的某一個,客戶端在使用時無須關心是哪一個工廠子類創建產品子類,需要時再動態指定,可將具體工廠的類名存儲在配置文件或資料庫中(比如spring中的FactoryBean)

抽象工廠模式

抽象工廠模式定義了一個能生產一個產品族的超級抽象工廠,然後交給子類工廠去生產某一個產品族的產品。

產品族和產品等級

001.png

產品等級結構既是產品的繼承結構。比如一個抽象類是電視機,其子類有海爾電視機、TCL電視機,則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構。

產品族是指由同一個工廠生產的,位於不同產品等級結構中的一組產品,如海爾生產的海爾電視機、海爾洗衣機和海爾冰箱,構成了一個產品族。

設計模式詳解

002.png

圖中,IProductFactory是工廠介面,定義了生產手機和路由器組成的產品族的方法。而子類工廠HuaweiFactory負責生產華為產品族,XiaomiFactory負責生產小米產品族。

另外,IPhoneProductIRouterProduct分別定義了手機和路由器兩個產品等級。

它的優點在於

  • 一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象
  • 可以很方便地添加一個新的產品族

它的缺點在於

  • 產品族的拓展非常困難,要增加一個系列的某一個產品,既要修改工廠抽象類里添加代碼,又要在具體的實現類裡面添加代碼
  • 增加了系統的抽象性和理解難度

它適用於

  • 一系列相關產品對象(屬於同一產品族)一起創建時需要大量的重覆代碼
  • 提供一個產品類的庫,所有的產品以同樣的介面出現,從而使得客戶端不依賴於具體的實現

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ![file](https://img2023.cnblogs.com/other/2685289/202309/2685289-20230906105454530-376816477.jpg) > 導讀:國內某頭部理財服務提供商成立於 2019 年,是股份制銀行中首批獲准籌建、首家獲准開業、首家成 ...
  • 當談到[數據湖](https://www.dtstack.com/dtengine/easylake?src=szsm)的時候,大家都在說,可以把所有數據(結構化/半結構化/非結構化)一股腦都丟進去,進行統一的元數據管理。然後上層計算對接,進行[流批計算](https://www.dtstack.c ...
  • 浙江省工業和信息化廳開展了2023第二季度創新型中小企業評價工作,玖章算術以優秀的自主創新能力通過認定,成為浙江省2023年度創新型中小企業。玖章算術聚焦於雲計算與數據管理基礎技術領域,擁有豐富的研發經驗和專業技術團隊。NineData是新一代的雲原生智能數據管理平臺,包含了數據複製、SQL開發、數... ...
  • `` 數組的includes方法在日常的編程中比較常用到,其作用就是判斷某一數據是否在數組中,通常來說,數組中的數據如果是數字,布爾值,或者字元串的話,都是能夠進行判斷的 例如: ``` [1,2,3,4].includes(3) // true [1,2,3,4].includes(5) // f ...
  • 好家伙, 1.<template>去哪了 在正式內容之前,我們來思考一個問題, 當我們使用vue開發頁面時,<tamplete>中的內容是如何變成我們網頁中的內容的? 它會經歷四步: 解析模板:Vue會解析<template>中的內容,識別出其中的指令、插值表達式({{}}),以及其他元素和屬性。 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一.@click和@click.native的區別 vue @click.native 原生點擊事件: 1,給vue組件綁定事件時候,必須加上native ,不然不會生效(監聽根元素的原生事件,使用 .native 修飾符) 2,等同於在 ...
  • 在vue3中,可以使用vue3的API `defineExpose()`函數結合`ref`或者`$parent`,實現父子組件數據的傳遞。 # 子組件向父組件傳遞數據`defineExpose()`和`ref` - 子組件:通過`defineExpose()` 函數,向外暴露響應式數據或者方法 `` ...
  • 本文給大家介紹了什麼是"編程範式",選擇合適的編程範式可以提高代碼的可讀性、可維護性和可擴展性。 一、 什麼是編程範式? "編程範式"是一種編程思想的總稱,它是指在編寫程式時所採用的基本方法和規範。常見的編程範式有面向對象、函數式、邏輯式等。 選擇合適的編程範式可以提高代碼的可讀性、可維護性和可擴展 ...
一周排行
    -Advertisement-
    Play Games
  • WPF本身不支持直接的3D繪圖,但是它提供了一些用於實現3D效果的高級技術。 如果你想要在WPF中進行3D繪圖,你可以使用兩種主要的方法: WPF 3D:這是一種在WPF應用程式中創建3D圖形的方式。WPF 3D提供了一些基本的3D形狀(如立方體、球體和錐體)以及一些用於控制3D場景和對象的工具(如 ...
  • 一、XML概述 XML(可擴展標記語言)是一種用於描述數據的標記語言,旨在提供一種通用的方式來傳輸和存儲數據,特別是Web應用程式中經常使用的數據。XML並不預定義標記。因此,XML更加靈活,並且可以適用於廣泛的應用領域。 XML文檔由元素(element)、屬性(attribute)和內容(con ...
  • 從今年(2023)三月份開始,Github開始強制用戶開啟兩步驗證2FA(雙因數)登錄驗證,毫無疑問,是出於安全層面的考慮,畢竟Github賬號一旦被盜,所有代碼倉庫都會毀於一旦,關於雙因數登錄的必要性請參見:別讓你的伺服器(vps)淪為肉雞(ssh暴力破解),密鑰驗證、雙向因數登錄值得擁有。 雙因 ...
  • 第一題 下列代碼輸入什麼? public class Test { public static Test t1 = new Test(); { System.out.println("blockA"); } static { System.out.println("blockB"); } publi ...
  • 本文主要涉及的問題:用ElementTree和XPath讀寫XML文件;解決ElementTree新增元素後再寫入格式不統一的問題;QTableWidget單元格設置控制項 ...
  • QStandardItemModel 類作為標準模型,主打“類型通用”,前一篇水文中,老周還沒提到樹形結構的列表,本篇咱們就好好探討一下這貨。 還是老辦法,咱們先做示例,然後再聊知識點。下麵這個例子,使用 QTreeView 組件來顯示數據,使用的列表模型比較簡單,只有一列。 #include <Q ...
  • 一、直充內充(充值方式) 直充: 包裝套餐直接充值到上游API系統。【PID/Smart】 (如:支付寶、微信 話費/流量/語音/簡訊 等 充值系統)。 內充(套餐打包常見物聯卡系統功能): 套餐包裝 適用於不同類型套餐 如 流量、簡訊、語音 等。 (目前已完善流量邏輯) 二、套餐與計費產品 計費產 ...
  • 在前面幾天中,我們學習了Dart基礎語法、可迭代集合,它們是Flutter應用研發的基本功。今天,我們繼續學習Flutter應用另一個必須掌握知識點:非同步編程(即Future和async/await)。它類似於Java中的FutureTask、JavaScript中的Promise。它是後續Flut... ...
  • 針對改動範圍大、影響面廣的需求,我通常會問上線了最壞情況是什麼?應急預案是什麼?你帶開關了嗎?。當然開關也是有成本的,接下來本篇跟大家一起交流下高頻發佈支撐下的功能開關技術理論與實踐結合的點點滴滴。 ...
  • 1.d3.shuffle D3.shuffle() 方法用於將數組中的元素隨機排序。它使用 Fisher–Yates 洗牌演算法,該演算法是無偏的,具有最佳的漸近性能(線性時間和常數記憶體)。 D3.shuffle() 方法的語法如下: d3.shuffle(array, [start, end]) 其中 ...