在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。

    在介绍抽象工厂模式前,我们先厘清两个概念:

产品等级结构:产品等级结构指的是产品的继承结构,例如一个空调抽象类,它有海尔空调、格力空调、美的空调等一系列的子类,那么这个空调抽象类和他的子类就构成了一个产品等级结构。
产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如,海尔工厂生产海尔空调、海尔冰箱,那么海尔空调则位于空调产品族中。
1、什么是抽象工厂模式:

    抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象;并且通过隔离具体类的生成,使得客户端不需要明确指定具体生成类;所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。但该模式的缺点在于添加新的行为时比较麻烦,如果需要添加一个新产品族对象时,需要更改接口及其下所有子类,这必然会带来很大的麻烦。

2、UML结构图:

抽象工厂 AbstractFactory:定义了一个接口,这个接口包含了一组方法用来生产产品,所有的具体工厂都必须实现此接口。
具体工厂 ConcreteFactory:用于生产不同产品族,要创建一个产品,用户只需使用其中一个工厂进行获取,完全不需要实例化任何产品对象。
抽象产品 AbstractProduct:这是一个产品家族,每一个具体工厂都能够生产一整组产品。
具体产品 Product
3、代码实现:

    通过抽象工厂模式,我们可以实现以下的效果:比如宝马320系列使用空调型号A和发动机型号A,而宝马230系列使用空调型号B和发动机型号B,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。也就是说,当每个抽象产品都有多于一个的具体子类的时候(空调有型号A和B两种,发动机也有型号A和B两种),工厂角色怎么知道实例化哪一个子类呢?抽象工厂模式提供两个具体工厂角色(宝马320系列工厂和宝马230系列工厂),分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化,每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

产品类:

//发动机以及型号
public interface Engine {}

public class EngineA extends Engine{
public EngineA(){
System.out.println(“制造–>EngineA”);
}
}
public class EngineBextends Engine{
public EngineB(){
System.out.println(“制造–>EngineB”);
}
}

//空调以及型号
public interface Aircondition {}

public class AirconditionA extends Aircondition{
public AirconditionA(){
System.out.println(“制造–>AirconditionA”);
}
}
public class AirconditionB extends Aircondition{
public AirconditionB(){
System.out.println(“制造–>AirconditionB”);
}
}
创建工厂类:

//创建工厂的接口
public interface AbstractFactory {
//制造发动机
public Engine createEngine();
//制造空调
public Aircondition createAircondition();
}

//为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
客户:

public class Customer {
public static void main(String[] args){
//生产宝马320系列配件
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();

    //生产宝马523系列配件  FactoryBMW523 factoryBMW523 = new FactoryBMW523();  factoryBMW523.createEngine();factoryBMW523.createAircondition();
}

}
工厂模式小结:

1、工厂方法模式与抽象工厂模式的区别在于:

(1)工厂方法只有一个抽象产品类和一个抽象工厂类,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。

(2)抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例

2022-15-Java 设计模式-抽象工厂模式相关推荐

  1. 【JAVA进阶系列】JAVA 设计模式 -- 抽象工厂模式(Abstract Factory)

    [JAVA进阶系列]JAVA 设计模式 -- 抽象工厂模式(Abstract Factory) [1.1]抽象工厂模式简介 抽象工厂者模式的类结构图 AbstractProduct(抽象产品),Abs ...

  2. java设计模式---抽象工厂模式

    工厂模式在项目中是常常用到的,有人说只有大项目才会用到,小项目是体会不出来.其实使用设计模式与项目的大小没有实质性的联系.设计模式是经验的总结而不是衡量项目大小的标准. 以开发项目的DAO层为例,在项 ...

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

    文章目录 抽象工厂 概念 优缺点 优点 缺点 适用场景 代码案例 抽象工厂 使用工厂方法模式足以应付我们可能遇到的大部分业务需求. 但是当产品种类非常多时,就会出现 大量的与之对应的工厂类,这不应该是 ...

  4. 程序设计之Java设计模式(抽象工厂模式)

    原文地址:http://zhangwei-david.iteye.com/blog/2187627,该文通俗易懂,实为经典! 在设计模式一书中是这样描述抽象工厂的意图的: 提供一个创建一系列相关或相互 ...

  5. Java设计模式--抽象工厂模式

    抽象工厂模式(别名:配套) 提供一个创建一系列或相互依赖对象的接口,而无需指定它们具体的类. Abstract Factory Pattern(Another Name: Kit) Provide a ...

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

    抽象工厂模式(Abstact Factory Pattern) , 也是创建型模式之一 . 之前主要介绍了工厂方法模式 , 抽象工厂模式和工厂方法模式稍有区别 . 工厂方法模式中工厂类生产出来的产品都 ...

  7. Java设计模式(工厂模式>抽象工厂模式和原型模式)

    Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...

  8. java设计模式之工厂模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

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

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

  10. Java设计模式之工厂模式篇 (转)

    Java设计模式之工厂模式篇 (转)[@more@]Java设计模式之工厂模式篇 作者:冯睿  本文选自:赛迪网 2003年03月07日 .NET.com.cn/servlets/ad?Pool=te ...

最新文章

  1. Oracle数据库联邦,使用联邦数据库将oracle表迁移到DB2(9.7)中的脚本说明
  2. 【LeetCode系列】从中序与后序遍历序列构造二叉树 从前序与中序遍历序列构造二叉树...
  3. 强化学习(十九) AlphaGo Zero强化学习原理
  4. Oracle数据库导入导出命令imp/exp
  5. MAC + Tomcat——部署Web项目时Tomcat启动成功,但部署的Web项目404错误
  6. 华为云服务器配置ipv6,华为云获“IPv6支持度优秀奖”,持续助推云网融合
  7. 1.EXTJS Row Editor Grid 点取消时插入的新行 的解决方法
  8. mysql group by 重复_mysql – 使用GROUP BY删除重复项的查询
  9. NHibernate教程(5)--CRUD操作
  10. 第十二届 蓝桥杯 青少年C++组 10月比赛 第1题
  11. 2.2 基本算法之递归和自调用函数 1751 分解因数 python
  12. (转)Java ConcurrentModificationException异常原因和解决方法
  13. DNS服务器的基本工作
  14. 《算法图解》---笔记
  15. Oracle的diag文件可以删除,oracle11g rac diag/tnslsnr/pgis2/listener/alert 中的文件能删除吗...
  16. java车辆使用管理系统_JAVA车辆管理系统,基于SSM框架的系统
  17. qq代理服务器传输文件失败,qq接收文件时显示传输文件失败?
  18. TB交易开拓者入门教程
  19. XP硬盘读写速度很慢的解决方法
  20. 使用HybridSN进行高光谱图像分类

热门文章

  1. 为新手准备的安卓连接经典蓝牙模块教程
  2. 运维平台体系化建设之工单系统
  3. Codeforces H. Ancient Wisdom
  4. HTML的audio与video
  5. 中运量71路线路图_中运量公交71路正式开通 附全线完整换乘信息
  6. 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数
  7. VSS2005 出现 Unable to Open User Login File 问题
  8. 人生之路 — 方式方法很重要
  9. 用连接工具连接虚拟机的mysql提示 Host ‘192.168.15.142‘ is not alllowed to connect to this MySQL server解决办法
  10. 【个人实验报告】博客网站