设计模式面对面之工厂模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式面对面之工厂模式相关的知识,希望对你有一定的参考价值。

简单工厂模式

类图:

技术分享

技术分享

常用的实现方式:

产品

技术分享
public abstract class Product
    {
        protected Product(){

        }

        public virtual void Operation(){
            Console.WriteLine("我是工厂生产所有产品");
        }

    }//end Product
View Code
技术分享
public class Care : Product
    {

        public Care(){

        }

        public override void Operation(){
            Console.WriteLine("我生产车!");
        }

    }//end Care
View Code
技术分享
public class Apple : Product {

        public Apple(){

        }

        public override void Operation(){
            Console.WriteLine("我产生苹果");
        }

    }//end Apple
View Code

工厂

技术分享
public class ProductFactory {

        public ProductFactory(){

        }

        /// 
        /// <param name="productName"></param>
        public Product Made(string productName)
        {
            Product product;
            switch (productName)
            {
                case nameof(Apple):
                {
                        product= new Apple();
                    break;
                }
                case nameof(Care):
                {
                    product = new Care();
                    break;
                }
                default:
                {
                    product=new Apple();
                    break;
                }

            }
            return product;
        }

    }//end ProductFactory
View Code

 调用

技术分享
class Program
    {
        static void Main(string[] args)
        {
          
            var factory = new ProductFactory();
            var car = factory.Made(nameof(Care));
            car.Operation();
            var apple = factory.Made(nameof(Apple));
            apple.Operation();

            Console.ReadLine();
        }
    }
View Code

 

使用场景:

简单工厂模式产品工厂提供了一个制造产品万能的类,需要什么产品只要修改made()方法就可以了,很方便。

它是直接new xx()对象的升级版,追求简洁方便开发效率可以考虑使用,或者直接new xx()。

设计原则:

优点

1.遵守了依赖倒置原则---使对象的创建延迟到了之类,不依赖具体产品,只依赖抽象产品

2.遵守了接口隔离原则---产品与产品之间隔离

3.遵守了里氏替换原则--子类实现父类所有方法

缺点

1.违背了对象开-闭原则---工厂对象是一个万能的类,每次扩展新的产品都要维护一次

2.违背了单一职责原则--工厂对象是一个万能的类

3.违背了迪米特法则--工厂对象知道了太多产品对象

 

抽象工厂方法模式

类图:

 技术分享

技术分享

常用的实现方式:

 产品

技术分享
public abstract class ProductAbstract {
        protected ProductAbstract(){

        }

        public abstract void Operation();

    }//end ProductAbstractA
View Code
技术分享
public class ProductAbstractAGeneralized : ProductAbstract {

        public ProductAbstractAGeneralized(){

        }

        public override void Operation(){
            Console.WriteLine("生产ProductAbstractA");
        }

    }//end ProductAbstractAGeneralized
View Code
技术分享
public class ProductAbstractBGeneralized : ProductAbstract {

        public ProductAbstractBGeneralized(){

        }

        public override void Operation(){
            Console.WriteLine("生产ProductAbstractB");
        }

    }//end ProductAbstractBGeneralized
View Code

工厂

技术分享
public abstract class FactoryAbstract {
        protected FactoryAbstract(){

        }

        public abstract ProductAbstract Made();

    }//end FactoryAbstractA
View Code
技术分享
public class FactoryAbstractAGeneralized : FactoryAbstract {

        private readonly ProductAbstract _productAbstractA;

        public FactoryAbstractAGeneralized(){
            _productAbstractA=new ProductAbstractAGeneralized();
        }

        public override ProductAbstract Made(){

            return _productAbstractA;
        }

    }//end FactoryAbstractAGeneralized
View Code
技术分享
public class FactoryAbstractBGeneralized : FactoryAbstract {

        private readonly ProductAbstract _productAbstractB;

        public FactoryAbstractBGeneralized(){
            _productAbstractB=new ProductAbstractBGeneralized();
        }

        public override ProductAbstract Made(){

            return _productAbstractB;
        }

    }//end FactoryAbstractBGeneralized
View Code

 调用

技术分享
 static void Main(string[] args)
        {

            var factoryA = new FactoryAbstractAGeneralized();

            var productA = factoryA.Made();
            productA.Operation();

            var factoryB = new FactoryAbstractBGeneralized();
            var productB = factoryB.Made();
            productB.Operation();

            Console.ReadLine();

        }
View Code

 

使用场景:

 工厂方法模式是简单工厂模式的升级版,目的是改善简单工厂所违背的设计原则,使其更加完美,主要意图是解耦产品的创建。

它对产品工厂进行了抽象,使不同的产品工厂制造不同的产品,方便以后新产品的扩展,新产品只要泛化一个新工厂就可以了。

设计原则:

优点

1.遵守了依赖倒置原则---使对象的创建延迟到了之类,不依赖具体产品,只依赖抽象产品

2.遵守了接口隔离原则---产品与产品之间隔离

3.遵守了里氏替换原则--子类实现父类所有方法

4遵守了对象开-闭原则---产品的创建只要泛化工厂就可以了,扩展好

5.遵守了单一职责原则--一个工厂一个产品,修改工厂逻辑不影响其它工厂

6.遵守了迪米特法则--工厂只知道所要创建的产品,其它产品信息不知道,知道的非常少。

缺点

1.很明显,产品一多,工厂跟着多,后期不好维护,所以有了抽象工厂模式。

 

抽象工厂模式

类图:

 技术分享

技术分享

常用的实现方式:

 产品

技术分享
public abstract class ProductAbstractA {

        protected ProductAbstractA(){

        }

        public abstract void Operation();

    }//end ProductAbstractA
View Code
技术分享
public class ProductAbstractAGeneralized1 : ProductAbstractA {

        public ProductAbstractAGeneralized1(){

        }

        public override void Operation(){
            Console.WriteLine("生产组1:ProductAbstractAGeneralized1");
        }

    }//end ProductAbstractAGeneralized1
View Code
技术分享
public abstract class ProductAbstractB {

        protected ProductAbstractB(){

        }

        public abstract void Operation();

    }//end ProductAbstractB
View Code
技术分享
public class ProductAbstractBGeneralized1 : ProductAbstractB {

        public ProductAbstractBGeneralized1(){

        }

        public override void Operation(){
            Console.WriteLine("生产组1:ProductAbstractBGeneralized1");
        }

    }//end ProductAbstractBGeneralized1
View Code

工厂

技术分享
 public abstract class FactoryAbstract
    {

        protected FactoryAbstract()
        {

        }

        public abstract ProductAbstractA MadeProductA();

        public abstract ProductAbstractB MadeProductB();
    }
View Code
技术分享
public class FactoryAbstractGroup1Generalized : FactoryAbstract {

        public FactoryAbstractGroup1Generalized(){

        }

        public override ProductAbstractA MadeProductA(){

            return new ProductAbstractAGeneralized1();
        }

        public override ProductAbstractB MadeProductB(){

            return new ProductAbstractBGeneralized1();
        }

    }//end FactoryAbstractAGeneralized
View Code

调用

技术分享
 static void Main(string[] args)
        {
            

            var productGroup= new FactoryAbstractGroup1Generalized();

            var groupProduct1 = productGroup.MadeProductA();
            groupProduct1.Operation();

            var groupProduct2 = productGroup.MadeProductB();
            groupProduct2.Operation();

            Console.ReadLine();


        }
View Code

 使用场景:

 抽象工厂模式是抽象工厂方法模式的升级版,唯一的区别是泛化的工厂少了,维护的工厂对象少了,使工厂模式更加完美了。

抽象工厂会针对一组有关联或者相互依赖的产品做抽象,所以泛化的工厂会创建一组产品而不是一个产品。

所谓的关联指的是创建产品的方式关联或者产品间的直接关联(依赖),可以按照这些关联将它们归为一组产品去维护。比如生产床头柜和床,生产的时候床头柜和床都要遵守高低尺寸和风格搭配这些约束,此时我们可以将床头柜和床抽象成一个组产品去维护。

所谓的相互依赖指的是不同产品间是依赖关系,比如手机和电池,二者相互依赖,分离了就没意义了,生产的时候需要抽象为一组产品去维护。

优点

1.遵守了依赖倒置原则---使对象的创建延迟到了之类,不依赖具体产品,只依赖抽象产品

2.遵守了接口隔离原则---产品与产品之间隔离

3.遵守了里氏替换原则--子类实现父类所有方法

4遵守了对象开-闭原则---产品的创建只要泛化工厂就可以了,扩展好

5.遵守了单一职责原则--一个工厂一个产品,修改工厂逻辑不影响其它工厂

6.遵守了迪米特法则--工厂只知道所要创建的产品,其它产品信息不知道,知道的非常少。

7.减少了工厂对象维护量

缺点

1.很明显,需要根据自己的理解去合理的抽象,抽象错了反而适得其反,增加了对象创建的复杂度。

 

三种工厂模式各有优缺点,使用的时候需要根据场景去判断,选择最优方式。

 

以上是关于设计模式面对面之工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

23种设计模式之简单工厂模式

PHP面向对象之选择工厂和更新工厂

C#设计模式之三抽象工厂模式(AbstractFactory)创建型

设计模式之单例模式

《设计模式》之抽象工厂模式(Abstract Factory)

设计模式面对面