一、简介
定义:
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
为了方便引进抽象工厂模式,引进一个新概念:产品族(Product Family) 。所谓产品族,是指位于不同产品等级结构,功能相关联的产品组成的家族。如图:
图中一共有四个产品族,分布于三个不同的产品等级结构中。只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一的确定这个产品。
引进抽象工厂模式
所谓的抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。如果用图来描述的话,如下图:
二、Abstract Factory模式的结构:
上图用产品族的概念来解释如下图:
其中分为以下四个角色:
- 抽象工厂(Abstract Factory)角色: 担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
- 具体工厂(Concrete Factory)角色: 这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
- 抽象产品(Abstract Product)角色: 担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
- 具体产品(Concrete Product)角色: 抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
三、示范程序
该程序演示了抽象工厂的结构,本身不具有任何实际价值。
先看类图:
抽象产品(按钮):
package _3AbstractFactoryPattern;
public interface IButton {
public void click();
}
抽象产品(输入框):
package _3AbstractFactoryPattern;
public interface ITextInput {
public void input();
}
按钮产品实现(windows):
package _3AbstractFactoryPattern;
public class WindowsButton implements IButton {
@Override
public void click() {
System.out.println("windows 按钮点击");
}
}
按钮产品实现(linux):
package _3AbstractFactoryPattern;
public class LinuxButton implements IButton {
@Override
public void click() {
System.out.println("Linux 按钮点击");
}
}
输入框产品实现(windows):
package _3AbstractFactoryPattern;
public class WindowsTextInput implements ITextInput {
@Override
public void input() {
System.out.println("Windows 输入框输入");
}
}
输入框产品实现(linux):
package _3AbstractFactoryPattern;
public class LinuxTextInput implements ITextInput {
@Override
public void input() {
System.out.println("Linux 输入框输入");
}
}
抽象工厂:
package _3AbstractFactoryPattern;
public interface IUICreator {
public IButton createButton();
public ITextInput createTextInput();
}
工厂实现(windows):
package _3AbstractFactoryPattern;
public class WindowsUICreator implements IUICreator {
@Override
public IButton createButton() {
return new WindowsButton();
}
@Override
public ITextInput createTextInput() {
return new WindowsTextInput();
}
}
工厂实现(linux)
package _3AbstractFactoryPattern;
public class LinuxUICreator implements IUICreator {
@Override
public IButton createButton() {
return new LinuxButton();
}
@Override
public ITextInput createTextInput() {
return new LinuxTextInput();
}
}
这其中:button和textinput就是产品等级,而windows和linux两个系列的产品就是产品族。
抽象工厂模式的优点:
- 封装性
- 产品族内的约束为非公开状态
- 扩展产品族非常方便
抽象工厂模式的缺点:
- 扩展产品等级困难,需要修改工厂类的接口.上例中如果需要新增一个panel产品,则需要修改的UICreator接口。
抽象工厂模式的使用场景:
一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。上例中的button和TextInput没有任何关系,但是它们同时被操作系统约束。