美文网首页设计模式 C#程序员
创建相似对象,就交给『工厂模式』吧

创建相似对象,就交给『工厂模式』吧

作者: 圣杰 | 来源:发表于2016-11-30 09:41 被阅读561次

    目录:设计模式之小试牛刀
    源码路径:Github-Design Pattern


    定义(Factory Pattern):

    用来创建目标对象的类,将相似对象的创建工作统一到一个类来完成。

    一、简单工厂模式:

    代码:

        /// <summary>
        /// 产品枚举
        /// </summary>
        public enum ProductEnum
        {
            ConcreateProductA,
            ConcreateProductB
        }
    
        /// <summary>
        /// 简单工厂模式:
        /// 简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
        /// 不修改代码的话,是无法扩展的。(如果增加新的产品,需要增加工厂的Swith分支)
        /// 不符合【开放封闭原则】
        /// </summary>
        public static class SimpleFactory
        {
            public static AbstractCar Create(ProductEnum productType)
            {
                switch (productType)
                {
                    case ProductEnum.ConcreateProductA:
                        return new ConcreateCarA();
                    case ProductEnum.ConcreateProductB:
                        return new ConcreateCarB();
                    default:
                        return null;
                }
            }
        }
    
            /// <summary>
            /// 测试简单工厂模式
            /// </summary>
            private static void TestSimpleFactory()
            {
                Console.WriteLine("简单工厂模式:");
                var productA = SimpleFactory.Create(ProductEnum.ConcreateProductA);
                productA.GetInfo();
                Console.ReadLine();
            }
    
    简单工厂模式运行结果

    优缺点:

    工厂类包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类。对于客户端来说,去除了对具体产品的依赖。
    不符合【OCP】。

    应用场景:

    当工厂类负责创建的对象比较少时可以考虑使用简单工厂模式。


    二、反射工厂模式(基于简单工厂模式的拓展)

    通过反射,以完成工厂对对象的创建。可以最大限度的解耦。

    代码:

        /// <summary>
        /// 反射工厂模式
        /// 是针对简单工厂模式的一种改进
        /// </summary>
        public static class ReflectFactory
        {
            public static AbstractCar Create(string typeName)
            {
                Type type = Type.GetType(typeName, true, true);
                var instance = type?.Assembly.CreateInstance(typeName) as AbstractCar;
    
                return instance;
            }
        }
    
            /// <summary>
            /// 测试反射工厂模式
            /// </summary>
            private static void TestReflectFactory()
            {
                Console.WriteLine("反射工厂模式:");
                var productB = ReflectFactory.Create("FactoryPattern.ConcreateCarB");
    
                productB.GetInfo();
                Console.ReadLine();
            }
    
    反射工厂模式运行结果

    PS:反射工厂模式可以和配置文件配合使用,效果更佳


    三、工厂方法模式

    定义:

    定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法将类的实例化延长到子类。

    类图:

    工厂方法模式类图

    启示:

    工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品。

    代码:

        /// <summary>
        /// 工厂方法模式:
        /// 工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
        /// 在同一等级结构中,支持增加任意产品。
        /// 符合【开放封闭原则】,但随着产品类的增加,对应的工厂也会随之增多
        /// </summary>
        public interface IFactoryMethod
        {
            AbstractCar Create();
        }
    
        public class ConcreateFactoryA:IFactoryMethod
        {
            public AbstractCar Create()
            {
                return new ConcreateCarA();
            }
        }
    
        public class ConcreateFactoryB : IFactoryMethod
        {
            public AbstractCar Create()
            {
                return new ConcreateCarB();
            }
        }
    
            /// <summary>
            /// 测试工厂方法模式
            /// </summary>
            private static void TestFactoryMethod()
            {
                Console.WriteLine("工厂方法模式:");
                IFactoryMethod factoryB =new ConcreateFactoryB();
                var productB = factoryB.Create();
                productB.GetInfo();
    
                Console.ReadLine();
            }
    
    工厂方法模式运行结果

    优缺点:

    符合【OCP】,但随着产品类的增加,对应的工厂类也会随之增多。
    工厂方法模式实现时,客户端需要决定实例化哪个工厂来创建对象。工厂方法把简单工厂的内部创建对象的逻辑判断移到了客户端。如果需要修改,只需要修改客户端即可!

    应用场景:

    单一产品的创建。


    三、抽象工厂模式

    定义:

    为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。

    类图:

    抽象工厂模式类图

    启示:

    抽象工厂是应对产品族概念的,比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。

    代码:

        /// <summary>
        /// 抽象工厂模式:
        /// 抽象工厂是应对产品族概念的,比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。
        /// 应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。
        /// </summary>
        public interface IAbstractFactory
        {
            AbstractCar CreateCar();
            AbstractBus CreateBus();
        }
    
        /// <summary>
        /// 宝马工厂
        /// </summary>
        public class BMWFactory:IAbstractFactory
        {
            public AbstractCar CreateCar()
            {
                return new ConcreateCarA();
            }
    
            public AbstractBus CreateBus()
            {
                return new ConcreateBusA();
            }
        }
    
        /// <summary>
        /// 比亚迪工厂
        /// </summary>
        public class BYDFactory : IAbstractFactory
        {
            public AbstractCar CreateCar()
            {
                return new ConcreateCarB();
            }
    
            public AbstractBus CreateBus()
            {
                return new ConcreateBusB();
            }
        }
    
    
            /// <summary>
            /// 测试抽象工厂模式
            /// </summary>
            private static void TestAbstractFactory()
            {
                Console.WriteLine("抽象工厂模式:");
    
                var bmwFactory = new BMWFactory();
                bmwFactory.CreateCar().GetInfo();
                bmwFactory.CreateBus().GetInfo();
    
                var bydFactory = new BYDFactory();
                bydFactory.CreateCar().GetInfo();
                bydFactory.CreateBus().GetInfo();
    
                Console.ReadLine();
            }
    
    抽象工厂模式运行结果

    优缺点:

    应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。

    应用场景:

    一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
    这个系统有多个系列产品,而系统中只消费其中某一系列产品
    系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。


    总结:

    简单工厂:简单实用,但违反开放封闭;
    工厂方法:开放封闭,单一产品;
    抽象工厂:开放封闭,多个产品;
    反射工厂:可以最大限度的解耦。

    相关文章

      网友评论

        本文标题:创建相似对象,就交给『工厂模式』吧

        本文链接:https://www.haomeiwen.com/subject/spnzpttx.html