小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

C#設(shè)計(jì)模式系列:工廠方法模式(Factory Method)

 雪柳花明 2016-09-18

1. 工廠方法模式簡介

1. 工廠方法模式簡介

1.1 定義

  工廠方法模式定義一個(gè)用于創(chuàng)建對象的接口,讓子類決定實(shí)例化哪一個(gè)類。工廠方法模式是以一個(gè)類的實(shí)例化延遲到其子類。

  Factory Method模式用于在不指定待創(chuàng)建對象的具體類的情況下創(chuàng)建對象。

  Factory Method模式的主要意圖是隱藏對象創(chuàng)建的復(fù)雜性。Client通常不指定要?jiǎng)?chuàng)建的具體類,Client將面向接口或抽象類進(jìn)行編碼,讓Factory類負(fù)責(zé)創(chuàng)建具體的類型。通常Factory類有一個(gè)返回抽象類或者接口的靜態(tài)方法。Client通常提供某種信息讓Factory類使用提供的信息來確定創(chuàng)建并返回哪個(gè)子類。

  將創(chuàng)建子類的責(zé)任抽象出來的好處是允許Client完全無需考慮依賴類是如何創(chuàng)建的,這遵守依賴倒置原則(Dependency Inversion Principle,DIP)。Factory Method模式另外一個(gè)好處是把負(fù)責(zé)對象創(chuàng)建的代碼集中起來,如果需要修改對象生成方式,可以輕松定位并更新,而不會(huì)影響到依賴它的代碼。

  在面向?qū)ο缶幊讨?,一般方法是用一個(gè)new操作符產(chǎn)生一個(gè)對象的實(shí)例。但是在一些情況下,用new操作符直接生成對象會(huì)帶來一些問題。首先,要使用new運(yùn)算符創(chuàng)建一個(gè)對象必須清楚所要?jiǎng)?chuàng)建的對象的類信息,包括類名、構(gòu)造函數(shù)等,而有時(shí)并不現(xiàn)實(shí)。其次許多類型的對象創(chuàng)建需要一系列的步驟,可能需要計(jì)算或取得對象的初始設(shè)置,選擇生成那個(gè)子對象實(shí)例,或在生成需要的對象之前必須生成一些輔助功能的對象。在這些情況下,新對象的建立就是一個(gè)過程,而不是一個(gè)簡單的操作。為輕松方便地完成復(fù)雜對象的創(chuàng)建,從而引入了工廠模式。

1.2 使用頻率

   高

2. 工廠方法模式結(jié)構(gòu)

2.1 結(jié)構(gòu)圖

2.2 參與者

  工廠方法模式參與者:

   Product:Product角色,定義工廠方法所創(chuàng)建的對象的接口

   ConcreteProduct:具體Product角色,實(shí)現(xiàn)Product接口

   Factory

    ° 抽象的工廠角色,聲明工廠方法,該方法返回一個(gè)Product類型的對象

    ° Factory可以定義一個(gè)工廠方法的默認(rèn)實(shí)現(xiàn),返回一個(gè)默認(rèn)的ConcreteProduct對象??梢哉{(diào)用工廠方法以創(chuàng)建一個(gè)Product對象。

   ConcreteFactory:具體的工廠角色,創(chuàng)建具體Product的子工廠,重寫工廠方法以返回一個(gè)ConcreteProduct實(shí)例

3. 工廠方法模式結(jié)構(gòu)實(shí)現(xiàn)

  Product.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Structural
{
    /// <summary>
    /// 定義Product抽象類,Client調(diào)用Product抽象類,并由Factory來創(chuàng)建具體類。
    /// </summary>
    public abstract class Product
    {
    }
}
復(fù)制代碼

  ConcreteProductA.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Structural
{
    public class ConcreteProductA : Product
    {
    }
}
復(fù)制代碼

  ConcreteProductB.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Structural
{
    public class ConcreteProductB : Product
    {
    }
}
復(fù)制代碼

  Factory.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Structural
{
    public abstract class Factory
    {
        public abstract Product CreateProduct();
    }
}
復(fù)制代碼

  ConcreteFactoryA.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Structural
{
    public class ConcreteFactoryA : Factory
    {
        public override Product CreateProduct()
        {
            return new ConcreteProductA();
        }
    }
}
復(fù)制代碼

  ConcreteFactoryB.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Structural
{
    public class ConcreteFactoryB : Factory
    {
        public override Product CreateProduct()
        {
            return new ConcreteProductB();
        }
    }
}
復(fù)制代碼

  Program.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DesignPatterns.FactoryMethodPattern.Structural;

namespace DesignPatterns.FactoryMethodPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Factory[] factories = new Factory[2];
            factories[0] = new ConcreteFactoryA();
            factories[1] = new ConcreteFactoryB();

            foreach (Factory factory in factories)
            {
                Product product = factory.CreateProduct();
                Console.WriteLine("Created {0}", product.GetType().Name);
            }
        }
    }
}
復(fù)制代碼

  運(yùn)行輸出:

Created ConcreteProductA
Created ConcreteProductB
請按任意鍵繼續(xù). . .

4. 工廠方法模式實(shí)踐應(yīng)用

  假設(shè)你現(xiàn)在是一家KFC的管理者,要給顧客提供一系列的食品,如雞翅、雞腿等,顧客沒要求一種食品,KFC應(yīng)當(dāng)可以很快生產(chǎn)出來,采用工廠模式來實(shí)現(xiàn)這個(gè)過程。

  KFCFood.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Practical
{
    /// <summary>
    /// 抽象的KFC食品,Product角色
    /// </summary>
    public abstract class KFCFood
    {
        public abstract void Display();
    }
}
復(fù)制代碼

  Chicken.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Practical
{
    public class Chicken : KFCFood
    {
        public override void Display()
        {
            Console.WriteLine("雞腿 + 1");
        }
    }
}
復(fù)制代碼

  Wings.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Practical
{
    public class Wings : KFCFood
    {
        public override void Display()
        {
            Console.WriteLine("雞翅 + 1");
        }
    }
}
復(fù)制代碼

  IKFCFactory.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Practical
{
    public interface IKFCFactory
    {
        KFCFood CreateFood();
    }
}
復(fù)制代碼

  ChickenFactory.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Practical
{
    public class ChickenFactory : IKFCFactory
    {
        public KFCFood CreateFood()
        {
            return new Chicken();
        }
    }
}
復(fù)制代碼

  WingsFactory.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.FactoryMethodPattern.Practical
{
    public class WingsFactory : IKFCFactory
    {
        public KFCFood CreateFood()
        {
            return new Wings();
        }
    }
}
復(fù)制代碼

  Program.cs

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DesignPatterns.FactoryMethodPattern.Practical;

namespace DesignPatterns.FactoryMethodPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // 定義一個(gè)雞腿工廠
            IKFCFactory factory = new ChickenFactory();
            // 生產(chǎn)雞腿
            KFCFood food1 = factory.CreateFood();
            food1.Display();
            // 生產(chǎn)雞腿
            KFCFood food2 = factory.CreateFood();
            food2.Display();
            // 生產(chǎn)雞腿
            KFCFood food3 = factory.CreateFood();
            food3.Display();
        }
    }
}
復(fù)制代碼

  運(yùn)行輸出:

雞腿 + 1
雞腿 + 1
雞腿 + 1
請按任意鍵繼續(xù). . .

  在以上例子中,使用工廠模式的好處:

  1>. 客戶端在創(chuàng)建產(chǎn)品的時(shí)候只需指定一個(gè)子工廠而無需了解該子工廠具體創(chuàng)建什么產(chǎn)品;

  2>. 當(dāng)需求有變動(dòng),要不food1、food2、food3均改為“雞翅”的時(shí)候,只需將

IKFCFactory factory = new ChickenFactory();

  改為

IKFCFactory factory = new WingsFactory();

  即可;

  3>. 在工廠方法模式中,核心的工廠類不是負(fù)責(zé)所有產(chǎn)品的創(chuàng)建,而是將具體的創(chuàng)建工作交給子類ConcreteFactory去做。工廠類僅僅負(fù)責(zé)給出具體工廠必須實(shí)現(xiàn)的接口,而不涉及哪一個(gè)產(chǎn)品類被實(shí)例化這種細(xì)節(jié)。工廠方法模式可以使得系統(tǒng)在不需要修改原有代碼的情況下引進(jìn)新產(chǎn)品,如現(xiàn)在要增加一種新的產(chǎn)品“薯?xiàng)l”,則無需修改原有代碼,只需增加一個(gè)“薯?xiàng)l”產(chǎn)品類和一個(gè)相應(yīng)的“薯?xiàng)l”子工廠即可。在工廠方法模式中,子工廠與產(chǎn)品類往往具有平行的等級結(jié)構(gòu),它們之間一一對應(yīng)。

5. 工廠方法模式應(yīng)用分析

5.1 工廠方法模式適用情形

   當(dāng)一個(gè)類不知道它所必須創(chuàng)建的對象的類信息的時(shí)候

   當(dāng)一個(gè)類希望由它來指定它所創(chuàng)建的對象的時(shí)候

   當(dāng)類將創(chuàng)建對象的職責(zé)委托給多個(gè)輔助子類中的某一個(gè),并且希望將哪一個(gè)輔助之類是代理者這一信息局部化的時(shí)候

5.2 工廠方法模式特點(diǎn)

   使用工廠方法在一個(gè)類的內(nèi)部創(chuàng)建對象通常比直接創(chuàng)建對象更靈活

   工廠方法模式通過面向?qū)ο蟮氖址ǎ瑢⑺獎(jiǎng)?chuàng)建的具體對象的創(chuàng)建工作延遲到子類,從而提供了一種擴(kuò)展的策略,較好的解決了緊耦合的關(guān)系

   工廠方法模式遵守依賴倒置原則(Dependency Inversion Principle,DIP)

5.3 工廠方法模式與簡單工廠模式區(qū)別

   工廠方法模式和簡單工廠模式在結(jié)構(gòu)上的不同是很明顯的。工廠方法模式的核心是一個(gè)抽象工廠類,而簡單工廠模式把核心放在一個(gè)具體工廠類上。工廠方法模式可以允許很多具體工廠類從抽象工廠類中將創(chuàng)建行為繼承下來,從而可以成為多個(gè)簡單工廠模式的綜合,進(jìn)而推廣了簡單工廠模式。

   工廠方法模式退化后可以變得很像簡單工廠模式。如果非常確定一個(gè)系統(tǒng)只需要一個(gè)具體工廠類,那么就不妨把抽象工廠類合并到具體的工廠類中去。由于只有一個(gè)具體工廠類,所以不妨將工廠方法改成為靜態(tài)方法,這時(shí)候就得到了簡單工廠模式

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多