设计模式(二 & 三)工厂模式: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 ...
随机推荐
- LibreOJ #2037. 「SHOI2015」脑洞治疗仪
线段树区间合并问题 恶心... 屠龙宝刀点击就送 #include <cstdio> #define N 200005 struct Segment { int l,r,mid,sum,l ...
- 小常识:变量的修饰符和DEMO
public static string ss = "这是全局静态变量";//生命周期:程序结束为止,可以修改 public string s = "这是全局变量&quo ...
- 【Python全栈-JavaScript】JavaScript-字符串详解
JavaScript-字符串详解 预热:Number() 方法 <script> //重要等级 1,2,3,4,5 var s=10; //最高级别5 var s1=new Number( ...
- LINQ结合正则表达式查询文件系统
string startFolder = @"D:\Program Files (x86)\Microsoft Visual Studio 12.0\"; IEnumerable& ...
- 代码块(block)的使用
Objective-C语法之代码块(block)的使用 代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱 ...
- 【MySql】Mysql ERROR 1067: Invalid default value for ‘date’ 解决
在给一个表添加字段的时候,忽然发现会报一个date类型的字段的默认值错误,郁闷~ 经过排查,原来是MySQL的配置问题,在wamp下,MySQL 5.7里是没有设置 SQL_MODE 的. 1.my. ...
- com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 3 字节的 UTF-8 序列的字节 x 无效
在启动Tomcat项目时,控制台报错:nested exception is com.sun.org.apache.xerces.internal.impl.io.MalformedByteSeque ...
- destoon添加修改会员信息时,信息丢失
最近做一destoon项目,因注册字段太多,分了几个步骤.分几个页面来修改公司信息.发现有时候修改时以前保存的字段莫名丢失.. 经查是 因为member.class.php add 和 edit时, ...
- thinkphp5开发restful-api接口学习 笔记二
目录 第4节 为api项目搭建数据库 第5节 使用markdown书写接口文档 第6节(判断数据库中是否有此用户) 第7节 为项目配置URL 需求分析 配置主域名和二级域名 使用tp5路由进行URL解 ...
- linux系统入门—文件管理
目录 linux系统入门-文件管理 系统目录结构 目录管理 linux系统入门-文件管理 系统目录结构 几乎所有的计算机操作系统都是使用目录结构组织文件.具体来说就是在一个目录中存放子目录和文件,而在 ...