4、抽象工厂
4.1 介绍
- 抽象工厂模式(Abstract Factory)是对工厂的抽象化,而不只是制造方法
- 系统如果按工厂方法那样为每种产品都增加一个新工厂又会造成工厂泛滥
- 抽象工厂模式提供了另一种思路,将各种产品分门别类
- 基于此来规划各种工厂的制造接口,最终确立产品制造的顶级规范,使其与具体产品彻底脱钩
- 抽象工厂是建立在制造复杂产品体系需求基础之上的一种设计模式
- 在某种意义上,我们可以将抽象工厂模式理解为工厂方法模式的高度集群化升级版
- 测试类文件

4.2 品牌与系列(针对工厂泛滥)(分类)
- 产品多元化 --> 工厂泛滥 --> 产业规划与整合
- A品牌3系列 + B品牌3系列 + …
- 这便是抽象工厂模式的基础数据模型
- 分为品牌工厂,系列工厂
4.3 产品规划(数据模型)
- 无论哪种工厂模式,都一定是基于特定的产品特性发展而来的: 从产品建模切入(提取相同点,找出不同点)
- 例子(星际战争游戏)
- 分析规划(提取相同点,找出不同点)
- 建立数据模型
- 兵种顶层父类
package abstractFactory.entity.abstractt;
public abstract class Unit {
protected int attack;
protected int defence;
protected int health;
protected int x;
protected int y;
public Unit(int attack, int defence, int health, int x, int y) {
this.attack = attack;
this.defence = defence;
this.health = health;
this.x = x;
this.y = y;
}
public abstract void show();
public abstract void attack();
}
- 兵种等级: 各等级兵种类都继承自兵种抽象类Unit,它们对应的攻击力、防御力及生命力也各不相同
- 初级兵种类LowClassUnit
- 中级兵种类MidClassUnit
- 高级兵种类HighClassUnit
package abstractFactory.entity.abstractt;
public abstract class LowClassUnit extends Unit{
public LowClassUnit( int x, int y) {
super(5, 2, 35, x, y);
}
}
package abstractFactory.entity.abstractt;
public abstract class MidClassUnit extends Unit {
public MidClassUnit( int x, int y) {
super(10, 8, 80, x, y);
}
}
package abstractFactory.entity.abstractt;
public abstract class HighClassUnit extends Unit {
public HighClassUnit( int x, int y) {
super(25, 30, 300, x, y);
}
}
- 定义具体的兵种类
- 海军陆战队员类Marine
- 变形坦克类Tank
- 巨型战舰类Battleship
- 蟑螂类Roach
- 毒液类Poison
- 猛犸类Mammoth
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.LowClassUnit;
public class Marine extends LowClassUnit {
public Marine(int x, int y) {
super(x, y);
}
@Override
public void show() {
System.out.println("士兵出现在坐标:[" + x + "," + y + "]");
}
@Override
public void attack() {
System.out.println("士兵用机关枪射击,攻击力:" + attack);
}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.MidClassUnit;
public class Tank extends MidClassUnit {
public Tank(int x, int y) {
super(x, y);
}
@Override
public void show() {
System.out.println("坦克出现在坐标:[" + x + "," + y + "]");
}
@Override
public void attack() {
System.out.println("坦克用炮轰击,攻击力:" + attack);
}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.HighClassUnit;
public class Battleship extends HighClassUnit {
public Battleship(int x, int y) {
super(x, y);
}
@Override
public void show() {
System.out.println("战舰出现在坐标:[" + x + "," + y + "]");
}
@Override
public void attack() {
System.out.println("战舰用激光炮打击,攻击力:" + attack);
}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.LowClassUnit;
public class Roach extends LowClassUnit {
public Roach(int x, int y) {
super(x, y);
}
@Override
public void show() {
System.out.println("蟑螂兵出现在坐标:[" + x + "," + y + "]");
}
@Override
public void attack() {
System.out.println("蟑螂兵用爪子挠,攻击力:" + attack);
}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.MidClassUnit;
public class Poison extends MidClassUnit {
public Poison(int x, int y) {
super(x, y);
}
@Override
public void show() {
System.out.println("毒液兵出现在坐标:[" + x + "," + y + "]");
}
@Override
public void attack() {
System.out.println("毒液兵用毒液喷射,攻击力:" + attack);
}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.HighClassUnit;
public class Mammoth extends HighClassUnit {
public Mammoth(int x, int y) {
super(x, y);
}
@Override
public void show() {
System.out.println("猛犸巨兽出现在坐标:[" + x + "," + y + "]");
}
@Override
public void attack() {
System.out.println("猛犸巨兽用獠牙顶,攻击力:" + attack);
}
}
- 所有兵种类已定义完毕,代码不是难点,重点集中在对兵种的划分上
- 横向划分族,纵向划分等级(系列),利用类的抽象与继承描绘出所有的游戏角色以及它们之间的关系,同时避免了不少重复代码
4.4 生产线规划(工厂类)
- 数据模型构建完成,定义工厂,建立生产线
- 定义了6个兵种产品(数据模型):实体
- 可分为2个工厂:人族、怪兽族
- 3个制造标准:3个等级
- 定义抽象工厂接口:
package abstractFactory.factory;
import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
public interface AbstractFactory {
LowClassUnit createLowClassUnit();
MidClassUnit createMidClassUnit();
HighClassUnit createHighClassUnit();
}
package abstractFactory.factory.impl;
import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
import abstractFactory.entity.product.Battleship;
import abstractFactory.entity.product.Marine;
import abstractFactory.entity.product.Tank;
import abstractFactory.factory.AbstractFactory;
public class HumanFactory implements AbstractFactory {
private int x;
private int y;
public HumanFactory(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public LowClassUnit createLowClassUnit() {
LowClassUnit unit = new Marine(x, y);
System.out.println("制造海军陆战队员成功。");
return unit;
}
@Override
public MidClassUnit createMidClassUnit() {
MidClassUnit unit = new Tank(x, y);
System.out.println("制造变形坦克成功。");
return unit;
}
@Override
public HighClassUnit createHighClassUnit() {
HighClassUnit unit = new Battleship(x, y);
System.out.println("制造巨型战舰成功。");
return unit;
}
}
package abstractFactory.factory.impl;
import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
import abstractFactory.entity.product.Mammoth;
import abstractFactory.entity.product.Poison;
import abstractFactory.entity.product.Roach;
import abstractFactory.factory.AbstractFactory;
public class AlienFactory implements AbstractFactory {
private int x;
private int y;
public AlienFactory(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public LowClassUnit createLowClassUnit() {
LowClassUnit roach = new Roach(x, y);
System.out.println("制造蟑螂兵成功。");
return roach;
}
@Override
public MidClassUnit createMidClassUnit() {
MidClassUnit poison = new Poison(x, y);
System.out.println("制造毒液兵成功。");
return poison;
}
@Override
public HighClassUnit createHighClassUnit() {
HighClassUnit mammoth = new Mammoth(x, y);
System.out.println("制造猛犸巨兽成功。");
return mammoth;
}
}
- 生产线规划非常清晰
- 人类兵工厂与外星母巢分别实现了3个等级兵种的制造方法
- 其中前者由低到高分别返回海军陆战队员、变形坦克以及巨型战舰对象,
- 后者则分别返回蟑螂兵、毒液兵以及猛犸巨兽对象
- 测试使用
- 抽象兵工厂接口引用了人类兵工厂实现
- 调用3个等级的制造方法分别得到人类族的对应兵种
- 将抽象兵工厂接口引用替换为外星母巢实现
- 制造出的兵种变为3个等级的外星怪兽族兵种
- 如果玩家需要一个新族加入,我们可以在此模式之上去实现一个新的族工厂并实现3个等级的制造方法
- 工厂一经替换即可产出各系列产品兵种,且无须改动现有代码,良好的可扩展性
- 这就是一套拥有完备生产模式的标准化工业系统所带来的好处
package abstractFactory;
import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
import abstractFactory.entity.abstractt.Unit;
import abstractFactory.factory.AbstractFactory;
import abstractFactory.factory.impl.AlienFactory;
import abstractFactory.factory.impl.HumanFactory;
public class Client {
public static void main(String[] args) {
System.out.println("游戏开始......");
System.out.println("双方挖掘攒钱......");
System.out.println("建造人类族工厂.......");
AbstractFactory factory = new HumanFactory(10, 10);
Unit marine = factory.createLowClassUnit();
marine.show();
Unit tank = factory.createMidClassUnit();
tank.show();
Unit ship = factory.createHighClassUnit();
ship.show();
System.out.println("建造外星怪兽族工厂");
factory = new AlienFactory(200, 200);
Unit roach = factory.createLowClassUnit();
roach.show();
Unit poison = factory.createMidClassUnit();
poison.show();
Unit mammoth = factory.createHighClassUnit();
mammoth.show();
System.out.println("两族开始混战......");
marine.attack();
roach.attack();
poison.attack();
tank.attack();
mammoth.attack();
ship.attack();
}
}
4.5 分而治之
- 抽象工厂制造模式已经布局完成,各工厂可以随时大规模投入生产活动了
- 我们还可以进一步,再加一个“制造工厂的工厂”来决定具体让哪个工厂投入生产活动
- 此时客户端就无须关心工厂的实例化过程了,直接使用产品就可以了
- 这也是抽象工厂可以被视为“工厂的工厂”的原因
- 与工厂方法模式不同,抽象工厂模式能够应对更加复杂的产品族系,它更类似于一种对“工业制造标准”的制定与推行
- 各工厂实现都遵循此标准来进行生产活动
- 以工厂类划分产品族(工厂类)
- 以制造方法划分产品系列(数据模型)
- 达到无限扩展产品的目的
4.6 抽象工厂模式的各角色定义如下
- 产品系列的抽象类:
- AbstractProduct1、AbstractProduct2(抽象产品1、抽象产品2)
- 一系产品与二系产品分别代表同一产品族的多个产品系列,对应本章例程中的初级、中级、高级兵种抽象类
- 继承自抽象产品的产品实体类(数据模型)
- ProductA1、ProductB1、ProductA2、ProductB2(产品A1、产品B1、产品A2、产品B2)
- 其中ProductA1与ProductB1代表A族产品与B族产品的同一产品系列,类似于例中人类族与外星怪兽族的初级兵种
- 抽象工厂接口(AbstractFactory)
- 各族工厂的高层抽象,可以是接口或者抽象类
- 抽象工厂对各产品系列的制造标准进行规范化定义,但具体返回哪个族的产品由具体族工厂决定,它并不关心。
- 工厂实现类:
- ConcreteFactoryA、ConcreteFactoryB(工厂A实现、工厂B实现)
- 继承自抽象工厂的各族工厂,需实现抽象工厂所定义的产品系列制方法,可以扩展多个工厂实现。
- 对应本章例程中的人类兵工厂与外星母巢
- Client(客户端):
- 产品的使用者,只关心制造出的产品系列,具体是哪个产品族由工厂决定
4.7 基于此抽象工厂模式以品牌与系列进行全局规划
- 抽象工厂模式一定是基于产品的族系划分来布局的
- 其产品系列一定是相对固定的
- 故以抽象工厂来确立工业制造标准(各产品系列生产接口)
- 而产品族则可以相对灵活多变