目录
要了解抽象工厂,先得了解什么叫产品等级结构,什么叫产品族。
场景:
Sunny软件公司欲推出一款新的手机游戏软件,该软件能够支持Symbian、Android和Windows Mobile等多个智能手机操作系统平台,针对不同的手机操作系统,该游戏软件提供了不同的游戏操作控制(OperationController)类和游戏界面控制(InterfaceController)类,并提供相应的工厂类来封装这些类的初始化过程。软件要求具有较好的扩展性以支持新的操作系统平台,为了满足上述需求,试采用抽象工厂模式对其进行设计。
产品等级结构:同一类产品类型下面都不同型号的产品称为产品等级。例如上面的Symbian游戏操作控制和android游戏操作控制都叫做游戏操作控制即为同一产品类型,但两者属于不同系统下的操作控制,故两者为不同的产品等级。
产品族:产品族是对应工厂来说的,一个工厂下面生产的产品等级结构的集合称为产品族。
相信你现在还是懵逼是,反正我当时看完之后是懵逼的!!!
理解的关键点:谁作为产品族,谁作为产品等级,比如上面的案例,谁应该作为产品族,谁应该作为产品等级呢?记住一点,产品族不可扩展,产品等级结构可进行扩展(抽象工厂的倾斜性扩展)。上面要求,对操作系统来说以后要能进行扩展,所以很容易区分出来,操作系统是决定产品等级结构原因,游戏控制操作、游戏界面操作是产品族。
操作系统是 产品等级结构产生的原因,而这种原因是支持扩展的。
例如:有了symbian操作系统,才会出现为symbian量身定做的新的游戏操作控制和游戏界面控制产品等级结构,而新产生的就是新的产品等级结果,所以产品等级结构是支持扩展的。
理解的关键点变为:谁作为产品族?谁是产生新产品等级结构的因素?记住一点,产品族不可扩展,产品等级结构可进行扩展(抽象工厂的倾斜性扩展 )上面就很容易得出,因为后面要求系统可扩展,则游戏操作控制、游戏界面控制是产品族;各个不同系统是产生不同产品等级结构的因素。工厂类的作用就是将特定的因素和产生的相应结果进行组装。
图片抄自:https://www.jianshu.com/p/5fb1e21c4d19
现在结合代码:
1、构建产品族---界面控制抽象类AbstractInterfaceController、游戏操作控制抽象类AbstractOperationController
/**
* 界面控制抽象类
*
* @author qiaofeng
*/
public abstract class AbstractInterfaceController {
public abstract void interfaceOperation();
}
/**
* 游戏操作控制抽象类
*
* @author qiaofeng
*/
public abstract class AbstractOperationController {
//具体的操作抽象方法
public abstract void operationControl();
}
2、抽象工厂类----封装产生不同产品等级结构的原因和对应的结果SystemAbstractFactory
/**
* 抽象工厂类
*
* @author qiaofeng
*/
public interface SystemAbstractFactory {
/**
* 获取游戏界面控制 --产品类
* @return 游戏界面控制对象
*/
AbstractInterfaceController getAbstractInterfaceController();
/**
* 获取游戏操作控制 --产品类
* @return 游戏操作控制对象
*/
AbstractOperationController getAbstractOperationController();
}
上面就已经将抽象工厂的结构搭建起来了,下面我们开始进行实现,相当于扩展产品结构等级。
3、现在要增加一个symbian操作系统,该系统有自己特定的游戏界面控制和游戏操作控制,故下面实现这两个产品等级结构
/**
* 塞班系统游戏界面操作
*
* @author qiaofeng
*/
public class SymbianInterface extends AbstractInterfaceController {
@Override
public void interfaceOperation() {
System.out.println("塞班系统执行了游戏界面操作");
}
}
/**
* 塞班系统游戏控制
*
* @author qiaofeng
*/
public class SymbianOperation extends AbstractOperationController {
@Override
public void operationControl() {
System.out.println("塞班系统执行游戏控制操作");
}
}
4.对symbian系统量身定制的产品等级结构(界面控制、操作控制)进行封装成工厂实现类,提供给使用symbian系统的人使用。
/**
* 塞班系统
*
* @author qiaofeng
*/
public class SymbianFactory implements SystemAbstractFactory{
@Override
public AbstractInterfaceController getAbstractInterfaceController() {
return new SymbianInterface();
}
@Override
public AbstractOperationController getAbstractOperationController() {
return new SymbianOperation();
}
}
进行测试:
public static void main(String[] args) {
SystemAbstractFactory symbianFactory = new SymbianFactory();
symbianFactory.getAbstractInterfaceController().interfaceOperation();
symbianFactory.getAbstractOperationController().operationControl();
}
输出结果:
塞班系统执行了游戏界面操作
塞班系统执行游戏控制操作
- 当产品族只有一个是即为简单工厂模式,当产品族有多个时,便是抽象工厂模式。
- 现在有新的需求,android系统需要不一样的游戏控制与界面控制,则方法相同,先扩展各产品族对产品等级结构(界面控制、操作控制),在使用androidFactory工厂实现类对相应产品族先量身定制对产品等级结构进行封装。代码和上面symbian的类似,就不贴代码了。
说明点:由于抽象工厂的倾斜性扩展,所以扩展产品等级结构很容易,但是要扩展产品族(界面控制、操作控制)例如在扩展一个界面声音控制就比较困难了,必须修改抽象工厂,增加界面声音控制产品,那么之前实现了改抽象工厂的工厂实现类都得修改,违背开闭原则。
扩展部分 和理解抽象工厂关系不大,但有点点关系!!
比如说现在操作系统已经有20多个了,每次使用都得new对应操作系统的工厂类,操作总有点不方便类似下面这样:
public static void main(String[] args){
SystemAbstractFactory symbianFactory = new SymbianFactory();
symbianFactory.getAbstractInterfaceController().interfaceOperation();
symbianFactory.getAbstractOperationController().operationControl();
SystemAbstractFactory androidFactory = new AndroidFactory();
androidFactory.getAbstractOperationController().operationControl();
androidFactory.getAbstractInterfaceController().interfaceOperation();
......
....
....
..
}
我想到的解决方案:通过反射的方式获取相应的工厂对象(其实两者差不多,下面的少了new的操作),代码上要优雅得多。
public static SystemAbstractFactory getSystemAbstractFactory(String className) {
try {
return (SystemAbstractFactory) Class.forName(className).newInstance();
} catch (Exception e) {
System.out.println("通过反射获取工厂对象失败");
throw new RuntimeException("通过反射获取工厂对象失败");
}
}
public static void main(String[] args) {
SystemAbstractFactory symbianFactory = getSystemAbstractFactory(SymbianFactory.class.getName());
symbianFactory.getAbstractInterfaceController().interfaceOperation();
symbianFactory.getAbstractOperationController().operationControl();
SystemAbstractFactory androidFactory = getSystemAbstractFactory(AndroidFactory.class.getName());
androidFactory.getAbstractOperationController().operationControl();
androidFactory.getAbstractInterfaceController().interfaceOperation();
。。。。。
。。。。
。。。
。。
。
}
简单工厂模式和工厂模式的区别:
简单工厂模式---->简单工厂类有个方法,根据传入的参数创建对应的产品等级对象,会导致每次需要增加产品等级结构时都要修改工厂类,不符合开闭原则。
抽象/工厂模式---->抽象工厂模式使用工厂实现类代替不同参数传入的情况,根据需要new自己对应的工厂实现类;当需要进行业务扩展时,直接实现抽象工厂类,不需要修改原来的工厂实现类,符合开闭原则,易于扩展。
简单工厂模式,当工厂抽象类里面有多个产品族时,简单工厂模式就变为抽象工厂模式。
参考地址:
https://www.jianshu.com/p/5fb1e21c4d19
https://blog.csdn.net/lovelion/article/details/9319571