抽象工厂模式
定义:
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
解释:
提供一个用于创建一系列相关产品的接口,在使用的时候,不需要指明具体的产品类
这是一种创建型设计模式
举例:
比如有一个类库包,这个类库可以包为上层应用得到基于当前系统的一些工具,这个工具包括画图工具,记事本工具等;我们称这些工具为一些列相关的产品。
我们知道系统有多个,如Linux,Window,当上层应用判断出处于Linux系统时,可以方便的获取到Linux下的工具软件,同样,在Window下也可以获取Window下的软件
基于这样子的一个场景。我们可以使用如下的代码来实现:
产品类:
首先我们得定义出我们的产品类,我们知道我们有两种工具,分别是画图工具,记事本工具,然后在各个平台下有各自的实现,那么。我们需要首先定义出
画图和记事本的接口类出来。
public interface Painter {
void paint();
}
public interface Notepad {
void write();
}
然后我们分别有Window下的实现和Linux下的实现。
我们先实现Widnow下的工具包
public class WindowPainter implements Painter {
public void paint() {
System.out.println("我是Window下的画图工具");
}
}
public class WindowNotepad implements Notepad {
public void write() {
System.out.println("我是Winwod下的记事本工具");
}
}
然后实现Linux下的工具包
public class LinuxPainter implements Painter{
public void paint() {
System.out.println("我是Linux下的画图工具");
}
}
public class LinuxNotepad implements Notepad{
public void write() {
System.out.println("我是Linux下的记事本工具");
}
}
工厂类
在工厂类中,定义出我们的工具包接口类AbstractToolkit,用于获取指定工具。
public interface AbstractToolKit {
Painter getPainter();//获取画图工具
Notepad getNotePad();//获取记事本工具
}
然后定义出各个操作系统平台下的Toolkit的实现类:
public class WindowToolkit implements AbstractToolKit{
public Painter getPainter() {
return new WindowPainter();
}
public Notepad getNotePad() {
return new WindowNotepad();
}
}
public class LinuxToolkit implements AbstractToolKit{
public Painter getPainter() {
return new LinuxPainter();
}
public Notepad getNotePad() {
return new LinuxNotepad();
}
}
到这里我们的这个简单的类库就开发完成了,我们来看一下上层应用怎么来调用。
比如说,一开始我们的应用在Widow下使用。
public class Client {
public static void main(String[] args) {
AbstractToolKit kit = new WindowToolkit();
Painter painter = kit.getPainter();
painter.paint();;
Notepad notepad = kit.getNotePad();
notepad.write();
}
}
客户端
后来我们的应用切换到Linux下使用,那么只需要简单修改一下即可
public class Client {
public static void main(String[] args) {
AbstractToolKit kit = new LinuxToolkit();
Painter painter = kit.getPainter();
painter.paint();;
Notepad notepad = kit.getNotePad();
notepad.write();
}
}
只需要修改main函数里面一行代码,就可以实现切换。
如果我们需求修改,需要增加支持mac系统,那么我们只需要创建出MacToolkit即可。
类图
应用场景
抽象工厂模式有如下的应用场景:
- 一个系统与产品的创建,组合和实现无关:比如例子中的这个系统,他只想获得对应平台下的工具,至于这个工具是怎么实现的,怎么创建的
应用并不关系,只要能用就可以了。 - 一个系统要有多个产品系列中的一个来配置时:上述的这个例子,在Window下运行时,只需要Window下一系列工具就可以了,不需要其他平台下的
同样,在Linux下也是这样。 - 一个系列的相关产品被设计用来一同使用时,并且希望加强这联系:上述的例子,我们在Linux下只想使用Linux下的工具,而不会想在Linux下获取到Window下
的应用
优点:
- 封装性:只关心抽象产品,封装了具体的产品类。
- 一致性:一个系列中的产品是由一个工厂生产出来的,能够保证相关产品的一致性
- 易交换:可以很方便的从一系列产品中切换到另一个系列的产品。
缺点:
- 产品族扩展困难,如果要新增加一个产品,则下面的所有工程都要修改
参考资料
《GOF 设计模式》
《设计模式之禅》