简单工厂模式
简介
简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern),简单来说,简单工厂模式有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式。简单工厂模式不在GoF 23种设计模式之列。
通用模板
-
创建抽象产品接口:是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
// 抽象产品 public interface IProduct { void doSomething(); }
-
创建具体产品类:是简单工厂模式的创建目标。
// 具体产品ProductA public class ProductA implements IProduct { public void doSomething() { System.out.println("ProductA..."); } }
// 具体产品ProductB public class ProductB implements IProduct { public void doSomething() { System.out.println("ProductB..."); } }
-
创建简单工厂类:是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
public class SimpleFactory { public static final int PRODUCT_A = 0; public static final int PRODUCT_B = 1; public static IProduct makeProduct(int product) { switch (product) { case PRODUCT_A: return new ProductA(); case PRODUCT_B: return new ProductB(); } return null; } }
模板测试
-
代码
public class Client { public static void main(String[] args) { IProduct iProduct = SimpleFactory.makeProduct(0); assert iProduct != null; iProduct.doSomething(); } }
-
结果
ProductA...
应用场景
- 当工厂类负责创建的对象比较少时:因为每增加一个产品就需要修改工厂类的判断逻辑,所以如果产品种类不多,可以考虑使用简单工厂模式。
- 客户端只知道传入工厂类的参数:客户端并不知道具体要创建哪一个类的对象,只负责传递相关的参数给工厂类。
- 具体产品类的创建算法相似:如果创建各种产品类的逻辑非常相似,那么可以通过一个简单的工厂方法来实现。
优点
- 封装性:简单工厂将对象的创建过程封装起来,使得客户端不需要关心具体对象的创建过程。
- 扩展性:当系统需要增加新的产品时,可以通过修改工厂类来实现,客户端代码不需要改变。
- 简化接口:对于客户端来说,只需要调用工厂类中的静态方法即可获取到所需的产品对象,这使得客户端代码更简洁。
缺点
- 不符合开闭原则:当增加新产品时,需要修改工厂类中的逻辑,这违反了“对扩展开放,对修改关闭”的原则。
- 判断逻辑集中:所有的判断逻辑都在工厂内部实现,如果产品种类较多,那么工厂会变得臃肿且难以维护。
- 类型安全问题:如果传给工厂的方法参数有误,可能会导致类型转换异常。
“生搬硬套”实战
场景描述
假设我们在做一个游戏,游戏中有不同的武器(Weapon),比如剑(Sword)、枪(Gun)。每种武器都有攻击的方法。我们需要在游戏中根据玩家的选择来创建相应的武器对象。
代码开发
我们知道使用简单工厂模式拢共就三步:
-
创建抽象产品(这里指武器)接口:
// 武器接口 public interface IWeapon { void attack(); }
-
创建具体产品(就是剑、抢等武器)类:
// 具体武器类-剑 public class Sword implements IWeapon{ public void attack() { System.out.println("用剑攻击!"); } }
// 具体武器类-枪 public class Gun implements IWeapon{ public void attack() { System.out.println("用枪攻击!"); } }
-
创建简单工厂(这里指生产武器的工厂)类:
public class WeaponFactory { public static final int WEAPON_SWORD = 0; public static final int WEAPON_GUN = 1; public static IWeapon createWeapon(int type) { switch (type) { case WEAPON_SWORD: return new Sword(); case WEAPON_GUN: return new Gun(); } return null; } }
至此,我们就通过“生搬硬套”简单工厂模式的模板设计出一套武器生产工厂,接下来我们进行测试:
-
测试代码
public class Client { public static void main(String[] args) { IWeapon weapon = WeaponFactory.createWeapon(0); assert weapon != null; weapon.attack(); } }
-
结果
用剑攻击!
总结
对于产品种类相对较少的情况,考虑使用简单工厂模式可以很方便地创建所需产品。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑。