设计模式(二 & 三)工厂模式:3-抽象工厂模式
- 什么是抽象工厂?
抽象工厂模式,引入了“产品族”的概念。
何为产品族?还是以 设计模式(二)工厂模式: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-抽象工厂模式的更多相关文章
- 设计模式之工厂模式VS抽象工厂
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...
- Java设计模式之【工厂模式】(简单工厂模式,工厂方法模式,抽象工厂模式)
Java设计模式之[工厂模式](简单工厂模式,工厂方法模式,抽象工厂模式) 工厂模式出现的原因 在java中,创建一个对象最简单的方法就是使用new关键字.但在一些复杂的业务逻辑中,创建一个对象不只需 ...
- Java设计模式(3)——创建型模式之抽象工厂模式(Abstract Factory)
一.概述 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象. UML图: 其他的过多概念不再 ...
- Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...
- 设计模式(Python)-简单工厂,工厂方法和抽象工厂模式
本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python来实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的 ...
- 设计模式3---工厂模式(Factory Pattern简单工厂、工厂方法、抽象工厂)
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...
- iOS常用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)
1. 简单工厂模式 如何理解简单工厂,工厂方法, 抽象工厂三种设计模式? 简单工厂方法包含:父类拥有共同基础接口,具体子类实现子类特殊功能,工厂类根据参数区分创建不同子类实例.该场景对应的UML图如下 ...
- iOS经常使用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)
1. 简单工厂模式 怎样理解简单工厂,工厂方法. 抽象工厂三种设计模式? 简单工厂的生活场景.卖早点的小摊贩.他给你提供包子,馒头,地沟油烙的煎饼等,小贩是一个工厂.它生产包子,馒头,地沟油烙的煎饼. ...
- [19/04/23-星期二] GOF23_创建型模式(工厂模式、抽象工厂模式)
一.工厂模式(分为:简单工厂模式.工厂方法模式.抽象工厂模式) 实现了创建者和调用者的分离 核心本质:1.实例化对象,用工厂方法代替new操作:2.将选择实现类.创建对象统一管理和控制,从而将调用者跟 ...
- C#设计模式--工厂模式和抽象工厂模式
话说有三大潮牌公司一直相互PK,有一天举办了一个活动让这三大公司来一个PK,我们来看看哪家公司的上衣做出来好看穿得舒服 现在我们有一个上衣的抽象产品让三大公司来做 //抽象产品 public inte ...
随机推荐
- 将Java应用部署到SAP云平台neo环境的两种方式
方法1 - 使用Eclipse Eclipse里新建一个服务器: 服务器类型选择SAP Cloud Platform: 点Finish,成功创建了一个Server: Eclipse里选择要部署的项目, ...
- 重温Javascript(二)-对象
对象 可以想象成散列表,键值对,值可以是数据或函数 创建对象的方式 1.工厂模式 function createPerson(name, age, job){ var o = new Object() ...
- JNI接口的使用(简单版)
详见 http://b6ec263c.wiz03.com/share/s/2SX2oY0nX4f32CY5ax1bapaL2Qtc5q0tIQjG2yfwaU1MX4Ye
- UVA 110020 Efficient Solutions (STL)
把一个人看出一个二维的点,优势的点就是就原点为左下角,这个点为右上角的矩形,包含除了右上角以外边界,其他任意地方不存在点. 那么所有有优势的点将会形成一条下凹的曲线. 因为可能有重点,用multise ...
- kubernetes-平台日志收集(ELK)
使用ELK Stack收集Kubernetes平台中日志与可视化 K8S系统的组件日志 K8S Cluster里面部署的应用程序日志 日志系统: ELK安装 安装jdk [root@localhost ...
- OO作业第一单元总结
一.第一单元作业回顾 系列一作业分为三周进行,都是表达式求导,难度渐进. 第一次实现的是简单幂函数的求导,第二次加入了sin和cos两种三角函数,第三次实现了三角函数内的嵌套以及引入了表达式因 ...
- HTML5语义
语义通俗化为意义,也就是语义化的元素等于意义化的元素,看到这个元素的名称,就知道这个元素的意义,是拿来做什么用的,这就是HTML5的一个新特性,一个具有语义化的元素能够清楚的把元素的意义告诉浏览器和开 ...
- Shell脚本调用ftp上传文件
Shell脚本调用ftp上传文件 1.脚本如下 ftp -n<<! open x.x.x.x ###x.x.x.x为ftp地址 user username password ###user ...
- MySQL 查询优化之 Block Nested-Loop 与 Batched Key Access Joins
MySQL 查询优化之 Block Nested-Loop 与 Batched Key Access Joins 在MySQL中,可以使用批量密钥访问(BKA)连接算法,该算法使用对连接表的索引访问和 ...
- MYSQL不能显示中文字,显示错误“ERROR 1366 (HY000): Incorrect string value: '\xE5\xBC\xA0\xE4\xB8\x89'”
或者建表时带上编码utf8 CREATE TABLE `students`( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR( ...