简介
工厂方法模式(Factory Method Pattern)又叫作多态性工厂模式,指定义一个创建对象的接口,但由实现这个接口的类来决定实例化哪个类,工厂方法把类的实例化推迟到子类中进行。
通用模板
-
创建抽象产品接口:是工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
java// 抽象产品接口 public interface IProduct { void doSomething(); }
-
创建具体产品类:这个角色实现了抽象产品角色所定义的接口。某具体产品由专门的具体工厂创建,它们之间往往一一对应。
java// 具体产品类B public class ProductB implements IProduct { public void doSomething() { System.out.println("ProductB..."); } }
java// 具体工厂类B public class FactoryB implements IFactory { public IProduct makeProduct() { return new ProductB(); } }
-
创建抽象工厂接口:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
java// 抽象工厂接口 public interface IFactory { IProduct makeProduct(); }
-
创建具体工厂类:是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且被应用程序调用以创建产品对象。
java// 具体工厂类A public class FactoryA implements IFactory { public IProduct makeProduct() { return new ProductA(); } }
java// 具体工厂类B public class FactoryB implements IFactory { public IProduct makeProduct() { return new ProductB(); } }
模板测试
-
代码
javapublic class Client { public static void main(String[] args) { IFactory factory = new FactoryA(); factory.makeProduct().doSomething(); factory = new FactoryB(); factory.makeProduct().doSomething(); } }
-
结果
javaProductA... ProductB...
应用场景
- 不知道实例化的具体类:当一个类无法预见它所必须创建的产品时,可以使用工厂方法模式。
- 希望用户扩展产品族:当希望由用户(如子系统)来指定具体的类时,可以使用工厂方法模式。这样可以允许用户在不修改原有代码的情况下增加新的功能。
- 多级产品结构:当一个类的实例只能由另一个紧密相关的对象创建时,可以使用工厂方法模式来创建不同等级结构的对象。
优点
- 遵循开闭原则:在工厂方法模式中,为每一个具体产品类都配置一个具体的工厂类,当增加新的产品类时,无需修改已有的工厂类代码,只需添加对应的具体产品类和具体工厂类即可。
- 封装性好:客户端只需知道产品的抽象类,而不需要知道具体的产品类是如何创建的。
- 灵活性强:每个具体工厂类都独立于其他的工厂类,增加了系统的灵活性和可扩展性。
缺点
- 增加系统类的数量:由于需要为每一个具体产品类都配置一个具体的工厂类,因此系统中类的个数会增加。
- 具体产品类依赖于对应的具体工厂类:如果具体产品类的创建逻辑发生改变,那么对应的工厂类也需要修改。
- 系统复杂数增加:随着具体产品类和具体工厂类的增加,系统将会变得更加复杂。
"生搬硬套"实战
场景描述
假设我们正在设计一个游戏,游戏中有多种类型的武器(Weapon),例如剑(Sword)和枪(Gun)。我们需要在游戏中根据玩家选择的角色来创建相应的武器对象。我们可以使用工厂方法模式来实现这一功能。
代码开发
根据模板我们知道工厂方法模式开发拢共就是4步:
-
创建抽象产品(这里只武器)接口
java// 抽象武器接口 public interface IWeapon { void attack(); }
-
创建具体产品(这里指剑、枪等武器)类
java// 具体武器类-剑 public class Sword implements IWeapon { public void attack() { System.out.println("用剑攻击!"); } }
java// 具体武器类-枪 public class Gun implements IWeapon { public void attack() { System.out.println("用枪攻击!"); } }
-
创建抽象工厂(这里指武器工厂)接口
java// 抽象武器工厂接口 public interface IWeaponFactory { IWeapon createWeapon(); }
-
创建具体工厂(这里指生产剑和枪的工厂)类
java// 具体生产剑的工厂类 public class SwordFactory implements IWeaponFactory { public IWeapon createWeapon() { return new Sword(); } }
java// 具体生产枪的工厂类 public class GunFactory implements IWeaponFactory { public IWeapon createWeapon() { return new Gun(); } }
至此,我们就通过"生搬硬套"工厂方法模式的模板设计出一套武器生产工厂,接下来我们进行测试:
-
测试代码
javapublic class Client { public static void main(String[] args) { IWeaponFactory factory = new SwordFactory(); factory.createWeapon().attack(); factory = new GunFactory(); factory.createWeapon().attack(); } }
-
结果
java用剑攻击! 用枪攻击!
总结
工厂方法模式主要适用于以下应用场景。
(1)创建对象需要大量重复的代码。
(2)客户端(应用层)不依赖产品类实例如何被创建、实现等细节。
(3)一个类通过其子类来指定创建哪个对象。