一、模式名
工厂方法, Factory Method
二、解决的问题
工厂方法,顾名思义,就是类似于工厂的方法,而工厂具有什么特点呢?我们都知道工厂可以批量生产某类商品,而设计模式正是借用了这个特点。工厂方法模式可以用于统一生成某类对象。将对象的生成统一到工厂方法中,当新增某类对象时,可以增加新对象类和对应的工厂类即可实现扩展,提高了程序的可扩展性。
三、解决方案
工厂方法分为简单工厂方法和工厂方法。
1. 简单工厂方法
简单工厂方法的UML图如下所示。
代码如下
interface Product { void method1(); } class ProductA implements Product { @Override public void method1() { System.out.println("ProductA"); } } class ProductB implements Product { @Override public void method1() { System.out.println("ProductB"); } } class ProductFactory { Product createProduct(int type) { if (type == 1) { return new ProductA(); } else if (type == 2) { return new ProductB(); } return null; } } public class Client { public static void main(String[] args) { ProductFactory productFactory = new ProductFactory(); Product productA = productFactory.createProduct(1); productA.method1(); Product productB = productFactory.createProduct(2); productB.method1(); } }
可以看到,定义一个Product接口,再分别定义两个实现类ProductA和ProductB实现该接口。最后定义一个工厂,里面创建一个对象生成方法,用于根据输入参数生成对应的对象。
简单工厂方法的优点是将所有对象的生成都放到了工厂方法中,易于管理和获取对象。缺点是每增加一个新的实现类时,除了添加一个实现类外,还需要修改工厂方法,这样不符合"对扩展开放,对修改关闭"的设计原则。所以提出了工厂方法,工厂方法增加一个工厂接口,每个具体的产品实现类都需要定义其对应的工厂类,用于对应对象的生成,这样每增加一个产品实现类时,只需要新增两个类,不需要修改原有代码。
2. 工厂方法
工厂方法的UML图如下所示。
代码如下
interface Product { void method1(); } interface ProductFactory { Product createProduct(); } class ProductA implements Product { @Override public void method1() { System.out.println("ProductA"); } } class ProductAFactoryA implements ProductFactory { @Override public Product createProduct() { return new ProductA(); } } class ProductB implements Product { @Override public void method1() { System.out.println("ProductB"); } } class ProductAFactoryB implements ProductFactory { @Override public Product createProduct() { return new ProductB(); } } public class FactoryMethodClient { public static void main(String[] args) { ProductAFactory productAFactoryA = new ProductAFactoryA(); Product productA = productAFactoryA.createProduct(); productA.method1(); ProductAFactory productAFactoryB = new ProductAFactoryB(); Product productB = productAFactoryB.createProduct(); productB.method1(); } }
可以看到,每个产品具体类都对应一个工厂类,用于生成对应的产品类对象。以后需要新增产品类时,只需要新增产品类和对应的工厂类即可,不需要修改原有代码。