設計模式--抽象工廠(個人筆記)

一、抽象工廠的應用場景以及優缺點

1? 應用場景:

? ? ? 如果系統需要多套的代碼解決方案,并且每套的代碼解決方案中又有很多相互關聯的產品類型,并且在系統中我們可以相互替換的使用一套產品的時候可以使用該模式,客戶端不需要依賴具體的實現。

2?優點:

? ? ? 抽象工廠模式將產品的創建工作遲到了具體工廠的子類中,我們聲明工廠類變量的時候是使用的抽象類型,同理,我們使用產品類型也是抽象類型。

? ? ? 這樣做就盡可能的減少了客戶端代碼與產品類之間的依賴,從而降低了系統的耦合度。耦合度降低了,對于后期的維護和擴展就更加的有利。

3?缺點:

? ? ? 抽象工廠模式很難支持增加新產品的變化,這是因為抽象工廠接口中已經明確了可以被創建的產品集合,如果需要添加新產品,此時就必須去修改抽象工廠的接口,

? ? ? 這樣就涉及到抽象工廠類的以及所有子類的變化。也就違背了“開放--封閉”原則。

4.實現要點:

? ? ? ?1)、如果沒有應對“多系列對象創建”的需求變化,則沒有必要使用AbstractFactory模式,這時候使用簡單的靜態工廠完全可以。

? ? ? ?2)、"系列對象"指的是這些對象之間有相互依賴、或作用的關系,例如游戲開發場景中“道路”與“房屋”的依賴,“道路”與“地道”的依賴。

? ? ? ?3)、AbstractFactory模式主要在于應對“新系列”的需求變動。其缺點在于難以應對“新對象”的需求變動。

? ? ? ?4)、AbstractFactory模式經常和FactoryMethod模式共同組合來應對“對象創建”的需求變化。

二、模式的組成

1?抽象產品類角色(AbstractProduct):

? ? ? ?為抽象工廠中相互依賴的每種產品定義抽象接口對象,

? ? ? ?也可以這樣說,有幾種產品,就要聲明幾個抽象角色,?每一個抽象角色和一種具體的產品相匹配。

2?具體產品類(ConcreteProduct):

? ? ? ?具體產品類實現了抽象產品類,是針對某個具體產品的實現的類型。

3? 抽象工廠類角色(AbstractFactory):

? ? ? ? 定義了創建一組相互依賴的產品對象的接口操作,每種操作和每種產品一一對應。

4? 具體工廠類角色(ConcreteFactory):

? ? ? ? 實現抽象類里面的所有抽象接口操作,可以創建某系列具體的產品,這些具體的產品是“抽象產品類角色”的子類。

三、代碼

? 1.基本代碼:

 #region 創建抽象類/// <summary>/// 房頂抽象類,子類的房頂必須繼承該類/// </summary>public abstract class Roof{/// <summary>/// 創建房頂/// </summary>public abstract void Create();}/// <summary>/// 地板抽象類,子類的地板必須繼承該類/// </summary>public abstract class Floor{/// <summary>/// 創建地板/// </summary>public abstract void Create();}/// <summary>/// 窗戶抽象類,子類的窗戶必須繼承該類/// </summary>public abstract class Window{/// <summary>/// 創建窗戶/// </summary>public abstract void Create();}/// <summary>/// 房門抽象類,子類的房門必須繼承該類/// </summary>public abstract class Door{/// <summary>/// 創建房門/// </summary>public abstract void Create();}/// <summary>/// 桌子抽象類,子類的房門必須繼承該類/// </summary>public abstract class Dask{/// <summary>/// 創建桌子/// </summary>public abstract void Create();}#endregion 創建抽象類#region 實現具體類/// <summary>/// 歐式地板類/// </summary>public class EuropeanFloor : Floor{public override void Create(){Console.WriteLine("創建歐式的地板");}}/// <summary>/// 歐式的房頂/// </summary>public class EuropeanRoof : Roof{public override void Create(){Console.WriteLine("創建歐式的房頂");}}/// <summary>///歐式的窗戶/// </summary>public class EuropeanWindow : Window{public override void Create(){Console.WriteLine("創建歐式的窗戶");}}/// <summary>/// 歐式的房門/// </summary>public class EuropeanDoor : Door{public override void Create(){Console.WriteLine("創建歐式的房門");}}/// <summary>/// 歐式桌子類/// </summary>public class EuropeanDask : Dask{public override void Create(){Console.WriteLine("創建歐式的桌子");}}/// <summary>/// 現代的房頂/// </summary>public class ModernizationRoof : Roof{public override void Create(){Console.WriteLine("創建現代的房頂");}}/// <summary>/// 現代的地板/// </summary>public class ModernizationFloor : Floor{public override void Create(){Console.WriteLine("創建現代的地板");}}/// <summary>/// 現代的窗戶/// </summary>public class ModernizationWindow : Window{public override void Create(){Console.WriteLine("創建現代的窗戶");}}/// <summary>/// 現代的房門/// </summary>public class ModernizationDoor : Door{public override void Create(){Console.WriteLine("創建現代的房門");}}/// <summary>/// 現代的桌子(擴展)/// </summary>public class ModernizationDask : Dask{public override void Create(){Console.WriteLine("創建現代的桌子");}}#endregion 實現具體類#region 創建抽象工廠類/// <summary>/// 抽象工廠類,提供創建不同類型房子的接口/// </summary>public abstract class AbstractFactory{// 抽象工廠提供創建一系列產品的接口,這里作為例子,只給出了房頂、地板、窗戶和房門創建接口public abstract Roof CreateRoof(); //(可多可單)public abstract Floor CreateFloor();public abstract Window CreateWindow();public abstract Door CreateDoor();public abstract Dask CreateDask();//(擴展)}#endregion#region 實現抽象工廠類/// <summary>/// 歐式風格房子的工廠,負責創建歐式風格的房子/// </summary>public class EuropeanFactory : AbstractFactory{// 制作歐式房頂public override Roof CreateRoof(){return new EuropeanRoof();}// 制作歐式地板public override Floor CreateFloor(){return new EuropeanFloor();}// 制作歐式窗戶public override Window CreateWindow(){return new EuropeanWindow();}// 制作歐式房門public override Door CreateDoor(){return new EuropeanDoor();}// 制作歐式桌子(擴展)public override Dask CreateDask(){return new EuropeanDask();}}/// <summary>/// 現在風格房子的工廠,負責創建現代風格的房子/// </summary>public class ModernizationFactory : AbstractFactory{// 制作現代房頂public override Roof CreateRoof(){return new ModernizationRoof();}// 制作現代地板public override Floor CreateFloor(){return new ModernizationFloor();}// 制作現代窗戶public override Window CreateWindow(){return new ModernizationWindow();}// 制作現代房門public override Door CreateDoor(){return new ModernizationDoor();}// 制作現代桌子只有現代有)public override Dask CreateDask(){return new ModernizationDask();}}#endregion

?

? 2.擴展代碼:

? ?新建一套古典風格的房子:

?

/// <summary>///先為表弟的房子來建立一個工廠類吧/// </summary>public class ClassicalFactory : AbstractFactory{//創建房頂public override Roof CreateRoof(){return new  ClassicalRoof();}// 創建地板public override Floor CreateFloor(){return new  ClassicalFloor();}// 創建窗戶public override Window CreateWindow(){return new  ClassicalWindow();}// 創建房門public override Door CreateDoor(){return new  ClassicalDoor();}}/// <summary>///古典的房頂/// </summary>public class  ClassicalRoof : Roof{public override void Create(){Console.WriteLine("創建古典的房頂");}}/// <summary>/// 古典的地板/// </summary>public class  ClassicalFloor : Floor{public override void Create(){Console.WriteLine("創建古典的地板");}}/// <summary>/// 古典的窗戶/// </summary>public class  ClassicalWindow : Window{public override void Create(){Console.WriteLine("創建古典的窗戶");}}/// <summary>/// 古典的房門/// </summary>public class  ClassicalDoor: Door{public override void Create(){Console.WriteLine("創建古典的房門");}}

  此時,只需要添加五個類:一個是古典風格工廠類,負責創建古典風格的房子,另外幾個類是具有古典風格的房頂、地板、窗戶和房門的具體產品。

? ? ? ?從上面代碼看出,抽象工廠對于系列產品的變化支持 “開放——封閉”原則(指的是要求系統對擴展開放,對修改封? 閉),擴展起來非常簡便,

? ? ? ? 但是,抽象工廠對于增加新產品這種情況就不支持”開放——封閉 “原則,因為要修改創建系列產品的抽象基類 AbstractFactory,增加相應產品的創建方法,這也是抽象工廠的缺點所在。

?

說明:此文章純屬個人筆記,加深記憶,希望以后能寫出自己的作品。

?

轉載于:https://www.cnblogs.com/BounceGuo/p/10180015.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/450278.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/450278.shtml
英文地址,請注明出處:http://en.pswp.cn/news/450278.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

利用阿里云OSS對文件進行存儲,上傳等操作

--pom.xml加入阿里OSS存儲依賴 <!--阿里云OSS存儲--> <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>2.8.3</version> </dependency> --配置阿里云oss相關常量參數 /…

Java并發編程之ThreadGroup

ThreadGroup是Java提供的一種對線程進行分組管理的手段&#xff0c;可以對所有線程以組為單位進行操作&#xff0c;如設置優先級、守護線程等。 線程組也有父子的概念&#xff0c;如下圖&#xff1a; 線程組的創建 1 public class ThreadGroupCreator {2 3 public static v…

springboot 緩存ehcache的簡單使用

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 步驟&#xff1a; 1. pom文件中加 maven jar包&#xff1a; <!-- ehcache 緩存 --><dependency><groupId>net.sf.eh…

Spring boot + mybatis plus 快速構建項目,生成基本業務操作代碼。

---進行業務建表&#xff0c;這邊根據個人業務分析&#xff0c;不具體操作 --加入mybatis plus pom依賴 <!-- mybatis-plus 3.0.5--> <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId>&l…

給手機瀏覽器減負 輕裝上陣才能速度制勝

隨著手機瀏覽器的發展&#xff0c;瀏覽器已經變得臃腫不堪&#xff0c;各種“功能”系于一身&#xff0c;有廣告、社區、樂園等等&#xff0c;我們真的需要它們嗎&#xff1f;如何才能讓瀏覽器做到輕裝上陣&#xff0c;又能高效滿足我們需求呢&#xff1f; 過多“功能”的瀏覽器…

653. Two Sum IV - Input is a BST

題目來源&#xff1a; 自我感覺難度/真實難度&#xff1a; 題意&#xff1a; 分析&#xff1a; 自己的代碼&#xff1a; class Solution(object):def findTarget(self, root, k):""":type root: TreeNode:type k: int:rtype: bool"""Allself.InO…

解決 dubbo問題:Forbid consumer 192.xx.xx.1 access service com.xx.xx.xx.rpc.api.xx from registry 116.xx1

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 我的情況是&#xff1a; 原本我把服務放在A工程中&#xff0c;后來改到B工程中了&#xff0c;所以原來的服務不存在了&#xff0c;查不…

vue學習:7、路由跳轉

2019獨角獸企業重金招聘Python工程師標準>>> <body><div id"app"></div></body><script type"text/javascript">var Login {template: <div>我是登陸界面</div>};var Register {template: <div…

Spring Retry 重試機制實現及原理

概要 Spring實現了一套重試機制&#xff0c;功能簡單實用。Spring Retry是從Spring Batch獨立出來的一個功能&#xff0c;已經廣泛應用于Spring Batch,Spring Integration, Spring for Apache Hadoop等Spring項目。本文將講述如何使用Spring Retry及其實現原理。 背景 重試&…

inline 內聯函數詳解 內聯函數與宏定義的區別

一、在C&C中   一、inline 關鍵字用來定義一個類的內聯函數&#xff0c;引入它的主要原因是用它替代C中表達式形式的宏定義。表達式形式的宏定義一例&#xff1a;#define ExpressionName(Var1,Var2) ((Var1)(Var2))*((Var1)-(Var2))為什么要取代這種形式呢&#xff0c;且…

Oracle序列更新為主鍵最大值

我們在使用 Oracle 數據庫的時候&#xff0c;有時候會選擇使用自增序列作為主鍵。但是在開發過程中往往會遇到一些不規范的操作&#xff0c;導致表的主鍵值不是使用序列插入的。這樣在數據移植的時候就會出現各種各樣的問題。當然數據庫主鍵不使用序列是一種很好的方式&#xf…

dubbo forbid service的解決辦法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 017-05-31 10:36:54.523 [http-nio-8080-exec-5] ERROR c.h.pdl.web.APIExceptionHandler - Unknown Exception, URI /payday-loan-co…

用SSH登錄遠程的機器,在遠程機器上執行本地機器上的腳本

假設本地的機器IP為10.245.111.90&#xff0c;我們想要在10.245.111.93上執行一個保存在10.245.111.90上的腳本。經過測試通過的命令如下&#xff1a;ssh root10.245.111.93 bash -s < /root/testlocal.sh如果要帶參數的話&#xff0c;那就需要參考這篇文章中描述的代碼了。…

golang學習之旅(1)

這段時間我開始了golang語言學習&#xff0c;其實也是為了個人的職業發展的拓展和衍生&#xff0c;語言只是工具&#xff0c;但是每個語言由于各自的特點和優勢&#xff0c;golang對于當前編程語言的環境&#xff0c;是相對比較新的語言&#xff0c;對于區塊鏈&#xff0c;大數…

為什么要在Linux平臺上學C語言?用Windows學C語言不好嗎?

用Windows還真的是學不好C語言。C語言是一種面向底層的編程語言&#xff0c;要寫好C程序&#xff0c;必須對操作系統的工作原理非常清楚&#xff0c;因為操作系統也是用C寫的&#xff0c;我們用C寫應用程序直接使用操作系統提供的接口&#xff0c;Linux是一種開源的操作系統&am…

數據庫中Schema(模式)概念的理解

在學習SQL的過程中&#xff0c;會遇到一個讓你迷糊的Schema的概念。實際上&#xff0c;schema就是數據庫對象的集合&#xff0c;這個集合包含了各種對象如&#xff1a;表、視圖、存儲過程、索引等。為了區分不同的集合&#xff0c;就需要給不同的集合起不同的名字&#xff0c;默…

linux系統中打rz命令后出現waiting to receive.**B0100000023be50

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 linux系統中打rz命令后出現 waiting to receive.**B0100000023be50 而沒有出現選擇文件彈出框是什么問題&#xff1a; 我本來用的是 gi…

golang學習之旅(2)- go的數據基本數據類型及變量定義方式

叮鈴鈴&#xff0c;這不有人在評論問下一篇何時更新&#xff0c;這不就來了嘛&#xff0c;&#x1f604; 今天我們說說golang 的基本數據類型 基本類型如下&#xff1a; //基本類型 布爾類型&#xff1a;bool 即true 、flase 類似于java中的boolean 字符類型&#xff1a;s…

StackExchange.Redis 官方文檔(六) PipelinesMultiplexers

流水線和復用 糟糕的時間浪費。現代的計算機以驚人的速度產生大量的數據&#xff0c;而且高速網絡通道(通常在重要的服務器之間同時存在多個鏈路)提供了很高的帶寬&#xff0c;但是計算機花費了大量的時間在 等待數據 上面&#xff0c;這也是造成使用持久性鏈接的編程方式越來越…

開發優秀產品的六大秘訣

摘要&#xff1a;本文是Totango的聯合創始人兼公司CEO Guy Nirpaz發表在Mashable.com上的文章。無論是在哪個行業&#xff0c;用戶永遠是一款產品的中心&#xff0c;本文作者就以用戶為中心&#xff0c;為大家講述了六個如何為企業產品添加功能的秘訣。 隨著云計算的發展&#…