• 设计模式之工厂模式


    工厂模式的作用(解决的问题):能轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程。

    简单工厂模式

     组成:
    *1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品。
    *2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
     3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在代码中由一个具体类实现。

    优点:
    隔离了客户和产品具体实现类之间的关系,从而降低了系统间的耦合性。

     缺点:
     对于工厂来说,每增加一种新产品,都要在工厂类中增加相应的创建逻辑(CreateProduct(string _productName)方法中就要增加else if语句),这显然是违背开闭原则的。如果要创建的产品种类很多,这个工厂类将会非常庞大,不利于后期的代码维护。

     1 /// <summary>
     2     /// 产品基类
     3     /// </summary>
     4     public abstract class Product
     5     {
     6     }
     7     /// <summary>
     8     /// 具体产品类1
     9     /// </summary>
    10     public class Product1 : Product
    11     {
    12         public Product1()
    13         {
    14             Console.WriteLine("制造了一个产品1");
    15         }
    16     }
    17     /// <summary>
    18     /// 具体产品类2
    19     /// </summary>
    20     public class Product2 : Product
    21     {
    22         public Product2()
    23         {
    24             Console.WriteLine("制造了一个产品2");
    25         }
    26     }
    27     /// <summary>
    28     /// 工厂类
    29     /// </summary>
    30     public class Factory
    31     {
    32         public Product CreateProduct(string _productName)
    33         {
    34             if (_productName == "Product1")
    35             {
    36                 return new Product1();
    37             }
    38             else if (_productName == "Product2")
    39             {
    40                 return new Product2();
    41             }
    42             return null;
    43         }
    44     }

    工厂方法模式

    组成:
    1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在代码中它由抽象类或者接口来实现。
    2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
    3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在代码中一般有抽象类或者接口来实现。
    4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在代码中由具体的类来实现。

     优点:
     工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的一个工厂类,这样使得结构变得灵活起来,当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的! 
     
     缺点:
     工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但使得对象的数量成倍增长。当产品种类非常多时,
     会出现大量的与之对应的工厂对象,这不是我们所希望的。

     1  /// <summary>
     2     /// 产品基类
     3     /// </summary>
     4     public abstract class Product
     5     {
     6     }
     7     /// <summary>
     8     /// 具体产品类1
     9     /// </summary>
    10     public class Product1 : Product
    11     {
    12         public Product1()
    13         {
    14             Console.WriteLine("制造了一个产品1");
    15         }
    16     }
    17     /// <summary>
    18     /// 具体产品类2
    19     /// </summary>
    20     public class Product2 : Product
    21     {
    22         public Product2()
    23         {
    24             Console.WriteLine("制造了一个产品2");
    25         }
    26     }
    27     /// <summary>
    28     /// 工厂基类
    29     /// </summary>
    30     public abstract class Factory
    31     {
    32         public abstract Product CreateProduct();
    33     }
    34     /// <summary>
    35     /// 产品1工厂实现
    36     /// </summary>
    37     public class FactoryProduct1 : Factory
    38     {
    39         public override Product CreateProduct()
    40         {
    41             return new Product1();
    42         }
    43     }
    44     /// <summary>
    45     /// 产品2工厂实现
    46     /// </summary>
    47     public class FactoryProduct2 : Factory
    48     {
    49         public override Product CreateProduct()
    50         {
    51             return new Product2();
    52         }
    53     }

    抽象工厂模式

    概念:
    抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。比如宝马320系列使用空调型号A和发动机型号A,而宝马230系列使用空调型号B和发动机型号B,那么使用抽象工厂模式,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。

     /// <summary>
        /// A产品基类
        /// </summary>
        public abstract class ProductA
        {
        }
        /// <summary>
        /// B产品基类
        /// </summary>
        public abstract class ProductB
        {
        }
        /// <summary>
        /// 具体A产品类1
        /// </summary>
        public class ProductA1 : ProductA
        {
            public ProductA1()
            {
                Console.WriteLine("制造了一个A产品1");
            }
        }
        /// <summary>
        /// 具体A产品类2
        /// </summary>
        public class ProductA2 : ProductA
        {
            public ProductA2()
            {
                Console.WriteLine("制造了一个A产品2");
            }
        }
        /// <summary>
        /// 具体B产品类1
        /// </summary>
        public class ProductB1 : ProductB
        {
            public ProductB1()
            {
                Console.WriteLine("制造了一个B产品1");
            }
        }
        /// <summary>
        /// 具体B产品类2
        /// </summary>
        public class ProductB2 : ProductB
        {
            public ProductB2()
            {
                Console.WriteLine("制造了一个B产品2");
            }
        }
        /// <summary>
        /// 工厂基类
        /// </summary>
        public abstract class Factory
        {
            public abstract ProductA CreateProductA();
            public abstract ProductB CreateProductB();
        }
        /// <summary>
        /// 产品1工厂实现(产品1由A产品1和B产品1组合而成)
        /// </summary>
        public class FactoryProduct1 : Factory
        {
            public override ProductA CreateProductA()
            {
                return new ProductA1();
            }
    
            public override ProductB CreateProductB()
            {
                return new ProductB1();
            }
        }
        /// <summary>
        /// 产品2工厂实现(产品2由A产品2和B产品2组合而成)
        /// </summary>
        public class FactoryProduct2 : Factory
        {
            public override ProductA CreateProductA()
            {
                return new ProductA2();
            }
    
            public override ProductB CreateProductB()
            {
                return new ProductB2();
            }
        }

    不管是哪种工厂模式,起到的效果都是一样,够用就行,不必强求。

  • 相关阅读:
    js 中for forEach map some every的区别
    2019.3.27面试
    js中的继承
    关于iPhone手机上的浏览器、微信内置浏览器不识别yyyy-mm-dd格式的时间显示为NaN问题
    一个有关ajax去获取天气预报然后用echarts展现出来的小demo
    js中var和let的快速区别
    配置服务器-------------适合小白和从未接触过服务器的人阅读
    .net core 响应的json数据驼峰显示问题。
    asp .net core中swagger的简单使用
    关于修改.net core webapi中null默认返回的状态码。
  • 原文地址:https://www.cnblogs.com/xiaoyulong/p/9425400.html
Copyright © 2020-2023  润新知