抽象工厂模式简介:

每一个模式都是针对某一种问题的解决方案。抽象工厂模式与工厂模式最大的区别在于,工厂模式针对的是一个产品等级结构,而抽象工厂模式面对的是多个产品等级结构,即产品族的概念。

这里讲解一下产品等级与产品族:Cpu属于一种产品,Cpu有多种型号,比如Intel的、AMD的,它们都属于同一个产品等级,即同一类产品下边的不同系列或者品牌;而产品族是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如对于Intel公司,这家公司生产的Cpu,也生产主板,内存,芯片组等相关联产品组成一个产品族。所以我们只要知道某个产品所属的产品族,以及这个产品在产品族中的产品等级结构,就可以唯一确定这个产品。

显然,每一个产品族中含有产品的数目,与产品等级结构的数目是相等的。而在工厂模式中,需要创建的工厂类数量等于产品等级结构数目。由于这三个产品等级结构的相似性,会导致三个平行的工厂等级结构。随着产品等级结构的数目的增加,工厂方法模式所给出的工厂等级结构的数目也会随之增加。如下图:

造成大量重复性代码,这样违背了软件设计初衷。

那么是否可以将这些极为相似的产品等级工厂代码用同一个产品等级工厂代替呢?当然可以,这就是产品族的概念,之前是纵向构建了多个产品等级工厂,那么我们改为横向的使用产品族来构建一个产品族工厂,这个与我们现实世界的工厂更为相似。如图:

显然,这种工厂模式更有效率。

抽象工厂模式详解:

抽象工厂模式是对象的创建模式,它是工厂模式的进一步推广。假设一个子系统需要多个产品对象,而这些产品对象又不处于同一个产品等级,为了将消费这些产品对象的责任与创建这些产品对象的责任分隔开,可以引入抽象工厂模式。这样消费产品的一方不必参与产品的创建工作,只需要向一个工厂接口请求生产产品即可。

由于上述两个产品族的产品等级结构相同,所以可以继续将两个产品族抽象为同一个工厂族,这就是抽象工厂概念。

源代码:

前面示例实现的CPU接口和CPU实现对象,主板接口和主板实现对象,都不需要变化。

  工厂类需要全部重写,新加入的抽象工厂类和实现类:

package com.itheima.factory.factory;

import com.itheima.factory.entity.CPU;
import com.itheima.factory.entity.Mainboard;
/**
* 抽象工厂类,定义规范
* @author Administrator
*
*/
public interface AbstractFactory {
/**
* 创建CPU
* @return
*/
public CPU createCpu();
/**
* 创建主板对象
* @return
*/
public Mainboard createMainboard();
} //具体的实现类工厂
package com.itheima.factory.factory; import com.itheima.factory.entity.CPU;
import com.itheima.factory.entity.IntelCpu;
import com.itheima.factory.entity.IntelMainboard;
import com.itheima.factory.entity.Mainboard;
/**
* Intel工厂
* @author Administrator
*
*/
public class IntelFactory implements AbstractFactory {
@Override
public CPU createCpu() {
// TODO Auto-generated method stub
return new IntelCpu(755);
}
@Override
public Mainboard createMainboard() {
// TODO Auto-generated method stub
return new IntelMainboard(755);
}
} package com.itheima.factory.factory; import com.itheima.factory.entity.AmdCpu;
import com.itheima.factory.entity.AmdMainboard;
import com.itheima.factory.entity.CPU;
import com.itheima.factory.entity.Mainboard;
/**
* AMD工厂
* @author Administrator
*
*/
public class AmdFactory implements AbstractFactory { @Override
public CPU createCpu() {
// TODO Auto-generated method stub
return new AmdCpu(938);
}
@Override
public Mainboard createMainboard() {
// TODO Auto-generated method stub
return new AmdMainboard(938);
}
}

组装工程师代码与之前的主要区别是:现在不在需要客户传入Cpu与主板的类型,而是直接传入已经选择后的产品对象,且产品对象已经被限制,客户无法选择Intel与Amd的组合了。客户要选就是一套,一个组合。

package com.itheima.factory.engineer;

import com.itheima.factory.entity.CPU;
import com.itheima.factory.entity.Mainboard;
import com.itheima.factory.factory.AbstractFactory; public class ComputerEngineer {
//需要Cpu
private CPU cpu;
//需要主板
private Mainboard mainboard;
//组装电脑
public void makeComputer(AbstractFactory af) {
cpu=af.createCpu();
mainboard=af.createMainboard();
cpu.calculate();
mainboard.installCpu();
System.out.println("电脑组装完成");
}
}

客户端代码:

package com.itheima.factory.client;

import com.itheima.factory.engineer.ComputerEngineer;
import com.itheima.factory.factory.AbstractFactory;
import com.itheima.factory.factory.IntelFactory; public class Client {
public static void main(String[] args) {
//创建装机工程师对象
ComputerEngineer computerEngineer = new ComputerEngineer();
//客户选择从并创建相应的产品对象
AbstractFactory af=new IntelFactory();
computerEngineer.makeComputer(af);
}
}

抽象工厂的功能是为一系列相关对象或相互依赖的对象(跨产品等级)创建一个接口。一定注意接口内的方法不是任意堆砌的,而是一系列相关的或相互依赖的方法。比如上面例子中的主板和CPU,都是为了组装一台电脑的相关对象。不同的装机方案,代表一种具体的电脑系列。

由于抽象工厂定义的一系列对象通常是相关或相互依赖的,这些产品对象就构成了一个产品族,也就是抽象工厂定义了一个产品族。这就带来非常大的灵活性,切换产品族的时候,只要提供不同的抽象工厂实现就可以了,也就是说现在是以一个产品族作为一个整体被切换。

在什么情况下应当使用抽象工厂模式

  1.一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。

  2.这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

  3.同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。(比如:Intel主板必须使用Intel CPU、Intel芯片组)

  4.系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

2.java设计模式-抽象工厂模式的更多相关文章

  1. JAVA设计模式--抽象工厂模式

    抽象工厂设计模式 1.系统中有多个产品族,而系统一次只可能消费其中一族产品2.同属于同一个产品族的产品以其使用.来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):抽象工厂角色: 这是工厂方法模式的 ...

  2. Java设计模式-抽象工厂模式(Abstract Factory )

    工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这 ...

  3. Java设计模式-抽象工厂模式(Abstarct Factory)

    抽象工厂模式 举个生活中常见的例子,组装电脑,在组装电脑时,通常需要选择一系列的配件,比如CPU,硬盘,内存,主板,电源,机箱等,为了讨论使用简单,值考虑选择CPU和主板的问题. 事实上,在选择CPU ...

  4. Java设计模式——抽象工厂模式

    抽象工厂模式也是创建模式,可以把它理解成创建工厂的工厂,这种模式也是我们经常使用的.在抽象工厂中的接口是用来创建工厂的,每个生成的工厂又都可以按照工厂模式创建其他对象. 举例说明: 创建Shape接口 ...

  5. 设计模式——抽象工厂模式及java实现

    设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...

  6. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

  7. Java设计模式之工厂模式(Factory模式)介绍(转载)

    原文见:http://www.jb51.net/article/62068.htm 这篇文章主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式.工厂方法.抽象工 ...

  8. Java 设计模式之工厂模式(二)

    原文地址:Java 设计模式之工厂模式(二) 博客地址:http://www.extlight.com 一.背景 本篇内容是 Java 设计模式创建型模式的第二篇.上一篇主题为 <Java 设计 ...

  9. 浅析JAVA设计模式之工厂模式(二)

    1 工厂方法模式简单介绍 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory),在这样的模式中,核心工厂不再是一个详细的类.而是一个抽象工厂,提 ...

随机推荐

  1. 【git】——简单用法

    git 更新远程代码到本地 git fetch origin master git merge origin/master 冲突: Your local changes to the followin ...

  2. 【UI组件】——用jQuery做一个上拉刷新

    技术要点: 1.jQuery的插件写法 2.上拉刷新步骤分解 3.css样式 jQuery的插件写法: $.fn.pluginName = function() { return this.each( ...

  3. mybatis一级缓存与二级缓存的原理

    1.mybatis中的缓存是在mybatis框架中的Executor中来实现的,我们来看一下Executor的继承图 2.通过以上类图我们可以发现Executor接口下有两大实现类BaseExecut ...

  4. github访问慢加速访问

    实测从1kb到了1m多 方法: 登录 https://www.ipaddress.com/ 输入github.com得到一个或两个IP地址 输入github.global.ssl.fastly.net ...

  5. FindLine把多行查找改为多行替换

    Sub FindLine() Dim textSelection As TextSelection textSelection = DTE.ActiveDocument.Selection textS ...

  6. ASP.NET MVC利用ActionLink实现动态组合查询

    一个文件传输数据表,内有日期.传输协议.传输方向(上传或下载).文件名等信息,完整的表内容显示如下: 现在需要分类查询,即按照协议和传输方向查询.单独的分类查询问题并不大,比如,按协议查询,在View ...

  7. Java反射机制的浅显理解(这篇文章还没写好,留个草稿给自己看的)

    目前只是有一个大概的理解,先把自己感觉容易立即的概念放这里,等以后结合实际工作理解深刻了再来补充. 一.什么是Java反射机制?(多种定义) 1. JAVA反射机制是在运行状态中,对于任意一个类,都能 ...

  8. WCF系列教程之WCF中的会话

    本文参考自http://www.cnblogs.com/wangweimutou/p/4516224.html,纯属读书笔记,加深记忆 一.WCF会话简介 1.在WCF应用程序中,回话将一组消息相互关 ...

  9. shiro学习笔记_0300_jdbcRealm和认证策略

    使用shiro框架来完成认证工作,默认是iniRealm,如果需要使用其他的realm,需要配置. ini配置文件详解,官方文档的说明如下: [main] section 是你配置应用程序的 Secu ...

  10. LINUX 查找替换命令 总结

    find /var/ -name "*.php" > /home/tmp 在/var/目录下查找 所有以.php后缀结尾的文件  结果很多,就 > 输出结果到/home ...