抽象工厂模式
-
有两个变化维度
-
有一个变化维度包含的产品是继承统一品牌工厂——产品等级结构
另一个变化维度包含的产品通常为一起使用——产品族
动机
一个工厂提供多个产品对象——海尔工厂可以生产海尔冰箱,海尔电视机等且有多个品牌
定义
- 对象创建型模式
- 提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类
结构
抽象工厂:针对抽象产品进行声明
具体工厂:针对具体产品进行声明
抽象产品:一类产品——电视机、冰箱
具体产品:具体后一个产品——海尔电视机
产品族和产品等级结构
产品族:统一品牌工厂生产的一同协作的一族产品
产品等级结构:不同种类的产品
*注:课件问题,虚实线不准确,准确的请看后续另一个图。
分析
产品族:对应工厂
产品等级结构:对应产品
简例
如何定义产品族和产品等级结构
关键哪些是一同协作,倘若上述的转换横纵坐标,那么产品族为WindowsButton、UnixButton和LinuxButton,而产品族的定义为一同协作,显然这三种按钮不可能在同一电脑上一同协作
实例
*注:这里的虚实线为准确的虚实线
EFactory类
public interface EFactory
{
public Television produceTelevision();
public AirConditioner produceAirConditioner();
}
Television类
public interface Television
{
public void play();
}
AirConditioner类
public interface AirConditioner
{
public void changeTemperature();
}
HaierFactory类
public class HaierFactory implements EFactory
{
public Television produceTelevision()
{
return new HaierTelevision();
}
public AirConditioner produceAirConditioner()
{
return new HairAirConditioner();
}
}
HaierTelevision类
public class HaierTelevision implements Television
{
public void play()
{
System.out.println("海尔电视机播放中......");
}
}
HaierAirConditioner类
public class HairAirConditioner implements AirConditioner
{
public void changeTemperature()
{
System.out.println("海尔空调温度改变中......");
}
}
*注:另一产品相同,不作重复展示
Client类
public class Client
{
public static void main(String args[])
{
try
{
EFactory factory;
Television tv;
AirConditioner ac;
factory=(EFactory)XMLUtil.getBean();
tv=factory.produceTelevision();
tv.play();
ac=factory.produceAirConditioner();
ac.changeTemperature();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
客户端类里定义的都是抽象层的,符合依赖倒转原则
运行结果
优点
- 隔离了具体类生成,客户端不需要知道什么被创建了
- 一个产品族多个对象设计成一起工作是,能保证只使用统一产品族中的对象——通过配置文件,都是使用的海尔工厂生产的产品族
- 新增产品族很方便,无需修改已有系统,符合开闭原则
缺点
增加产品等级结构的时候要修改代码,违背开闭原则——开闭原则的倾斜性,往一侧倾斜。因此,如果产品族和产品等级结构不容易区分时,则将常扩展维度的定为产品族,不常扩展的维度定位产品等级结构
适用场景
- 不依赖于产品类实例怎么被创建、组合和表达的细节
- 有多个产品族,但每次只使用某一产品族
- 产品等级结构稳定
退化
当抽象工厂每个具体工厂类只有一个产品对象时,即只有一个产品等级结构时,退化成工厂方法模式——海尔工厂只生产电视机。