简介
抽象工厂模式(Abstract Factory Pattern)指提供一个创建一系列相关或相互依赖对象的接口,无须指定它们具体的类。意思是客户端不必指定产品的具体类型,创建多个产品族中的产品对象。
与工厂方法模式相比,抽象工厂模式可以创建一组相关的对象,而不是单一的对象。
通用模板
-
创建抽象产品接口:为一类产品对象声明一个接口。
java// 抽象产品接口A public interface IProductA { void doA(); }
java// 抽象产品接口B public interface IProductB { void doB(); }
-
创建具体产品类:定义一个将被相应的具体工厂创建的产品对象,实现AbstractProduct接口。
java// 产品族A的具体产品A public class ProductAWithFamilyA implements IProductA { public void doA() { System.out.println("产品族A生产的的具体产品A..."); } }
java// 产品族A的具体产品B public class ProductBWithFamilyA implements IProductB { public void doB() { System.out.println("产品族A生产的的具体产品B..."); } }
java// 产品族B的具体产品A public class ProductAWithFamilyB implements IProductA { public void doA() { System.out.println("产品族B生产的的具体产品A..."); } }
java// 产品族B的具体产品A public class ProductBWithFamilyB implements IProductB { public void doB() { System.out.println("产品族B生产的的具体产品B..."); } }
-
创建抽象工厂接口:声明创建抽象产品对象的一个操作接口。
java// 抽象工厂接口 public interface IFactory { IProductA makeProductA(); IProductB makeProductB(); }
-
创建具体工厂类:实现创建具体产品对象的操作。
java// 具体工厂A public class FactoryA implements IFactory{ public IProductA makeProductA() { return new ProductAWithFamilyA(); } public IProductB makeProductB() { return new ProductBWithFamilyA(); } }
java// 具体工厂B public class FactoryB implements IFactory { public IProductA makeProductA() { return new ProductAWithFamilyB(); } public IProductB makeProductB() { return new ProductBWithFamilyB(); } }
模板测试
-
代码
javapublic class Client { public static void main(String[] args) { IFactory factory = new FactoryA(); factory.makeProductA().doA(); factory.makeProductB().doB(); factory = new FactoryB(); factory.makeProductA().doA(); factory.makeProductB().doB(); } }
-
结果
java产品族A生产的的具体产品A... 产品族A生产的的具体产品B... 产品族B生产的的具体产品A... 产品族B生产的的具体产品B...
应用场景
- 产品族:当一个系统需要一组相关的产品对象,即需要一个产品族时,可以使用抽象工厂模式。
- 产品系列独立:当产品系列中的产品是完全独立的时候,即一个系列的产品中的某个产品变更不会影响到其他系列产品时,可以考虑使用抽象工厂模式。
- 细节隐藏:当系统需要屏蔽具体的实现细节,只向客户端暴露接口时,可以使用抽象工厂模式。
优点
- 封装变体:抽象工厂模式将创建相关对象的过程封装在一个工厂类中,这样可以避免客户端代码直接依赖于具体的实现类。
- 高内聚,低耦合:抽象工厂模式可以提高系统的内聚性,降低各个模块之间的耦合度,使系统更容易扩展和维护。
- 易于交换产品系列:在抽象工厂模式中,可以通过改变具体工厂类来改变整个产品系列,而不需要修改客户端代码。
"生搬硬套"实战
场景描述
假设我们正在设计一个游戏,游戏中有多个种族(Race),每个种族都有其独特的武器(Weapon)和防具(Armor)。我们需要在游戏中根据玩家选择的种族来创建相应的武器和防具对象。我们可以使用抽象工厂模式来实现这一功能。
代码开发
根据模板我们知道抽象工厂和工厂方法模式一样也是拢共就是4步:
我们直观比较一下两种模式区别:
(1)抽象工厂模式中产品接口变多了,每个产品都有单独的接口
(2)抽象工厂模式中工厂接口中方法变多了,创建一组相关的对象,而不是单一的对象
-
创建抽象产品(这里包括武器和防具)接口
java// 武器接口 public interface IWeapon { void attack(); }
java// 防具接口 public interface IArmor { void defend(); }
-
创建具体产品(这里指为每个种族实现具体的武器和防具类)类
java// 人类具体武器类 public class HumanWeapon implements IWeapon{ public void attack() { System.out.println("人类武器攻击!"); } }
java// 人类具体防御类 public class HumanArmor implements IArmor { public void defend() { System.out.println("人类防具防御!"); } }
java// 精灵具体武器类 public class ElfWeapon implements IWeapon{ public void attack() { System.out.println("精灵武器攻击!"); } }
java// 精灵具体防御类 public class ElfArmor implements IArmor{ public void defend() { System.out.println("精灵防具防御!"); } }
-
创建抽象工厂(这里指生产武器和防具的工厂)接口
java// 生产设备的工厂接口 public interface IEquipmentFactory { IWeapon createWeapon(); IArmor createArmor(); }
-
创建具体工厂(这里指为每个种族实现具体的工厂类)类
java// 人类工厂 public class HumanFactory implements IEquipmentFactory{ public IWeapon createWeapon() { return new HumanWeapon(); } public IArmor createArmor() { return new HumanArmor(); } }
java// 精灵工厂 public class ElfFactory implements IEquipmentFactory{ public IWeapon createWeapon() { return new ElfWeapon(); } public IArmor createArmor() { return new ElfArmor(); } }
至此,我们就通过"生搬硬套"抽象工厂模式的模板设计出一套武器和防具生产工厂,接下来我们进行测试:
-
测试代码
javapublic class Client { public static void main(String[] args) { // 创建人类工厂 IEquipmentFactory humanFactory = new HumanFactory(); IWeapon humanWeapon = humanFactory.createWeapon(); IArmor humanArmor = humanFactory.createArmor(); humanWeapon.attack(); // 输出:人类武器攻击! humanArmor.defend(); // 输出:人类防具防御! // 创建精灵工厂 IEquipmentFactory elfFactory = new ElfFactory(); IWeapon elfWeapon = elfFactory.createWeapon(); IArmor elfArmor = elfFactory.createArmor(); elfWeapon.attack(); // 输出:精灵武器攻击! elfArmor.defend(); // 输出:精灵防具防御! } }
-
结果
text人类武器攻击! 人类防具防御! 精灵武器攻击! 精灵防具防御!
总结
在抽象工厂模式中,客户端(应用层)不依赖产品类实例如何被创建、实现等细节,强调一系列相关的产品对象(属于同一产品族)一起创建对象,需要大量重复的代码。 需要提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖具体实现。