• 什么是抽象工厂?

  抽象工厂模式,引入了“产品族”的概念。

  何为产品族?还是以 设计模式(二)工厂模式:2-工厂方法模式 提到的 Operation 为例。

  之前讨论的都是局限于 Operation 这个产品,这是一个由“工厂”做出来的产品,而至于是哪一个工厂做出来的产品,我们并不关心。

  抽象工厂模式关注的就是这一点,现在为其加上前缀:“工厂1生产的 Operation”,“工厂2生产的 Operation”。

  这就是产品族,对象拥有相同的行为,但却是有不同的实现。

  • 模拟场景:

  Operation 在这个并不能很好地体现 抽象工厂 的优势,我们换一个例子:

  现在,我需要去创建用户(User)和部门(Department)两个对象,但是底层需要用的数据库(DB2 和 MySQL),可能产生变化,所以需要两套解决方案。

  • 思想:

  首先,针对需要创建的对象,需要一个抽象工厂(AbsFactory),负责创建抽象用户(AbsUser)和抽象部门(AbsDepartment)。

  根据底层的数据库,抽象工厂拥有两个实现,DB2 工厂(FactoryDB2)和 MySQL 工厂(FactoryMySQL)。

  每个工厂各司其职,创建对应的继承抽象类的对象。

  • UML

  

  • UML 分析:

  这是一个针对给出情景的完整 UML 类图。

  为用户(AbsUser)定义了两种行为,而部门(AbsDepartment)没有定义行为。

  从 UML 就可以看出,抽象工厂,是对 工厂方法 的一种延伸,FactoryDB2 和 FactoryMySQL 起着 AbsOperationFactory 的作用。

  将工厂方法的 AbsOperationFactory 转为实例工厂,并在之上加上一个抽象层,就是抽象工厂。

  • 代码:
public abstract class AbsFactory {

    public abstract AbsUser createUser();

    public abstract AbsDepartment createDepartment();
}
public final class FactoryDB2 extends AbsFactory {

    @Override
public UserDB2 createUser() {
return new UserDB2();
} @Override
public DepartmentDB2 createDepartment() {
return new DepartmentDB2();
}
}
public final class FactoryMySQL extends AbsFactory {

    @Override
public UserMySQL createUser() {
return new UserMySQL();
} @Override
public DepartmentMySQL createDepartment() {
return new DepartmentMySQL();
}
}
public abstract class AbsUser {

    protected boolean hasRegistered = false;

    protected void joinDepartment(AbsDepartment department) {
if (hasRegistered) {
System.out.println(this + " join " + department);
} else {
System.out.println(this + " not registered cannot join department");
}
} protected abstract void register(); @Override
public String toString() {
return "User[" + this.getClass().getSimpleName() + ":" + this.hashCode() + "]";
}
}
public final class UserDB2 extends AbsUser {

    @Override
public void register() {
super.hasRegistered = true;
System.out.println(this + "register success");
}
}
public final class UserMySQL extends AbsUser {

    @Override
public void register() {
super.hasRegistered = false;
System.out.println(this + "register failure");
}
}
public abstract class AbsDepartment {

    @Override
public String toString() {
return "Department[" + this.getClass().getSimpleName() + ":" + this.hashCode() + "]";
}
}
public final class DepartmentDB2 extends AbsDepartment {

}
public final class DepartmentMySQL extends AbsDepartment {

}
  • 客户端的调用代码:
public final class AbsFactoryTest {

    @Test
void testFactoryDB2() {
AbsFactory factory = new FactoryDB2();
AbsUser user = factory.createUser();
AbsDepartment department = factory.createDepartment();
user.register();
user.joinDepartment(department);
} @Test
void testFactoryMySQL() {
AbsFactory factory = new FactoryMySQL();
AbsUser user = factory.createUser();
AbsDepartment department = factory.createDepartment();
user.register();
user.joinDepartment(department);
}
}
  • 优势

  从客户端的调用,我们就可以发现,从创建用户开始,后续的代码都是一致的。

  也就是说,只需要改变顶层的实例工厂,就可以改变具体的行为(到底是 MySQL 还是 DB2)。

  如果需要加入新的工厂,例如 FactoryOracle,不会对现有的代码产生破坏,很好体现了:对扩展开放,对修改关闭。

  • 劣势

  在设计 抽象工厂 时,需要完整地考虑到工厂需要创建哪些东西,在这个例子上就是 User 和 Department。

  如果在设计完毕之后,需要引入新的产品,例如订单 Order 之类的,对于现有代码的结构破坏会很大,从顶层开始就破坏了代码的封装性。

  • 抽象工厂有哪些实际应用?

  数据库的 ORM 框架。

  Java 平台无关的特性。

设计模式(二 & 三)工厂模式:3-抽象工厂模式的更多相关文章

  1. 设计模式之工厂模式VS抽象工厂

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...

  2. Java设计模式之【工厂模式】(简单工厂模式,工厂方法模式,抽象工厂模式)

    Java设计模式之[工厂模式](简单工厂模式,工厂方法模式,抽象工厂模式) 工厂模式出现的原因 在java中,创建一个对象最简单的方法就是使用new关键字.但在一些复杂的业务逻辑中,创建一个对象不只需 ...

  3. Java设计模式(3)——创建型模式之抽象工厂模式(Abstract Factory)

    一.概述 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象. UML图: 其他的过多概念不再 ...

  4. Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  5. 设计模式(Python)-简单工厂,工厂方法和抽象工厂模式

    本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python来实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的 ...

  6. 设计模式3---工厂模式(Factory Pattern简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  7. iOS常用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)

    1. 简单工厂模式 如何理解简单工厂,工厂方法, 抽象工厂三种设计模式? 简单工厂方法包含:父类拥有共同基础接口,具体子类实现子类特殊功能,工厂类根据参数区分创建不同子类实例.该场景对应的UML图如下 ...

  8. iOS经常使用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)

    1. 简单工厂模式 怎样理解简单工厂,工厂方法. 抽象工厂三种设计模式? 简单工厂的生活场景.卖早点的小摊贩.他给你提供包子,馒头,地沟油烙的煎饼等,小贩是一个工厂.它生产包子,馒头,地沟油烙的煎饼. ...

  9. [19/04/23-星期二] GOF23_创建型模式(工厂模式、抽象工厂模式)

    一.工厂模式(分为:简单工厂模式.工厂方法模式.抽象工厂模式) 实现了创建者和调用者的分离 核心本质:1.实例化对象,用工厂方法代替new操作:2.将选择实现类.创建对象统一管理和控制,从而将调用者跟 ...

  10. C#设计模式--工厂模式和抽象工厂模式

    话说有三大潮牌公司一直相互PK,有一天举办了一个活动让这三大公司来一个PK,我们来看看哪家公司的上衣做出来好看穿得舒服 现在我们有一个上衣的抽象产品让三大公司来做 //抽象产品 public inte ...

随机推荐

  1. 【LeetCode】4.Median of Two Sorted Arrays 两个有序数组中位数

    题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...

  2. 洛谷 P3019 [USACO11MAR]会见点Meeting Place

    题目背景 征求翻译.如果你能提供翻译或者题意简述,请直接发讨论,感谢你的贡献. 题目描述 Bessie and Jonell are great friends. Since Farmer John ...

  3. Java的三大特性之继承

    此处我会分为这几个部分来理解继承是怎么样的: 1.区分封装.继承和多态 2.区分限定词的范围 3.区分隐藏.覆盖.重载 4.继承的理解 5.一道面试题的原型 --------------------- ...

  4. [Git]使用Git上传本地项目,并同步到Github上

    第一步:先要在github.com中创建一个仓库(New Repository). 第二步,打开Git Bash ① git init [+仓库名]:初始化仓库,执行之后可以在指定的仓库存放地上面看到 ...

  5. Robot Framework(一)入门

    1.1简介 Robot Framework是一个基于Python的,可扩展的关键字驱动的测试自动化框架,用于端到端验收测试和验收测试驱动开发(ATDD).它可用于测试分布式异构应用程序,其中验证需要涉 ...

  6. vue 中根据地址名称获取实际经纬度方法

    <div id="container" class="map" style="margin-top:30px; width: 1200px;he ...

  7. 2018.2.09 php学习(二)

    1.用索引提高效率: 索引是表的一个概念部分,用来提高检索数据的效率,ORACLE使用了一个复杂的自平衡B-tree结构. 通常,通过索引查询数据比全表扫描要快. 当ORACLE找出执行查询和Upda ...

  8. c++作业:求N的阶乘。

    N的阶乘就是n.(n-1)! 5的阶乘是什么?5*4*3*2*1 #include <iostream> using namespace std; int jiecheng(int num ...

  9. redis学习笔记(2)

    redis学习笔记第二部分 --配置文件介绍 二,解析redis的配置文件redis.conf常见配置参数说明redis.conf 配置项说明如下:1. Redis默认不是以守护进程的方式运行,可以通 ...

  10. OwinStartupAttribute出错

    尝试加载应用时出现了以下错误.- 找不到包含 OwinStartupAttribute 的程序集.- 找不到包含 Startup 或 [AssemblyName].Startup 类的程序集.若要禁用 ...