抽象工厂模式是所有工厂模式中最为抽象的模式,是抽象程度最高的模式,也是最难理解的一种工厂模式。

        现在举一个生活中的案例来说明抽象工厂模式,电视是我们生活中必不可说的电器,但是电视有很多厂家,海尔工厂,海信工厂,美的工厂他们都生产自己的电视(海尔电视,海信电视,美的电视)。再有冰箱,这三个厂家又可以生产自己的冰箱(海尔冰箱,海信冰箱,美的冰箱)。等等......在抽象工厂模式中,海尔电视,海尔冰箱,海尔空调等组成的就是一个产品族。海尔电视,海信电视,美的电视等都是电视。所以他们可以抽象出一个共同的父类:电视类。在这里,抽象电视类和它的三个子类就构成了一个产品等级结构,同理抽象冰箱类和它的三个子类构成了另外一个产品等级结构。同时海尔工厂,海信工厂,美的工厂也可以抽象出一个共同的父类:工厂。

        所以在抽象工厂模式中,包含以下四种角色:

        (1)抽象工厂(抽象工厂类):它是所有具体工厂的父类,声明了创建一个产品族的方法,并由其子类去实现。抽象工厂可以声明成接口。

        (2)具体工厂(海尔工厂,海信工厂,美的工厂):它们实现了抽象工厂中声明的方法,生产出一个产品族(比如:海尔电视,海尔冰箱,海尔空调等一系列海尔产品)。

        (3)抽象产品:(如抽象电视类)它是所有具体产品的父类。声明所有具体产品的公共方法。抽象产品声明成接口。

        (4)具体产品(海尔电视,海信电视,美的电视):它们实现了抽象父类中声明的方法。也是客户端最终想要的产品。

         下面来看看抽象工厂的类图吧:

        总之一点,在抽象工厂模式中,客户端必须针对接口编程,绝对不能针对具体的实现类编程。否则无法保证程序的扩展性和灵活性。不仅仅抽象工厂,在其他的工厂模式中也都是针对接口(抽象)编程!

        接下来来看看具体的实现代码吧。

        首先是抽象产品(抽象电视,抽象冰箱)的代码:

namespace 抽象工厂模式
{
    interface AbstractTV//所有电视的父类
    {
        void DisPlay();//显示电视类型
    }
}
namespace 抽象工厂模式
{
    interface AbstractBX//所有冰箱的父类
    {
        void Display();//显示冰箱类型
    }
}
        接下来是所有的具体产品的代码(海尔电视,海信电视,美的电视和海尔冰箱,海信冰箱,美的冰箱)

namespace 抽象工厂模式
{
    class HaiErTV:AbstractTV//海尔电视
    {
        public void DisPlay()
        {
            Console.WriteLine("我是海尔电视!");
        }
    }
}
namespace 抽象工厂模式
{
    class HaiXinTV:AbstractTV//海信电视
    {
        public void DisPlay()
        {
            Console.WriteLine("我是海信电视!");
        }
    }
}
namespace 抽象工厂模式
{
    class MeiDiTV:AbstractTV//美的电视
    {
        public void DisPlay()
        {
            Console.WriteLine("我是美的电视!");
        }
    }
}

namespace 抽象工厂模式
{
    class HaiErBX:AbstractBX//海尔冰箱
    {
        public void Display()
        {
            Console.WriteLine("我是海尔冰箱!");
        }
    }
}
namespace 抽象工厂模式
{
    class HaiXinBX:AbstractBX//海信冰箱
    {
        public void Display()
        {
            Console.WriteLine("我是海信冰箱!");
        }
    }
}
namespace 抽象工厂模式
{
    class MeiDiBX:AbstractBX//美的冰箱
    {
        public void Display()
        {
            Console.WriteLine("我是美的冰箱!");
        }
    }
}
        抽象工厂的代码如下:
namespace 抽象工厂模式
{
    interface AbstractFactory//所有工厂的父类
    {
        AbstractBX CreateBX();//创建冰箱
        AbstractTV CreateTV();//穿件电视
    }
}
        最后是具体工厂的(海尔工厂,海信工厂)的代码

namespace 抽象工厂模式
{
    class HaiErFactory:AbstractFactory//海尔工厂
    {
        public AbstractBX CreateBX()//创建海尔冰箱
        {
            return new HaiErBX();
        }

        public AbstractTV CreateTV()//创建海尔电视
        {
            return new HaiErTV();
        }
    }
}
namespace 抽象工厂模式
{
    class HaiXinFactory:AbstractFactory//海信工厂
    {
        public AbstractBX CreateBX()//创建海信冰箱
        {
            return new HaiXinBX();
        }

        public AbstractTV CreateTV()//创建海信电视
        {
            return new HaiXinTV();
        }
    }
}
        还有客户端的代码:
namespace 抽象工厂模式
{
    class Program
    {
        static void Main(string[] args)
        {
            AbstractBX bx;
            //从配置文件中获取工厂名
            string factoryName = ConfigurationManager.AppSettings["factory"];
            //通过反射动态加载程序集,创建工厂实例
            AbstractFactory factory = (AbstractFactory)Assembly.Load("抽象工厂模式").CreateInstance(factoryName);
            bx = factory.CreateBX();
            bx.Display();
            Console.ReadLine();
        }
    }
}
        配置文件的代码如下:
  <appSettings>
    <add key="factory" value="抽象工厂模式.MeiDiFactory"/>
  </appSettings>
        程序的运行结果如下:


        到这里抽象工厂模式就给大家介绍完了。最后再简单介绍一下抽象工厂的优缺点:

        优点:抽象工厂在增加产品族的时候,很多好的符合了开闭原则。因为只需要增加具体产品和一个对象的具体工厂即可。不需要修改源代码。可以提供一个可视化界面,允许用户修改配置文件来修改工厂。

        缺点:如果要增加一个产品等级结构,就需要修改几乎所有的代码。在上面的代码中说到了电视,冰箱。如果现在要增加一个抽象空调——海尔空调,海信空调,美的 空调。就需要在抽象工厂中新增创建空调的方法,在所有的具体工厂中实现该方法,如果你系统中工厂类过多,显然会给修改带来很大的麻烦。这严重违背了开闭原则。也是抽象工厂最大的缺点所在。所以抽象工厂的使用一定要谨慎。以免给后期维护带来诸多麻烦。

        源代码下载地址:链接:http://pan.baidu.com/s/1hrw7M2w 密码:wps7

        下一节将给大家介绍建造者模式

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐