一、抽象工厂模式的由来

  抽象工厂模式,最开始是为了解决操作系统按钮和窗体风格,而产生的一种设计模式。例如:在windows系统中,我们要用windows设定的按钮和窗体,当我们切换Linux系统时,要把按钮和窗体统一切换成Linux风格的。如何统一进行调换呢?于是就有人设计出了,windows是一个工厂,生产windows的窗体和按钮,Linux是一个工厂,生产Linux的窗体和按钮,通过切换工厂,来整体切换按钮和窗体风格。

  看了上面的描述,是不是感觉说了一堆废话呢?其实抽象工厂模式是从工厂方法模式演变来的。在工厂方法模式中,工厂是不是就只做一件事情呢?只返回一个产品呢?但是在实际业务当中,一个工厂,可能要做多个事情,比如上面描述的,要同时搞定按钮和窗体两件事情,搞定多个事情的工厂,就是抽象工厂。

二、抽象工厂模式的定义

  定义:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。工厂模式中的每一个形态都是针对一定问题的解决方案,工厂方法针对的是多个产品系列结构;而抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列。

  在上面一通官方的说法下,是不是又蒙蔽了呢?下面,我用通俗的话,解释一下子。

  提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类:这句话的意思就是,提供一个抽象工厂接口,这个接口定义多个产品调度方法,而不是一个产品调度的方法。无需指定他们的具体类,是说,接口定义的方法,返回的都是产品规范类型,使用者无需用具体产品类接收,用产品规范类接收即可。

  抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列:这句话里,提到了产品族和产品等级。好多地方也提到了这两个概念。产品族就是一个抽象工厂的实现类。多个产品族就是不同的工厂实现类。产品等级就是在一个抽象工厂类里,多个产品的调度。其实就是一个工厂类里的多个产品。

三、抽象工厂模式的角色

  抽象工厂模式的角色与工厂方法模式角色一样。只不过,抽象工厂里有多个产品等级而已。具体见《设计模式之工厂方法模式(Factory Method Pattern)

四、抽象工厂模式的实现

我们就以Windows系统和Liunx系统的窗体和按钮风格为例,实现抽象工厂模式。

首先,定义产品规范,抽象工厂都是产品等级的,这里,分为窗体产品和按钮产品两种:

/**
* 按钮产品规范
*/
public interface Buttom {
public void buttonStyle();
}
/**
* 窗体产品规范
*/
public interface Form {
public void formStyle();
}

分别实现linux系统的窗体、按钮产品和windows系统的窗体、按钮产品,如下代码:

/**
* linux系统按钮产品
*/
public class LinuxButtom implements Buttom {
@Override
public void buttonStyle() {
System.out.println("linux系统按钮");
}
}
/**
* linux系统窗体产品
*/
public class LinuxFrom implements Form {
@Override
public void formStyle() {
System.out.println("linux系统窗体");
}
}
/**
* windows系统按钮产品
*/
public class WindowsButtom implements Buttom {
@Override
public void buttonStyle() {
System.out.println("windows系统按钮");
}
}
/**
* windows系统窗体产品
*/
public class WindowsForm implements Form {
@Override
public void formStyle() {
System.out.println("windows窗体");
}
}

接下来,需要定义工厂了,工厂需要调度按钮和窗体两个产品,这就是两个产品等级,一个工厂里包含了两个方法,这个工厂就叫产品族。我们先定义抽象工厂:

/**
* 定义抽象工厂族,调度窗体和按钮两个产品等级
*/
public abstract class AbstractFactory {
//按钮产品等级
public abstract void setButtom();
//窗体产品等级
public abstract void setForm();
}

然后我们要实现抽象工厂,抽象工厂的实现类实现两个调度方法。如下代码:

/**
* linux系统工厂实现
*/
public class LinuxAbstractFactory extends AbstractFactory {
@Override
public void setButtom() {
new LinuxButtom().buttonStyle();
} @Override
public void setForm() {
new LinuxFrom().formStyle();
}
}
/**
* windows系统工厂实现类,实现两个产品等级
*/
public class WindowsAbstractFactory extends AbstractFactory{
@Override
public void setButtom() {
new WindowsButtom().buttonStyle();
} @Override
public void setForm() {
new WindowsForm().formStyle(); }
}

作为设计模式的使用者,选择抽象工厂的实现类,来获得想要的产品,如下:

/**
* 使用者
*/
public class AbstractFactoryUser {
public static void main(String[] args) {
//使用者选择实现工厂类,生成产品组合
AbstractFactory factory=new WindowsAbstractFactory();
factory.setButtom();
factory.setForm();
}
}

五、抽象工厂模式在JDK中的实现

  抽象工厂模式在JDK中的典型应用是JDBC的Connection接口。前面我们已经分析了JDBC注册不同数据库的驱动,用的是简单工厂模式。在注册完驱动后,会得到不同驱动的Connection对象。Connection也是jdk提供的一个接口。所以驱动注册完后,需要实现Connection接口。Connection就相当于一个抽象工厂,里面定义了Statement、PreparedStatement、CallableStatement多个产品等级。Statement、PreparedStatement、CallableStatement都是产品规范接口,所以,数据库供应商在提供驱动时,需要同时提供一套Statement,PrepareStatement的产品实现类,还要提供Connection抽象工厂的实现类。这样,在使用者那里,不管切换哪个厂商的数据库驱动,只要面向抽象工厂类开发即可,无需知道内部实现。

  所以,在JDBC中,Driver利用的是简单工厂模式,其工厂类是DriverManager。Connection利用的是抽象工厂模式,它就是那个抽象工厂。

  由此可以看出,工厂模式设计的初衷就是,让使用者只面对接口进行开发即可,无需关心接口的内部继承和内部实现。



最新文章

  1. PHP的日期和时间处理函数
  2. Ajax跨域:Jsonp原理解析
  3. ASP.NET MVC SSO单点登录设计与实现(转载)
  4. ORACLE临时表总结(转载)
  5. Codeforce - Rock-Paper-Scissors
  6. Emmet 真是个好东西
  7. 刚刚结束了公司EP流程,开始KMS项目开发了
  8. Linux下使用fdisk发现磁盘空间和使用mount挂载文件系统
  9. H2 database的使用
  10. ASP.NET MVC5学习笔记之Controller执行ControllerDescriptor和ActionDescriptor
  11. Java 第六天 Spring Annotation 和其它
  12. hdu 2665 Kth number(划分树模板)
  13. django开发总结:
  14. linux shell pushd popd dirs命令
  15. 服务端API的OAuth认证实现
  16. C# lock关键词/lock语句块、线程锁
  17. gridview XML
  18. HTML页面使用layer弹出框输入数据
  19. 【代码笔记】Web-JavaScript-JavaScript调试
  20. 路飞学城-Python开发集训-第1章

热门文章

  1. JavaScript_继承
  2. 恢复win10 LTSC 2019 图片查看器功能
  3. MySQL菜鸟实录(一):MySQL服务安装实战
  4. TCP Wrappers原理及简单实验
  5. 命令提示符CMD下切换用户
  6. 3.Work Queues
  7. woj1013 Barcelet 字符串 woj1014 Doraemon's Flashlight 几何
  8. C++ 变量声明数组
  9. C# 类 (5)
  10. 最新 Steam 免费游戏