C#工厂模式



1:工厂模式

最近一直在看设计模式,想把自己的学习笔记与大家分享一下,如果能帮助大家的话,我会非常高兴,同时也欢迎大家指出里面的不足。园子里其实关于此类文章已经很多了,如果dudu感觉放在首页欠妥的话,可以调一下。
简单工厂模式(Simple Factory Pattern
介绍:简单工厂模式不能说是一个设计模式,说它是一种编程习惯可能更恰当些。因为它至少不是Gof23种设计模式之一。但它在实际的编程中经常被用到,而且思想也非常简单,可以说是工厂方法模式的一个引导,所以我想有必要把它作为第一个讲一下。
引入:
我们在编程的时候,每当"new"一个对象之后,这个对象就依赖于这个类了。如果在后期的维护过程中由于某些原因需要修改一下这个类,则唯一的做法就是打开源代码,进行修改,修改所有与这个对象有关的操作。这对我们是非常不利的。
问题出来了:对象不能应对具体实例化类型的变化
解决思路:套用一下李建忠李老师的话,封装变化点,哪里变化,封装哪里。在这个例子中,要实例化的类变了,就将实例化这个操作封装起来,我们可以把"new"这个操作移交一个具体的类,由它去负责根据我们的条件创建具体类的实例,也就是下面要说的简单工厂模式
定义:
专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类或接口。简单工厂模式又称为静态工厂方法(Static Factory Method)模式,属于类的创建型模式,通常根据一个条件(参数)来返回不同的类的实例。
意图:
提供一个类,由它负责根据一定的条件创建某一具体类的实例
参与者: 

· 工厂角色(Creator
是简单工厂模式的核心,它负责实现创建所有具体产品类的实例。工厂类可以被外界直接调用,创建所需的产品对象。 

· 抽象产品角色(Product
是所有具体产品角色的父类,它负责描述所有实例所共有的公共接口。 

· 具体产品角色(Concrete Product
继承自抽象产品角色,一般为多个,是简单工厂模式的创建目标。工厂类返回的都是该角色的某一具体产品。 

UML图:


现实生活中例子:
每次参加不同的聚会或者与不同的人见面,可能穿的衣服是不一样的,比如,你今天上午要与你的一个新客户见面,你可能会对你的老婆说:老婆,给拿件商务装(参数),我要去见我的一个客户,你老婆(工厂类)接到你的请求(商务装参数)后,从衣柜中取出一件商务装(具体产品),交给你。整个过程就完成了。
分析:
你可能根据不同的条件,要的衣服是不一样的,但要的衣服都是已经在你的衣柜中存在的。并且,每件上衣它们都属于同一种抽象,即它们可以从一个抽象类或接口 中继承,这此衣服各自都有一定特征,这些都是条件。然后你要的时候,就可以向你老婆说一种特征,她就会根据这个特征为你服务了。这就是典型的简单工厂模式 的应用。

2:简单工厂模式

 抽象产品类代码

2.1 建立接口

public class ICoats

    {

       public interface ICoat

       {

           voidGetYourCoat();

       }

    }

2.2 继承接口并实现接口

 

    public class BusinessCoat: FactoryMode.Interfaces.ICoats.ICoat

    {

 

        public void GetYourCoat()

        {

            Console.WriteLine("商务上衣");

        }

}

 

public class FashionCoat: FactoryMode.Interfaces.ICoats.ICoat

    {

        public void GetYourCoat()

        {

            Console.WriteLine("时尚大衣");

        }

}

2.3 建立静态的简单工厂类

  public FactoryMode.Interfaces.ICoats.ICoatCreateCoat(string styleName)

       {

         

               switch(styleName)

               {

                   case"business":

                       returnnew BusinessCoat();

                   case"fashion":

                       returnnew FashionCoat();

                   default:

                       thrownew Exception("还没有你要的那种衣服");

               }

          

       }

}

2.4 调用

namespaceFactoryMode

{

    class Program

    {

        public static  FactoryMode.Interfaces.ICoats.ICoatfood;

        static void Main(string[]args)

        {

            try

            {

                Console.Write("我要的是时尚上衣\t");

                Factoryfa = new Factory();

                food = fa.CreateCoat("business");

                food.GetYourCoat();

                Console.Read();

            }

            catch(Exception

                ex)

            {

                Console.Write(ex.ToString());

 

            }

        }

    }

}

3 工厂模式

工厂方法模式又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂模式(Polymorphic Factory,在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成, 即由子类来决定究竟应该实例化(创建)哪一个类。

意图
定义一个用户创建对象的接口,让子类决定实例化哪一个类,工厂方法模式使一个类的实例化延迟到其子类。

参与者

· 抽象产品角色(Product
定义产品的接口 

· 具体产品角色(ConcreteProduct 
实现接口Product的具体产品类 

· 抽象工厂角色(Creator 
声明工厂方法(FactoryMethod),返回一个产品 

· 真实的工厂(ConcreteCreator
实现FactoryMethod工厂方法,由客户调用,返回一个产品的实例 

3.1抽象角色类

//抽象产品角色代码

   public interface ICoat

    {

       voidShowICoat();

    }

3.2 具体的角色类

  public class BusinessCoat:ICoat

    {

        public void ShowICoat()

        {

            Console.WriteLine("这件是商务上衣");

        }

    }

  public class FashionCoat:ICoat

    {

        public void ShowICoat()

        {

            Console.Write("时尚大衣");

        }

    }

3.3 抽象工厂类

  //抽象工厂类

        public interface IFactory

        {

              ICoatCreateCoat();

        }

 

3.4 具体的工厂类

/ 具体工厂类,用于创建时尚上衣

        public ICoat CreateCoat()

        {

            returnnew FashionCoat();

        }

    /// <summary>

        /// 具体工厂类:用于创建商务上衣类

        /// </summary>

        /// <returns></returns>

        public ICoat CreateCoat()

        {

            returnnew BusinessCoat();

        }

 

3.5 调用

    stringfactoryName = ConfigurationManager.AppSettings["FactoryName"];

 

            ViraulFactoryMode.Factory.IFactoryfactory = (ViraulFactoryMode.Factory.IFactory)Assembly.Load("ViraulFactoryMode").CreateInstance("BusinessFactory." + factoryName);

           

            ICoatcoat = factory.CreateCoat();

            //显示你要的上衣

            coat.ShowICoat();

 

            Console.Read();

 

3.6客户端代码需要注意的两个地方:
1
,把具体工厂类类名称写在了应用程序配置文件中,方便修改
2
,用到了反射,利用.NET提供的反射可以根据类名来创建它的实例,非常方便

优点:

· 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象。而且如何创建一个具体产品的细节完全封装在具体工厂内部,符合高内聚,低耦合。 

· 在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,很好的利用了封装和委托。 

缺点: 

· 在添加新产品时,需要编写新的具体产品类(其实这不算一个缺点,因为这是不可避免的),要增加与之对应的具体工厂类。 

 

4 抽象工厂

引入:
在前面介绍的两个创建型模式里面,我们解决的都是有关"new"的问题,用它们来避免显式指定类创建对象。我写的也非常简单易懂,相信看过的朋友们都应该对简单工厂模式工厂方法模式的意图、所能解决的问题及适用情景有一定的了解了。但是若要达到灵活运用,什么时候用,怎样用合适还不是看一篇文章就能解决的问题。呵呵..这需要你对OO的理解程度,你的项目开发经验等等许多方面的积累。一起努力喔。。
好了,咱们言归正传,通过对这两个模式的了解,我们掌握一种思想,就是在创建一个对象时,需要把容易发生变化的地方给封装起来,来控制变化(哪里变化,封 装哪里),以适应客户的变动,项目的扩展。但是,我们在软件系统中,经常面临着一系列相互依赖的对象的创建工作,同时由于需求的变化,这一系列相互 依赖的对象也要改变,如何应对这种变化呢?如何像简单工厂模式工厂方法模式一样绕过常规的"new",然后提供一种封装机制来避免客户程序和这种多系列具体对象创建工作的紧耦合?可能有人会说,你也可以将这些对象一个一个通过工厂方法模式 解决呀?但是,我们试想,既然是一系列相互依赖的对象,它们是有联系的,每个对象都这样解决,你又如何来保证他们的联系呢?举一个例子:Windows 面主题,当你更换一个桌面主题的时候,系统的开始按钮、任务栏、菜单栏、工具栏等等都变了,而且是一起变的,他们的色调都还很一致,难道类似这样的问题, 怎么来解决呢?它的天敌就是抽象工厂模式。

意图:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

参考者:
也就是该模式中的各个类或对象之间的关系:

· 抽象工厂(Abstract Factory)
声明生成一系列抽象产品的方法 

· 具体工厂(Concrete Factory
执行生成一系列抽象产品的方法,生成一系列具体的产品 

· 抽象产品(Abstract Product
为这一系列的某一种产品声明接口 

· 具体产品(Product
定义具体工厂生成的具体产品的对象,实现产品接口 

· 客户(Client
我们的应用程序客户端(不要理解成人),使用抽象产品和抽象工厂生成对象。 

 抽象工厂模式UML

抽象工厂模式在生活中的实例
咱们继续拿怎么穿衣服来说明这个抽象工厂模式。
就拿你来说吧。工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。咱们假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在你的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用OO的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

分析:
要好好去读上面那个实例,虽然有点绕嘴,其实只要用心去读,分清了抽象工厂模式的各个角色,对理解设计模式是非常重要的。理解头绪,然后接合简单工厂模式、工厂方法模式对工厂家族的了解,再加上抽象工厂模式的意图,头脑中差不多有一个雏型了吧。好了,咱们一起来分析一下。。
先把各个角色揪出来。
抽象工厂:虚拟的衣柜,它只是个概念而已。在项目中可能是一个接口或抽象类,定义规则,取出上衣,裤子。
具体工厂:具体的存在的衣柜,它用于存放某一种成套的衣服,换句话说,这种成套的衣服都是从这个衣柜中取出的。在项目中继承于抽象工厂,实现抽象工厂中的方法,取出具体产品,某一件上衣,某一条裤子。
抽象产品:虚拟的衣服,也只是个概念。在项目中可能是多个接口或抽象类,定义规则,有什么特性,起什么作用。
具体产品:具体的实际存在的产品,它指的就是用于组装成某一套衣服的某一件上衣或裤子。它继承自某一个抽象产品。实
              
现抽象产品中制定的规则,特性。
它们之间怎么联系呢?客户在用的时候,依赖的又是什么呢?
客户在要的时候,首先要说出你要的什么系列的衣服,然后根据它的要求生成一个具体工厂的实例,剩下的工作就都是这个倒霉的具体工厂了,它会根据自己的实现 生成一个上衣,生成一个裤子,然后把它交给客户。客户在这一过程中并不知道具体工厂都做了什么。也就是说,客户只依赖于抽象工厂和抽象产品了。在初始化的 时候会用到一次具体工厂类名,我们根据.NET特有的反射机制又可以把这个在客户端唯一的具体的非抽象类放到一个应用程序配置文件中,防止它变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值