工厂方法(Factory Method)模式

引言(Introduction)

上一篇博客以手机工厂为例介绍了简单工厂模式,将创造OPPO手机和OPPO手机对象的逻辑都放在了内部PhoneFactory里面,并且分别创建了两个具体手机产品类OPPOPhone,OPPOPhone,具体Create哪类手机,就要看传入的参数了。这时,如果该手机工厂想要扩大生产规模,加入小米手机的生产,我们需要变动2个地方:增加一个XiaoMiPhone的具体产品类;修改工厂的内部逻辑,增加一个XiaoMiPhone的分支判断;这样不仅对于扩展开放了,而且对修改也开放了(修改了工厂类),这就违背了开闭原则。解决这个问题,就需要用到工厂方法(Factory Method)模式了。

意图(Intention)

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。

结构(struct)

角色(Roles)

抽象工厂(Creator):工厂方法的核心,任何在模式中创建的对象的工厂类必须实现这个接口。

具体工厂(Concrete Creator):实现抽象工厂接口的具体工厂类。

抽象产品(Producr):工厂方法所创建的对象的父类(或者说这些产品共同拥有的接口)。

具体产品(ConcreteProduct):由其对应的具体工厂创建,是抽象产品的子类(或者说实现了抽象产品的接口)

举例(Example)

创建一个工厂接口

    interface IFactory
    {
        Phone CreatePhone();
    }

三个牌的手机各建一个具体工厂去实现这个接口

    class HuaWeiFactory : IFactory
    {
        public Phone CreatePhone()
        {
            return new HuaweiPhone();
        }
    }
    class OPPOFactory : IFactory
    {
        public Phone CreatePhone()
        {
            return new OPPOPhone();
        }
    }
    class XiaoMiFactory : IFactory
    {
        public Phone CreatePhone()
        {
            return new XiaoMiPhone();
        }
    }

抽象产品类:手机类

    public  class Phone
    {
        public virtual void Start(){}
    }

具体产品类:HuaweiPhone,OPPOPhone,XiaoMiPhone,是Phone类的子类

    class HuaweiPhone:Phone
    {
        public override void Start()
        {
            Console.WriteLine("华为手机开机了");
        }
    }

    class OPPOPhone : Phone
    {
        public override void Start()
        {
            Console.WriteLine("OPPO手机开机了");
        }
    }

    class XiaoMiPhone : Phone
    {
        public override void Start()
        {
            Console.WriteLine("小米手机开机了");
        }
    }

客户端代码的实现

            IFactory phoneFactory = new HuaWeiFactory();
            Phone phone = phoneFactory.CreatePhone();
            phone.Start();

运行结果

与简单工厂相比,用抽象工厂模式,我们想要增加一个小米手机,只需要增加一个小米手机类和一个小米手机的具体工厂类就可以了,不需要修改原有的工厂类了。这样就只有扩展的变化,而没有修改的变化,就完全符合了开-闭原则。工厂方法模式在实现时,由客户端代码决定实例化哪一个工厂来实现创建哪一个品牌的手机,也存在判断,工厂方法将简单工厂内部逻辑判断移到了客户端代码来进行,不需要再改工厂类,只需要修改客户端就可以了。

如有错误的地方,欢迎大家指正~~~~

发布了75 篇原创文章 · 获赞 24 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/wtt15100/article/details/105081368