23种设计模型:Abstract Factory(抽象工厂) —— 对象创建型模式

创建型模式抽象了对象的创建(实例化)过程。类创建型模式使用继承改变被实例的类, 对象创建型模式将对象的创建的工作延迟到另一个对象中。通过对象创建模式绕开new,避免对象创建过程(new)的中紧耦合。

一、意图

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

二、动机

在软件系统中,经常面临着一系列互相依赖的对象的创建工作。同时,由于需求的变化,往往存在更多系列对象的创建工作。

三、适用性

  • 一个系统要独立于它的产品的创建,组合和表示时。

  • 一个系统要由多个产品系列中的一个来配置时。

  • 当强调一系列相关产品对象的设计以便进行联合使用时。

  • 当你提供一个产品类库,而只想显示它们的接口而不是实现时。

四、效果

  • (优点)分离了具体类(通过抽象类)。
  • (优点)易于改变产品系列
  • (优点)有利于产品的一致性(当一个系列的产品对象被设计成一起工作时,客户程序一次只能使用同一个系列中的对象)。
  • (缺点)难以支持新种类的产品。

五、代码示例

想象一个场景,一个工厂专门生产小米手机、小米移动电源、小米数据线。客户程序我们可能写成如下。

using System;

namespace AbstractFactory
{
    class Client
    {
        static void Main(string[] args)
        {
            MakeLine makeLine = new MakeLine();//依赖具体类MakeLine
            Console.WriteLine(makeLine.print());

            MakePhone makePhone = new MakePhone();//依赖具体类MakePhone 
            Console.WriteLine(makePhone.print());

            MakePower makePower = new MakePower();//依赖具体类MakePower 
            Console.WriteLine(makePower.print());

            Console.ReadLine();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace AbstractFactory
{
    class MakePhone
    {
        public string print()
        {
            return "生产小米手机";
        }
    }

    class MakePower
    {
        public string print()
        {
            return "生产小米电源";
        }
    }

    class MakeLine
    {
        public string print()
        {
            return "生产小米数据线";
        }
    }
}

如果我们现在想增加生产华为的手机、移动电源、数据线怎么办?首先我们增加三个类分别生产华为的手机、电源、数据线。然后客户端也要进行进行修改,增加实例化华为三个类的实例化。这就违背了之前的依赖倒置设计原则:高层模块不应该依赖底层模块,二者都应该依赖于抽象

改良后:

using System;

namespace AbstractFactoryImprove
{
    class Client
    {
        static void Main(string[] args)
        {
            IFactory factory = new FactoryA();//依赖抽象
            Console.WriteLine(factory.makePhone().Print());
            Console.WriteLine(factory.makePower().Print());
            Console.WriteLine(factory.makeLine().Print());
            Console.ReadLine();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace AbstractFactoryImprove
{
    abstract class IFactory
    {
        public abstract IMakePhone makePhone();
        public abstract IMakePower makePower();
        public abstract IMakeLine makeLine();
    }

    abstract class IMakePhone
    {
        abstract public string Print();
    }

    abstract class IMakePower
    {
        abstract public string Print();
    }

    abstract class IMakeLine
    {
        abstract public string Print();
    }

    class FactoryA_MakePhone : IMakePhone
    {
        public override string Print()
        {
            return "生产小米手机";
        }
    }

    class FactoryA_MakePower : IMakePower
    {
        public override string Print()
        {
            return "生产小米电源";
        }
    }

    class FactoryA_MakeLine : IMakeLine
    {
        public override string Print()
        {
            return "生产小米数据线";
        }
    }

    class FactoryA : IFactory
    {
        public override IMakeLine makeLine()
        {
            return new FactoryA_MakeLine();
        }

        public override IMakePhone makePhone()
        {
            return new FactoryA_MakePhone();
        }

        public override IMakePower makePower()
        {
            return new FactoryA_MakePower();
        }
    }
}

修改之后我们想增加华为的生产线,我们只需在底层增加四个类FactoryB、FactoryB_MakeLine、FactoryB_MakePower、FactoryB_MakePhone,客户端不需要改变,只需要传给它FactoryB的实例就可以,因为依赖的是抽象类(运行时依赖),在运行时你给我什么,我用什么,而没改良之前的代码,运行时是不能改变的。

我们再来看上面说的抽象工厂的缺点:难以支持新种类的产品。假如现在我们想生产手机壳,那么我就需要改变IFactory和所有继承它的子类,这种情况就不适合抽象工厂了。

“一系列”怎么理解呢,小米手机、小米电源、小米线是一个牌子的,有关联。

 

(学习笔记,仅供参考。走火入魔,概不负责。如有错误,谢谢指出。^_^)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值