知识点三: 抽象工厂模式
一、概述
抽象工厂模式(Abstract Factory Pattern) 是基于工厂方法模式的一个延伸,是所有形态的工厂模式中最为抽象和最具一般性的一种形态。它属于23种GOF设计模式的创建型设计模式。 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则
,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。简单的说就是:
- 围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
- 在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
定义:提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。
在学习抽象工厂模式之前,最好先熟悉一下简单工厂模式以及工厂方法模式,这样对理解抽象工厂模式会有一定帮助,而且抽象工厂也是基于工厂方法模式的。
二、优缺点及使用场景
优点:
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:
产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
使用场景:
系统的产品多于一个产品族,而系统只消费某一族的产品。
三、模式中包含的角色和其职责以及实现方式
1.角色
抽象工厂(Creator)角色:抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。
具体工厂(Concrete Creator)角色:具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。
抽象产品(Product)角色:抽象模式所创建的所有对象的父类,它负责描述所有的实例锁共有的公共接口。
具体产品(Concrete Product)角色:抽象模式所创建的具体实例对象。
2.产品族和产品等级结构
前面提到过很多次产品族,下面来介绍一下什么是产品族:
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法具有唯一性,一般情况下,一个具体工厂中只有一个或者一组重载的工厂方法。但是有时候我们希望一个工厂可以提供多个产品对象,而不是单一的产品对象,如一个电器工厂,它可以生产电视机、电冰箱、空调等多种电器,而不是只生产某一种电器。为了更好地理解抽象工厂模式,我们先引入两个概念:
- 产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
- 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。
产品等级结构与产品族示意图如图:
3.实现方式
我们将创建 ProductA 和 ProductB 接口和实现这些接口的实体类。下一步是创建抽象工厂类 Creator。接着定义工厂类 ConcreteCreator1 和 ConcreteCreator2,这两个工厂类都是扩展了 Creator。 如图:
四、在java中的实现
1.抽象工厂角色
AnimalFactory.java
/**
* @Description: 抽象工厂
* @Author: Ling.D.S
* @Date: Created in 2018/11/4 20:12
*/
public interface AnimalFactory {
//实例化狗
public Animal getDog();
//实例化猫
public Animal getCat();
}
2.具体工厂角色
YellowFactory.java
/**
* @Description: 产品族工厂:黄色的
* @Author: Ling.D.S
* @Date: Created in 2018/11/5 20:57
*/
public class YellowFactory implements AnimalFactory {
public Animal getDog() {
return new YellowDog();
}
public Animal getCat() {
return new YellowCat();
}
}
BlackFactory.java
/**
* @Description: 产品族工厂:黑色的
* @Author: Ling.D.S
* @Date: Created in 2018/11/5 20:58
*/
public class BlackFactory implements AnimalFactory {
public Animal getDog() {
return new BlackDog();
}
public Animal getCat() {
return new BlackCat();
}
}
3.抽象产品角色
Animal.java
/**
* @Description: 抽象产品
* @Author: Ling.D.S
* @Date: Created in 2018/11/2 16:23
*/
public interface Animal {
public void get();
}
Cat.java
/**
* @Description: 抽象产品类
* @Author: Ling.D.S
* @Date: Created in 2018/11/2 16:24
*/
public abstract class Cat implements Animal {
public abstract void get();
}
Dog.java
/**
* @Description: 抽象产品类
* @Author: Ling.D.S
* @Date: Created in 2018/11/2 16:23
*/
public abstract class Dog implements Animal {
public abstract void get();
}
4.具体产品角色
YellowCat.java
/**
* @Description: 具体产品:黄猫
* @Author: Ling.D.S
* @Date: Created in 2018/11/5 20:44
*/
public class YellowCat extends Cat {
public void get() {
System.out.println("获得黄猫");
}
}
YellowDog.java
/**
* @Description: 具体产品:黄狗
* @Author: Ling.D.S
* @Date: Created in 2018/11/5 20:44
*/
public class YellowDog extends Dog {
public void get() {
System.out.println("获得黄狗");
}
}
BlackCat.java
/**
* @Description: 具体产品:黑猫
* @Author: Ling.D.S
* @Date: Created in 2018/11/5 20:46
*/
public class BlackCat extends Cat {
public void get() {
System.out.println("获得黑猫");
}
}
BlackDog.java
/**
* @Description: 具体产品:黑狗
* @Author: Ling.D.S
* @Date: Created in 2018/11/5 20:44
*/
public class BlackDog extends Dog {
public void get() {
System.out.println("获得黑狗");
}
}
5.测试类
MainClass.java
/**
* @Description: 主方法
* @Author: Ling.D.S
* @Date: Created in 2018/11/5 20:59
*/
public class MainClass {
public static void main(String[] args) {
AnimalFactory yFactory = new YellowFactory();
Animal yDog = yFactory.getDog();
yDog.get();
Animal yCat = yFactory.getCat();
yCat.get();
AnimalFactory bFactory = new BlackFactory();
Animal bDog = bFactory.getDog();
bDog.get();
Animal bCat = bFactory.getCat();
bCat.get();
}
}
结果:
五、抽象工厂模式和工厂方法模式的区别
抽象工厂是可以生产多个产品的,例如 YellowFactory里可以生产 YellowDog以及 YellowCat两个产品,而这两个产品又是属于一个系列的,因为它们都是属于Animal的子类。而工厂方法模式则只能生产一个产品,例如之前的 CatFactory 里就只可以生产一个 Cat产品。
示意图:
转载请注明原地址,宋德凌的博客:http://CoderOfSong.github.io 谢谢!