• 什么是抽象工厂?

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

  何为产品族?还是以 设计模式(二)工厂模式: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. Codevs 1860 最大数

    题目描述 Description 设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数. 输入描述 Input Description 第一行一个正整数n. 第二行n个正整数,空格隔开 ...

  2. 【TensorFlow入门完全指南】神经网络篇·MLP多层感知机

    前面的不做过多解释了. 这里定义了两个占位符,各位也知道,在训练时,feed_dict会填充它们. 定义相关网络. 这里是权值矩阵和偏差. 这里是实例化了网络,定义了优化器和损失,和上一篇一样. 最后 ...

  3. [CV笔记]OpenCV机器学习笔记

    KNN算法: 目的是分类,具体过程为,先训练,这个训练我估计只是对训练数据进行一个存储,knn测试的过程是根据测试样例找出与这个样例的距离最近的k个点,看这k个点中哪个分类所占的比例比较多,那么这个样 ...

  4. NFS缓存IO机制

    NFS的缓存IO机制<一> async 参数模式下分析 NFS 默认的mount参数为async,async 参数表示内核不会透传程序的IO请求给sever,对于写IO会延迟执行,积累一定 ...

  5. Hibernate异常:identifier of an instance of 错误

    今天写项目时,在使用hibernate封装的插入方法时,由于需要同时保存多个数据,导致出现identifier of an instance of 如下代码 :(由于最大最小分数不同所以需要插入两条数 ...

  6. DateTime与long互转

    DateTime转long: public static long GetDateLong(object time) { DateTime epoc = TimeZone.CurrentTimeZon ...

  7. java,求1-100之和。

    package study01; public class TestWhile { public static void main(String[] args) { int sum = 0; int ...

  8. 零拷贝详解 Java NIO学习笔记四(零拷贝详解)

    转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...

  9. Lecture 1

    Principles of GIS( UNSW Metternicht ) outline:data input---data management---data manipulation+data ...

  10. python 取余运算

    python中取余运算逻辑如下: 如果a 与d 是整数,d 非零,那么余数 r 满足这样的关系: a = qd + r , q 为整数,且0 ≤ |r| < |d|. 经过测试可发现,pytho ...