在前面介绍的简单工厂模式和工厂方法模式中都是只有一个产品等级结构,也就是只定义了一个抽象的产品类,而抽象工厂模式最大的区别就是定义了多个产品等级结构,也就是定义了多个抽象产品类,而这些抽象产品类下又可以实现多个具体的产品类
这样讲可能比较抽象,我们以具体的示例来讲解
假设有IPhone(此IPhone非彼iPhone)和IComputer两个抽象接口,分别表示手机品类和电脑品类
IPhone下两个具体的实现类XiaomiPhone和HuaweiPhone,表示小米手机和华为手机
而IComputer下同样也有两个实现类XiaomiComputer和HuaweiComputer,表示小米电脑和华为电脑
根据之前文章介绍的工厂方法模式可知,如果用工厂方法模式实现的话,几个产品实现类就对应要有几个工厂类,那么如果使用工厂方法模式的话就有XiaomiPhoneFactory、HuaweiPhoneFactory、XiaomiComputerFactory、HuaweiComputerFactory四个工厂类,如果抽象产品类数量m及其对应的实现类数量n更多的话,就需要有m*n个工厂类,这就会造成工厂类的大爆炸,而这就是工厂方法模式的缺点,也是抽象工厂模式要解决的问题
以上问题如果用抽象工厂模式来实现的话,只需要两个工厂类
也就是说同个工厂可以同时生产多种不同的产品,我们可以称之为产品族,入小米手机和小米电脑同属同一个产品族
接下啦我们来看下具体的代码实现
先定义IPhone和IComputer两个接口表示手机和电脑两种产品类型
- public interface IPhone {
- void fun();
- }
-
- public interface IComputer {
- void fun();
- }
然后实现这两种产品类型
- public class XiaomiPhone implements IPhone {
- @Override
- public void fun() {
- System.out.print("小米手机,为发烧而生");
- }
- }
-
- public class XiaomiComputer implements IComputer {
- @Override
- public void fun() {
- System.out.print("小米电脑");
- }
- }
-
- public class HuaweiPhone implements IPhone {
- @Override
- public void fun() {
- System.out.print("华为手机");
- }
- }
-
- public class HuaweiComputer implements IComputer {
- @Override
- public void fun() {
- System.out.print("华为电脑");
- }
- }
接着定义工厂类的抽象类IFactory接口,可以同时生产手机和电脑
- public interface IFactory {
- IPhone createPhone();
- IComputer createComputer();
- }
然后再分别实现小米工厂和华为的工厂
- public class XiaomiFactory implements IFactory {
- @Override
- public IPhone createPhone() {
- return new XiaomiPhone();
- }
-
- @Override
- public IComputer createComputer() {
- return new XiaomiComputer();
- }
- }
- public class HuaweiFactory implements IFactory {
- @Override
- public IPhone createPhone() {
- return new HuaweiPhone();
- }
-
- @Override
- public IComputer createComputer() {
- return new HuaweiComputer();
- }
- }
开闭原则要求一个软件系统在不修改原有软件代码的情况下,通过扩展达到增加其功能的目的
这里分两种情况
对于第一种情况增加产品族,只需要增加一个工厂类GreeFactory,而原来所有的代码都无需修改,所以对于第一种情况是支持开闭原则的
对于第二种情况增加产品类型,就需要修改原有工厂接口类和每一个具体的工厂实现类,使其能够支持生产新的产品类型,比如IFactory就需要做如下的修改,这也就违背了开闭原则
- public interface IFactory {
- IPhone createPhone();
- IComputer createComputer();
- ICooker createCooker(); // 新增生产电饭煲的方法
- }
所以说抽象工厂模式只部分支持开闭原则,适用于产品类型固定,产品族有可能增加的场景