在实际场景下, 一个工厂往往会有多个产品的创建。 那么对于工厂方法模式来说, 是不实用的。 对于这样的需求,采用的就是抽象工厂模式。其对应的类图如下:
3-1Q11416002NW.gif
由上图看得出来, 其实抽象工厂模式和工厂方法模式其实是差不多的。 只不过一个工厂不单单只创建一种产品而已。所以总结来说工厂方法模式和抽象工厂模式的区别为:
工厂方法时一个工厂对应一个产品,抽象工厂是一个工厂对应多个产品

1、场景描述

现有华为、小米两个公司。 假设其都会生产电脑以及手机。表示如下:

  • 华为 —-> 电脑 + 手机
  • 小米 —-> 电脑 + 手机

    2、实现

    ```csharp //**定义产品抽象** /// /// 电脑类抽象接口 /// public interface IComputer { /// /// 展示 /// void Show(); } /// /// 手机类抽象接口 /// public interface IPhone { /// /// 展示 /// void Show(); }

//**产品具体实现** ///

/// 华为电脑 /// public class HuaWeiComputer : IComputer { public void Show() { Console.WriteLine(“华为电脑”); } } /// /// 华为手机 /// public class HuaWeiPhone : IPhone { public void Show() { Console.WriteLine(“华为手机”); } } /// /// 小米电脑 /// public class XiaoMiComputer : IComputer { public void Show() { Console.WriteLine(“小米电脑”); } } /// /// 小米手机 /// public class XiaoMiPhone : IPhone { public void Show() { Console.WriteLine(“小米手机”); } }

//**定义工厂抽象** ///

/// 工厂接口 /// public interface IFactory { /// /// 电脑 /// /// IComputer CreateComputer(); /// /// 手机 /// /// IPhone CreatePhone(); }

//**工厂具体实现** ///

/// 华为工厂 /// public class HuaWeiFactory : IFactory { public IComputer CreateComputer() { return new HuaWeiComputer(); }

  1. public IPhone CreatePhone()
  2. {
  3. return new HuaWeiPhone();
  4. }

} ///

/// 小米工厂 /// public class XiaoMiFactory : IFactory { public IComputer CreateComputer() { return new XiaoMiComputer(); }

public IPhone CreatePhone()
{
    return new XiaoMiPhone();
}

}

//**客户端调用** IFactory factory = null; factory = new HuaWeiFactory(); factory.CreateComputer().Show(); factory.CreatePhone().Show();

factory = new XiaoMiFactory(); factory.CreateComputer().Show(); factory.CreatePhone().Show(); ``` 上面类之间的关系图形可以描述如下:
image.png

3、优缺点

从上面的例子中可以看出, 当我门需要新增一个产品簇的时候。 比如Apple。 通过实现IFactory、IComputer、IPhone接口就可以完成相应的功能, 对原有的代码不会产生影响。客户端调用的时候也按如上面同样的方式调用即可,满足开闭原则
但是当我们新增一个产品的时候, 即我们现在不仅仅生产电脑、手机。还需要生产电视的时候,也就是我们需要在IFactory接口里面添加一个方法:CreateTV()的时候,那么所有的实现都将受影响,而必须更改,这是抽象工厂的缺点之一。
而且我们在面的代码当中可以看出,多一个产品簇,对应的就会增加很多的类,如果考虑产品簇很多的情况下,也会产生**类爆炸**的现象。

4、应用场景

当我们需要创建的对象,或者说是实现的业务, 是一系列互相关联、依赖的产品簇的时候。 那么就可以考虑使用抽象工厂模式。但是也要注意,抽象工厂模式每次只能使用其中的一种产品, 且对客户端来说不应该关心具体的创建细节。