C#设计模式之【创建型设计模式:工厂模式】

一. 简单工厂(非设计模式)

  首先,严格上来说,简单工厂并非23种设计模式之一,但是还是有必要介绍一下,
  现实中的工厂负责生产产品,编程中的简单工厂就是一个生产对象的类,它的主要功能就是负责创建类的实例。我们以一个生产汽车为例来分析简单工厂的作用:

注意:例子中的抽象类都可以用接口代替

代码如下:

   /// <summary>
   /// 汽车抽象类
   /// </summary>
   public abstract class  Car
    {
      public abstract void CreateCar();
    }

    /// <summary>
    /// 奥迪
    /// </summary>
    public class Audi : Car
    {
        public override void CreateCar()
        {
            Console.WriteLine("制造奥迪车");
        }
    }
    /// <summary>
    /// 宝马
    /// </summary>
    public class BMW : Car
    {
        public override void CreateCar()
        {
            Console.WriteLine("制造宝马车");
        }
    }

控制台代码:

   Car car1 = new Audi(); //创建奥迪对象                  
   Car car2 = new BMW(); //创建宝马对象
   car1.CreateCar();
   car2.CreateCar();
   Console.Read();

输出结果:
在这里插入图片描述
  这么一看,每次想要创建奥迪对象的时候,就去new Audi();想要创建宝马对象的时候,就 new BMW();嗯,挺好,没什么大问题。但是,当项目做大了以后,假设我有500个地方new BMW()。突然!由于项目需求的变更,宝马需要全部换成奥迪,这就难受了,得去找到500个创建宝马的地方修改代码。。。岂不是头皮发麻?
  所以我们需要创建一个类来帮助我们创建对象,我们可以这么搞:

    /// <summary>
    /// 简单工厂:创建对象的地方
    /// </summary>
    public class CarFactory
    {
        private Car car = null;
        public  Car CreateCarType(string carType)
        {
            switch (carType)
            {
                case "Audi":
                    car = new Audi();
                    break;
                case "BMW":
                    car = new BMW();
                    break;              
            }
            return car;
        }
    }

然后在控制台的代码可以改成以下代码:

   Car car1 = new CarFactory().CreateCarType("Audi"); //通过简单工厂类获取奥迪对象                         
   Car car2 = new CarFactory().CreateCarType("BMW"); //通过简单工厂类获取宝马对象
   car1.CreateCar();
   car2.CreateCar();
   Console.Read();

UML图如下:
在这里插入图片描述

  最终输出结果是一样的,如果需要把宝马改成奥迪,那简单,修改CarFactory类中的代码即可,这样一来,是不是轻松多了。或者把工厂类中carType变量抽到配置文档中,由配置文档配置,就可以实现不修改代码的请况下随意配置奥迪或者宝马。

 public class CarFactory
    {
        private Car car = null;
        //可以从配置文档配置:carType,更换实例对象
        private static readonly string carType = ConfigurationManager.AppSettings["carType"];
        public Car CreateCarType()
        {
            switch (carType)
            {
                case "Audi":
                    car = new Audi();
                    break;
                case "BMW":
                    car = new BMW();
                    break;              
            }
            return car;
        }
    }

  但是,这样设计虽然降低了对象之间的耦合,却违背了软件设计的开闭原则:比如说,现在要添加一个奔驰的实现类,那么就必须在工厂类中添加一个case 条件来生成奔驰的实例,要怎么搞??

二. 工厂方法

屏蔽对象创建,留下扩展空间,完美遵循开闭原则。

  为了解决简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法的缺点,出现了工厂方法模式。

    /// <summary>
    /// 抽象工厂类
    /// </summary>
   public abstract class AbstractFactory
    {
        public abstract Car CreateCarType();
    }
    
    /// <summary>
    /// 奥迪工厂类
    /// </summary>
    public class AudiFactory : AbstractFactory
    {
        public override Car CreateCarType()
        {
            return new Audi();
        }
    }
    
    /// <summary>
    /// 宝马工厂类
    /// </summary>
    public class BMWFactory : AbstractFactory
    {
        public override Car CreateCarType()
        {
            return new BMW();
        }
    }

  控制台代码:

	
     AbstractFactory audiFactory = new AudiFactory();
     AbstractFactory bmwFactory = new BMWFactory();

     Car car1 =  audiFactory.CreateCarType(); //通过工厂方法获取奥迪对象                         
     Car car2 =  bmwFactory.CreateCarType(); //通过工厂方法获取宝马对象

     car1.CreateCar();
     car2.CreateCar();
     Console.Read();	      

  使用工厂方法实现的系统,如果系统需要添加新产品时,我们可以利用多态性来完成系统的扩展,对于抽象工厂类和具体工厂中的代码都不需要做任何改动。
  例如:如果要添加一个奔驰类,那么只需要再写一个奔驰工厂类,实现抽象工厂的方法即可返回奔驰类的对象实例,控制台就可以调用奔驰工厂类的方法获取对象实例了。

  UML图:
在这里插入图片描述

三. 抽象工厂

  屏蔽对象创建,约束强制保障产品簇
  但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题,
  例如,在上面的例子中,我们要求形成一个交通工具产品簇的企业工厂,包括汽车、自行车、摩托车。缺一不可,怎么做呢?

  首先,我们先把其他交通工具的类写了,

   /// <summary>
    /// 自行车抽象类
    /// </summary>
    public abstract class Bicycle
    {
        public abstract void CreateBicycle();
    }

    /// <summary>
    ///奥迪
    /// </summary>
    public class AudiBicycle : Bicycle
    {
        public override void CreateBicycle()
        {
            Console.WriteLine("制造奥迪自行车");
        }
    }
    /// <summary>
    /// 宝马
    /// </summary>
    public class BMWBicycle : Bicycle
    {
        public override void CreateBicycle()
        {
            Console.WriteLine("制造宝马自行车");
        }
    }
    /// <summary>
    /// 摩托车抽象类
    /// </summary>
    public abstract class Motorbike
    {
        public abstract void CreateMotorbike();
    }

    /// <summary>
    /// 奥迪
    /// </summary>
    public class AudiMotorbike : Motorbike
    {
        public override void CreateMotorbike()
        {
            Console.WriteLine("制造奥迪摩托车");
        }
    }
    /// <summary>
    /// 宝马
    /// </summary>
    public class BMWMotorbike : Motorbike
    {
        public override void CreateMotorbike()
        {
            Console.WriteLine("制造宝马摩托车");
        }
    }

  然后,开始创建抽象工厂,强制约束,保障产品簇

    /// <summary>
    /// 抽象工厂:要求必须有汽车、自行车、摩托车,形成交通工具产品簇
    /// </summary>
   public abstract class AbstractFactory
    {

        public abstract  Car CreateCarType();
        public abstract Bicycle CreateBicycleType();
        public abstract Motorbike CreateMotorbikeType();

    }

  那么,宝马工厂和奥迪工厂继承了以上的抽象工厂,就必须生产要汽车、摩托车、自行车的完整产品簇

    /// <summary>
    /// 奥迪交通工具产品簇
    /// </summary>
    public class AudiFactory : AbstractFactory
    {
        public override Bicycle CreateBicycleType()
        {
            return new AudiBicycle();
        }

        public override Car CreateCarType()
        {
            return new Audi();
        }

        public override Motorbike CreateMotorbikeType()
        {
            return new AudiMotorbike();
        }
    }
    /// <summary>
    /// 宝马交通工具产品簇
    /// </summary>
    public class BMWFactory : AbstractFactory
    {
       
        public override Bicycle CreateBicycleType()
        {
            return new BMWBicycle();
        }

        public override Car CreateCarType()
        {
            return new BMW();
        }

        public override Motorbike CreateMotorbikeType()
        {
            return new BMWMotorbike();
        }
    }

  这样一来,就能够通过AudiFactory 或者BMWFactory 获取他们的 汽车、自行车、摩托车的对象实例。

  UML图如下:
在这里插入图片描述

四. 三种工厂模式的使用选择

  简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)

  工厂方法 : 用来生产同一等级结构中的固定产品。(支持拓展增加产品)

  抽象工厂 : 用来生产不同产品族的全部产品。(支持拓展增加产品;支持增加产品族)

  写到这里,一定有小伙子开始郁闷了!这不是脱裤子放屁?感觉有时候还不如直接new一个对象,怎么说呢?如果项目做大,如果创建对象的时候需要做一些处理,那就可以考虑使用工厂模式了。 使用工厂可以增加一些逻辑(例如IOC)屏蔽对象实例化的复杂度。

  还是那句话:没有最好的设计模式,只有最合适的设计模式!
  
  
  

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值