欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.Net創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory)

 更新時(shí)間:2022年05月25日 14:21:23   作者:springsnow  
這篇文章介紹了.Net設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory),文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、動(dòng)機(jī)(Motivation)

在軟件系統(tǒng)中,經(jīng)常面臨著“一系列相互依賴的對(duì)象”的創(chuàng)建工作;同時(shí),由于需求的變化,往往存在更多系列對(duì)象的創(chuàng)建工作。

如何應(yīng)對(duì)這種變化?如何繞過常規(guī)的對(duì)象創(chuàng)建方法(new),提供一種“封裝機(jī)制”來避免客戶程序和這種“多系列具體對(duì)象創(chuàng)建工作”的緊耦合?

二、意圖(Intent)

提供一個(gè)接口,讓該接口負(fù)責(zé)創(chuàng)建一系列“相關(guān)或者相互依賴的對(duì)象”,無需指定它們具體的類。

三、結(jié)構(gòu)(Structure)

ProductA1和ProductB1是一個(gè)系列,ProductA2和ProductB2是另一個(gè)系列。ConcreteFactory1是創(chuàng)建系列1的工廠方法,ConcreteFactory2是創(chuàng)建系列2的工廠方法??蛻舫绦駽lient只依賴了AbstractFactory和AbstractProductA、AbstractProductB,也就是客戶程序不依賴于具體實(shí)現(xiàn),而是只依賴與抽象類。

如果現(xiàn)在需要?jiǎng)?chuàng)建一個(gè)系列3運(yùn)用到客戶程序,我們只需要再寫一個(gè)系列3的工廠,繼承自AbstractFactory,這個(gè)工廠提供了2個(gè)實(shí)現(xiàn):

CreateProductA();

CreateProductB();

它們分別返回ProductA3(繼承自AbstractProductA)、ProductB3(繼承自AbstractProductB)。

也就是說,如果新增了系列3,Client程序可以完全不用改動(dòng),可能只需要改一些配置文件,增加一些新dll就可以應(yīng)對(duì)變化。

四、模式的組成

可以看出,在抽象工廠模式的結(jié)構(gòu)圖有以下角色:

(1)、抽象產(chǎn)品類角色(AbstractProduct):為抽象工廠中相互依賴的每種產(chǎn)品定義抽象接口對(duì)象,也可以這樣說,有幾種產(chǎn)品,就要聲明幾個(gè)抽象角色,每一個(gè)抽象產(chǎn)品角色和一種具體的產(chǎn)品相匹配。
(2)、具體產(chǎn)品類(ConcreteProduct):具體產(chǎn)品類實(shí)現(xiàn)了抽象產(chǎn)品類,是針對(duì)某個(gè)具體產(chǎn)品的實(shí)現(xiàn)的類型。
(3)、抽象工廠類角色(Abstract Factory):定義了創(chuàng)建一組相互依賴的產(chǎn)品對(duì)象的接口操作,每種操作和每種產(chǎn)品一一對(duì)應(yīng)。
(4)、具體工廠類角色(ConcreteFactory):實(shí)現(xiàn)抽象類里面的所有抽象接口操作,可以創(chuàng)建某系列具體的產(chǎn)品,這些具體的產(chǎn)品是“抽象產(chǎn)品類角色”的子類。

五、抽象工廠的具體代碼實(shí)現(xiàn)

作為長子的我,希望能有一套歐式風(fēng)格的房子,再加上田園風(fēng)光,此生足矣。我弟弟就不一樣了,他想要一套現(xiàn)代樣式的房子,如果兄弟姊妹再多年一點(diǎn),那就有更多的要求了。由于房子由房頂、地板、窗戶和房門組成,其他組件暫時(shí)省略,有這么多套房子要建設(shè),每套房子的房頂、地板、窗戶和房門都是一個(gè)體系的,那就讓我們看看如何使用【抽象工廠】模式來實(shí)現(xiàn)不同房屋的建造。

//抽象道路
public abstract class Road
{
}

//抽象房屋
public abstract class Building
{
}

//現(xiàn)代風(fēng)格道路
public class ModernRoad : Road
{
}

//現(xiàn)代風(fēng)格房屋
public class ModernBuilding : Building
{
}

//古典風(fēng)格道路
public class ClassicRoad : Road
{
}

//古典風(fēng)格房屋
public class ClassicBuilding : Building
{
}
//抽象工廠
public abstract class FacilitiesFactory
{
    public abstract Road CreateRoad();
    public abstract Building CreateBuilding();
}

//現(xiàn)代風(fēng)格
public class ModernFacilitiesFactory : FacilitiesFactory
{
    public override Road CreateRoad()
    {
        return new ModernRoad();
    }

    public override Building CreateBuilding()
    {
        return new ModernBuilding();
    }
}

//古典風(fēng)格
public class ClassicFacilitiesFactory : FacilitiesFactory
{
    public override Road CreateRoad()
    {
        return new ClassicRoad();
    }

    public override Building CreateBuilding()
    {
        return new ClassicBuilding();
    }
}

客戶程序:

可以看出,客戶程序依賴的全部是抽象類,在客戶程序代碼中沒有出現(xiàn)過任何具體的實(shí)現(xiàn)類。因?yàn)樵谙盗行枰兓臅r(shí)候,是不需要改變抽象類的,只是增加一個(gè)抽象類的實(shí)現(xiàn)而已,又由于客戶程序只依賴于抽象,所以系列變化的時(shí)候客戶程序完全無需變化。

internal class GameManager
{

    private FacilitiesFactory facilitiesFactory;
    private Road road;
    private Building building;

    public GameManager(FacilitiesFactory facilitiesFactory)
    {
        this.facilitiesFactory = facilitiesFactory;
    }

    public void BuildGameFacilities()
    {
        road = facilitiesFactory.CreateRoad();
        building = facilitiesFactory.CreateBuilding();
    }

    public void Run()
    {
        Console.WriteLine(road);
        Console.WriteLine(building);
    }
}

應(yīng)用到具體程序(現(xiàn)代風(fēng)格):

可以看出,風(fēng)格由Modern改變?yōu)镃lassic的時(shí)候,我們封裝好的GameManager客戶程序沒有改變,這就是我們想要的結(jié)果。GameManager的邏輯非常復(fù)雜,現(xiàn)在它的穩(wěn)定,能夠大大方便我們的工作。

GameManager g = new GameManager(new ModernFacilitiesFactory());
g.BuildGameFacilities();
g.Run();

改造

第一種改造

就是在系列對(duì)象不發(fā)生系列添加的情況下,使用配置文件來進(jìn)行例子中場景風(fēng)格的替換。添加一個(gè)App.config文件,在其中加入風(fēng)格設(shè)置的字段。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
         <appSettings>
              <add key="factoryName" value="ModernFacilitiesFactory"></add>
         </appSettings>
</configuration>

然后,在代碼中讀取這個(gè)配置字段,根據(jù)配置字段的值來做實(shí)現(xiàn)。首先實(shí)現(xiàn)一個(gè)構(gòu)建方法,然后再在客戶程序中調(diào)用。

public static FacilitiesFactory GetInstance()
{
    string factoryName = ConfigurationSettings.AppSettings["factoryName"];
    FacilitiesFactory f;
    switch (factoryName)
    {
        case "ModernFacilitiesFactory":
            f = new ModernFacilitiesFactory();
            break;
        case "ClassicFacilitiesFactory":
            f = new ClassicFacilitiesFactory();
            break;
        default:
            f = null;
            break;
    }

    return f;
}
//客戶程序
public static void Main()
{
    GameManager g = new GameManager(GetInstance());
    g.BuildGameFacilities();
    g.Run();
}

第二種改造

其實(shí)還有一種需求就是擴(kuò)展新的系列對(duì)象,如果還是不需要對(duì)客戶程序進(jìn)行維護(hù),而僅是添加了新的系列對(duì)象的類,那將是很舒服的一件事。這樣我們就可以通過添加DLL并配合配置文件的使用,就能在不修改源程序代碼的情況下,擴(kuò)展出我們需要的新的系列對(duì)象

public staticFacilitiesFactory GetInstance()
{
    string factoryName = ConfigurationSettings.AppSettings["factoryName"];
    FacilitiesFactory f;
    if (factoryName != "")
        f = (FacilitiesFactory)Assembly.Load(factoryName).CreateInstance(factoryName);
    else
        f = null;
    return f;
}

這樣,我們在擴(kuò)展時(shí)僅需將擴(kuò)展的DLL放在相應(yīng)的路徑下并配合配置文件即實(shí)現(xiàn)了我們的擴(kuò)展。

六、抽象工廠的實(shí)現(xiàn)要點(diǎn)

  • 如果沒有應(yīng)對(duì)“多系列對(duì)象創(chuàng)建”的需求變化,則沒有必要使用AbstractFactory模式,這時(shí)候使用簡單的靜態(tài)工廠完全可以。
  • “系列對(duì)象"指的是這些對(duì)象之間有相互依賴、或作用的關(guān)系,例如游戲開發(fā)場景中“道路”與“房屋”的依賴,“道路”與“地道”的依賴。
  • AbstractFactory模式主要在于應(yīng)對(duì)“新系列”的需求變動(dòng)。其缺點(diǎn)在于難以應(yīng)對(duì)“新對(duì)象”的需求變動(dòng)。
  • AbstractFactory模式經(jīng)常和FactoryMethod模式共同組合來應(yīng)對(duì)“對(duì)象創(chuàng)建”的需求變化。

抽象工廠模式的優(yōu)點(diǎn):

【抽象工廠】模式將系列產(chǎn)品的創(chuàng)建工作延遲到具體工廠的子類中,我們聲明工廠類變量的時(shí)候是使用的抽象類型,同理,我們使用產(chǎn)品類型也是抽象類型,這樣做就盡可能的可以減少客戶端代碼與具體產(chǎn)品類之間的依賴,從而降低了系統(tǒng)的耦合度。耦合度降低了,對(duì)于后期的維護(hù)和擴(kuò)展就更有利,這也就是【抽象工廠】模式的優(yōu)點(diǎn)所在。可能有人會(huì)說在Main方法里面(這里的代碼就是客戶端的使用方)還是會(huì)使用具體的工廠類,對(duì)的。這個(gè)其實(shí)我們通過Net的配置,把這部分移出去,最后把依賴關(guān)系放到配置文件中。如果有新的需求我們只需要修改配置文件,根本就不需要修改代碼了,讓客戶代碼更穩(wěn)定。依賴關(guān)系肯定會(huì)存在,我們要做的就是降低依賴,想完全去除很難,也不現(xiàn)實(shí)。

抽象工廠模式的缺點(diǎn):

有優(yōu)點(diǎn)肯定就有缺點(diǎn),因?yàn)槊糠N模式都有他的使用范圍,或者說要解決的問題,不能解決的問題就是缺點(diǎn)了,其實(shí)也不能叫缺點(diǎn)了?!境橄蠊S】模式很難支持增加新產(chǎn)品的變化,這是因?yàn)槌橄蠊S接口中已經(jīng)確定了可以被創(chuàng)建的產(chǎn)品集合,如果需要添加新產(chǎn)品,此時(shí)就必須去修改抽象工廠的接口,這樣就涉及到抽象工廠類的以及所有子類的改變,這樣也就違背了“開發(fā)——封閉”原則。

抽象工廠模式的使用場景:

如果系統(tǒng)需要多套的代碼解決方案,并且每套的代碼方案中又有很多相互關(guān)聯(lián)的產(chǎn)品類型,并且在系統(tǒng)中我們可以相互替換的使用一套產(chǎn)品的時(shí)候可以使用該模式,客戶端不需要依賴具體實(shí)現(xiàn)。

七、.NET中抽象工廠模式實(shí)現(xiàn)

微軟的類庫發(fā)展了這么多年,設(shè)計(jì)模式在里面有大量的應(yīng)用,【抽象工廠】模式在.NET類庫中也存在著大量的使用,比如和操作數(shù)據(jù)庫有關(guān)的類型,這個(gè)類就是System.Data.Common.DbProviderFactory,這個(gè)類位于System.Data.dll程序集中。該類扮演抽象工廠模式中抽象工廠的角色,DbProviderFactory就是【抽象工廠】模式UML里面AbstractFactory類型。其他具體的工廠類型繼承DbProviderFactory類型。

到此這篇關(guān)于.Net設(shè)計(jì)模式之抽象工廠模式(Abstract Factory)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • .Net?6簡介并和之前版本寫法做對(duì)比

    .Net?6簡介并和之前版本寫法做對(duì)比

    這篇文章介紹了.Net?6簡介并和之前版本寫法做對(duì)比,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • .NET?6更新使.NET生態(tài)系統(tǒng)蛻變

    .NET?6更新使.NET生態(tài)系統(tǒng)蛻變

    微軟正式發(fā)布.NET最新長期支持版本.NET?6,這個(gè)版本的更新重點(diǎn),除了C#和F#都有許多語言功能改進(jìn)之外,.NET?6終于集大成,成為跨瀏覽器、云計(jì)算、桌面、物聯(lián)網(wǎng)和移動(dòng)應(yīng)用程序的統(tǒng)一平臺(tái),性能也獲得大幅提升,并且更完整支持Arm64
    2022-01-01
  • .net?6精簡版webapi教程及熱重載、代碼自動(dòng)反編譯演示

    .net?6精簡版webapi教程及熱重載、代碼自動(dòng)反編譯演示

    這篇文章介紹了.net?6精簡版webapi教程及熱重載、代碼自動(dòng)反編譯演示,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • 搭建基礎(chǔ)結(jié)構(gòu)的ABP解決方案介紹

    搭建基礎(chǔ)結(jié)構(gòu)的ABP解決方案介紹

    這篇文章介紹了搭建基礎(chǔ)結(jié)構(gòu)的ABP解決方案的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • .net6引入autofac框架

    .net6引入autofac框架

    這篇文章介紹了.net6引入autofac框架的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • .net?core中的System.Buffers命名空間

    .net?core中的System.Buffers命名空間

    這篇文章介紹了.net?core中的System.Buffers命名空間,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • WPF框架Prism中導(dǎo)航Navigation用法介紹

    WPF框架Prism中導(dǎo)航Navigation用法介紹

    這篇文章介紹了WPF框架Prism中導(dǎo)航Navigation的用法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • .Net中的不可變集合(Immutable Collection)程序集簡介

    .Net中的不可變集合(Immutable Collection)程序集簡介

    這篇文章介紹了.Net中的不可變集合(Immutable Collection)程序集,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • ASP.NET Core應(yīng)用程序配置文件AppSetting.json

    ASP.NET Core應(yīng)用程序配置文件AppSetting.json

    這篇文章介紹了ASP.NET Core應(yīng)用程序配置文件AppSetting.json,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • ASP.NET中HiddenField隱藏域控件的使用方法

    ASP.NET中HiddenField隱藏域控件的使用方法

    本文主要介紹ASP.NET中HiddenField控件的基礎(chǔ)使用方法、事件以及配合javascript的一些使用,希望能幫到大家。
    2016-04-04

最新評(píng)論