上文我们说到的工厂方法模式对单一产品类型而言是非常试用的,但是当遇到多产品类型的时候,就有点力不从心了,这时就要使用到本文中所讲的抽象工厂模式。
学工厂类设计模式我们经常看到两个名词:产品等级结构和产品族。这里我们举例解释一下。冰箱是一种产品,有海尔、美的等多个品牌,这叫产品等级结构,也就是我们说到单一产品类型。同时海尔旗下还有海尔热水器,海尔洗衣机,这叫产品族,也就是我们说的多产品类型。
产品等级结构使用工厂方法模式,产品族使用抽象工厂模式。
1.基本定义
抽象工厂模式是(Abstract Factory),为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。类型是创建型模式。
1.1优点
- 具体产品在应用层代码隔离,无需关心产品创建的细节。
- 将一个系列的产品统一封装到一起创建。
1.2缺点
- 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。
- 增加了系统的抽象性和理解难度。
2.coding
本文以游戏中的青龙套装,玄武套装作为背景说明抽象工厂模式。套装包括武器和护具,我们暂定有刀和头盔,他们都是单一的产品等级结构,青龙套装、玄武套装是产品族。下面用程序语言模拟这个关系。
2.1 v0.1版
创建产品类(接口或者抽象类)
兵器类
package com.xxfamly.creational.absfactory;
/**
* 兵器
*/
public interface Weapon {
/**
* 发动攻击
*/
public void attack();
}
头盔类
package com.xxfamly.creational.absfactory;
/**
* 头盔
*/
public interface Helmet {
/**
* 防护
*/
public void protect();
}
武器套装工厂类:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类
package com.xxfamly.creational.absfactory;
/**
* 武器装备接口
*/
public interface Equipment {
/**
* 创建头盔
* @return
*/
public Helmet createHelmet();
/**
* 创建兵器
* @return
*/
public Weapon createWeapon();
}
具体的产品类:
青龙头盔和青龙偃月刀
package com.xxfamly.creational.absfactory;
public class QingLongHelmet implements Helmet {
QingLongHelmet(){
System.out.println("青龙头盔打造完成");
}
@Override
public void protect() {
System.out.println("青龙头盔防护开启");
}
}
package com.xxfamly.creational.absfactory;
public class QingLongWeapon implements Weapon {
QingLongWeapon(){
System.out.println("青龙偃月刀打造完成");
}
@Override
public void attack() {
System.out.println("青龙偃月刀发起攻击");
}
}
青龙套装
package com.xxfamly.creational.absfactory;
/**
* 青龙套装
*/
public class QingLongEquipment implements Equipment {
@Override
public Helmet createHelmet() {
return new QingLongHelmet();
}
@Override
public Weapon createWeapon() {
return new QingLongWeapon();
}
}
玄武头盔和玄武大刀
package com.xxfamly.creational.absfactory;
public class XuanWuHelmet implements Helmet {
XuanWuHelmet(){
System.out.println("玄武头盔打造完成");
}
@Override
public void protect() {
System.out.println("玄武头盔开启防护");
}
}
package com.xxfamly.creational.absfactory;
public class XuanWuWeapon implements Weapon {
XuanWuWeapon(){
System.out.println("玄武大刀打造完成");
}
@Override
public void attack() {
System.out.println("玄武大刀发起攻击");
}
}
玄武套装
package com.xxfamly.creational.absfactory;
public class XuanWuEquipment implements Equipment {
@Override
public Helmet createHelmet() {
return new XuanWuHelmet();
}
@Override
public Weapon createWeapon() {
return new XuanWuWeapon();
}
}
客户端类
package com.xxfamly.creational.absfactory;
/**
* 模拟客户端类
*/
public class Client {
public static void main(String[] args){
Equipment equipment = null;
//打造青龙套装
equipment = new QingLongEquipment();
equipment.createHelmet().protect();
equipment.createWeapon().attack();
//打造玄武套装
equipment = new XuanWuEquipment();
equipment.createHelmet().protect();
equipment.createWeapon().attack();
}
}
运行结果
青龙头盔打造完成
青龙头盔防护开启
青龙偃月刀打造完成
青龙偃月刀发起攻击
玄武头盔打造完成
玄武头盔开启防护
玄武大刀打造完成
玄武大刀发起攻击
Process finished with exit code 0
UML类图
抽象工厂模式很好的隐藏了产品创建的细节,并且可以统一创建产品。如果现在要扩展一个产品,比如套装中增加盔甲,那么抽象工厂模式的缺点就显示出来了:规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。
2.2 v0.2版
增加盔甲抽象产品类
package com.xxfamly.creational.absfactory;
/**
* 盔甲
*/
public interface Armor {
/**
* 防护
*/
public void protect();
}
修改核心抽象工厂接口,添加创建盔甲产品
package com.xxfamly.creational.absfactory;
/**
* 武器装备接口
*/
public interface Equipment {
/**
* 创建头盔
* @return
*/
public Helmet createHelmet();
/**
* 创建盔甲
* @return
*/
public Armor createArmor();
/**
* 创建兵器
* @return
*/
public Weapon createWeapon();
}
增加具体的产品类,青龙盔甲和玄武盔甲
package com.xxfamly.creational.absfactory;
public class QingLongArmor implements Armor {
QingLongArmor(){
System.out.println("青龙盔甲打造完成");
}
@Override
public void protect() {
System.out.println("青龙盔甲开启防护");
}
}
package com.xxfamly.creational.absfactory;
public class XuanWuArmor implements Armor {
XuanWuArmor(){
System.out.println("玄武盔甲打造完成");
}
@Override
public void protect() {
System.out.println("玄武盔甲开启防护");
}
}
修改具体的工厂类
package com.xxfamly.creational.absfactory;
/**
* 青龙套装
*/
public class QingLongEquipment implements Equipment {
@Override
public Helmet createHelmet() {
return new QingLongHelmet();
}
@Override
public Armor createArmor() {
return new QingLongArmor();
}
@Override
public Weapon createWeapon() {
return new QingLongWeapon();
}
}
package com.xxfamly.creational.absfactory;
public class XuanWuEquipment implements Equipment {
@Override
public Helmet createHelmet() {
return new XuanWuHelmet();
}
@Override
public Armor createArmor() {
return new XuanWuArmor();
}
@Override
public Weapon createWeapon() {
return new XuanWuWeapon();
}
}
修改客户端类
package com.xxfamly.creational.absfactory;
/**
* 模拟客户端类
*/
public class Client {
public static void main(String[] args){
Equipment equipment = null;
//打造青龙套装
equipment = new QingLongEquipment();
equipment.createArmor().protect();
equipment.createHelmet().protect();
equipment.createWeapon().attack();
//打造玄武套装
equipment = new XuanWuEquipment();
equipment.createArmor().protect();
equipment.createHelmet().protect();
equipment.createWeapon().attack();
}
}
运行结果
青龙盔甲打造完成
青龙盔甲开启防护
青龙头盔打造完成
青龙头盔防护开启
青龙偃月刀打造完成
青龙偃月刀发起攻击
玄武盔甲打造完成
玄武盔甲开启防护
玄武头盔打造完成
玄武头盔开启防护
玄武大刀打造完成
玄武大刀发起攻击
Process finished with exit code 0
UML类图