一、引言:
抽象工厂模式是工厂模式的升级版,书上说,这种模式的使用场景是:一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。该模式的设计方针图如下:
从图上可以看出,该模式的封装性非常好,client直接依赖于抽象工厂和抽象产品类就实现了产品的真正产出,也就是说,client端完全不需要知道工厂具体是怎么去产出的,只需要知道不同的工厂能生产什么产品就行了。
这里举一个demo,实现一个Word软件和绘图软件在不同OS(windows,Linux,Mac)下的使用来具体说明一下。
我认为这个设计模式强调维度的概念,如果以x-y坐标来表示这种设计模式的话,y轴强调的是“产品”的具体实现过程,而x轴则强调的是“工厂”:
Y轴的软件就是我们的产品接口,而DrawSoft和WordSoft则是我们的抽象产品,为什么说这两款软件是抽象的,因为,在不通的OS上面,两款软件各自实现的功能是一样的,但是,其软件内部实现是不同的,所以,真正的实现产品有六款,即每个操作系统下面都各有一个DrawSoft和WordSoft,所以,对于产品这条线,我们需要紧抓“接口-抽象类-实现类”这条线,而对于“工厂”,当然也有一个接口,就是操作系统,而其实现类就是具体的操作系统了,Windows,Linux或者MacOS,我们需要去打开一个软件的时候,在对应平台下去点击具体的软件就可以了。
二、代码:
1.首先是“产品线”:
软件接口很简单:
/* 产品接口:软件 */
interface Soft {
/* 软件信息描述 */
public void softShow();
public void getOSInfo();
}
然后是两个抽象类:
/* 产品抽象类:Word/draw */
abstract class AbstractWordSoft implements Soft {
public void softShow() {
System.out.println("This is word soft!");
}
}
abstract class AbstractDrawSoft implements Soft {
public void softShow() {
System.out.println("This is draw soft!");
}
}
最后就是具体的实现类了,这里仅列举Windows下的,其他OS类比:
/* 产品实现类:Windows/Android/Mac 2 * 3 = 6个 */
class WindowsWordSoft extends AbstractWordSoft {
public void getOSInfo() {
System.out.println("OS:Windows");
}
}
class LinuxWordSoft extends AbstractWordSoft {
public void getOSInfo() {
System.out.println("OS:Linux");
}
}
...
2.“工厂”:
工厂的任务很简单,就是去打开软件,软件接口如下:
/* 工厂类接口定义 */
interface SoftFactory {
/* 打开Word软件 */
public Soft openWordSoft();
/* 打开Draw软件 */
public Soft openDrawSoft();
}
假如你是用户,你现在要使用Word软件,你肯定是知道你在哪个操作系统下使用的,所以,这里的实现类就是不同的操作系统了:
class LinuxFactory implements SoftFactory {
/* 打开Linux下的Word软件 */
public Soft openWordSoft() {
return new LinuxWordSoft();
}
/* 打开Windows下的Draw软件 */
public Soft openDrawSoft() {
return new LinuxDrawSoft();
}
}
class MacFactory implements SoftFactory {
/* 打开Mac下的Word软件 */
public Soft openWordSoft() {
return new MacWordSoft();
}
/* 打开Mac下的Draw软件 */
public Soft openDrawSoft() {
return new MacDrawSoft();
}
}
每个操作系统会去调用具体的方法实现Word还是draw软件的打开;
3.整个源码:
/* 产品接口:软件 */
interface Soft {
/* 软件信息描述 */
public void softShow();
public void getOSInfo();
}
/* 产品抽象类:Word/draw */
abstract class AbstractWordSoft implements Soft {
public void softShow() {
System.out.println("This is word soft!");
}
}
abstract class AbstractDrawSoft implements Soft {
public void softShow() {
System.out.println("This is draw soft!");
}
}
/* 产品实现类:Windows/Android/Mac 2 * 3 = 6个 */
class WindowsWordSoft extends AbstractWordSoft {
public void getOSInfo() {
System.out.println("OS:Windows");
}
}
class LinuxWordSoft extends AbstractWordSoft {
public void getOSInfo() {
System.out.println("OS:Linux");
}
}
class MacWordSoft extends AbstractWordSoft {
public void getOSInfo() {
System.out.println("OS:Mac");
}
}
class WindowsDrawSoft extends AbstractDrawSoft {
public void getOSInfo() {
System.out.println("OS:Windows");
}
}
class LinuxDrawSoft extends AbstractDrawSoft {
public void getOSInfo() {
System.out.println("OS:Linux");
}
}
class MacDrawSoft extends AbstractDrawSoft {
public void getOSInfo() {
System.out.println("OS:Mac");
}
}
/* 工厂类接口定义 */
interface SoftFactory {
/* 打开Word软件 */
public Soft openWordSoft();
/* 打开Draw软件 */
public Soft openDrawSoft();
}
/* 三个工厂实现类 */
class WindowsFactory implements SoftFactory {
/* 打开Windows下的Word软件 */
public Soft openWordSoft() {
return new WindowsWordSoft();
}
/* 打开Windows下的Draw软件 */
public Soft openDrawSoft() {
return new WindowsDrawSoft();
}
}
class LinuxFactory implements SoftFactory {
/* 打开Linux下的Word软件 */
public Soft openWordSoft() {
return new LinuxWordSoft();
}
/* 打开Windows下的Draw软件 */
public Soft openDrawSoft() {
return new LinuxDrawSoft();
}
}
class MacFactory implements SoftFactory {
/* 打开Mac下的Word软件 */
public Soft openWordSoft() {
return new MacWordSoft();
}
/* 打开Mac下的Draw软件 */
public Soft openDrawSoft() {
return new MacDrawSoft();
}
}
public class softapi {
public static void main(String[] args) {
/* Windows系统 */
WindowsFactory wdfactory = new WindowsFactory();
/* Linux系统 */
LinuxFactory lxfactory = new LinuxFactory();
/* Mac系统 */
MacFactory macfactory = new MacFactory();
Soft wdwordsoft = wdfactory.openWordSoft();
wdwordsoft.softShow();
wdwordsoft.getOSInfo();
Soft lxdrawsoft = lxfactory.openDrawSoft();
lxdrawsoft.softShow();
lxdrawsoft.getOSInfo();
}
}