一、介绍
今天,我们来回顾一下工厂方法模式,这个模式很简单。
《研磨设计模式》中的定义是:定义一个用于创建对象的接口,让子类决定实例化哪个类,“Factory Mehod”使一个类的实例化延迟到子类。
工厂方法模式的本质是——延迟到子类来选择实现
什么意思呢?简单来说,就是面向接口编程。
打个比方,我现在需要一个水果类,就可以直接写一个简单的水果接口 interface Fruit{},至于实现类是什么,我不关心。直接使用这个接口就是了,反正java对象是运行时绑定。怎么使用这个接口呢,当然是抽象方法了。这样,不同的子类继承的时候就可以选择不同的实现类。
二、结构
1、Product——需要创建的对象的接口。
2、ConcreteProduct——需要创建的对象的实现类。
3、Creator——工厂方法接口,有一个返回所需对象的抽象方法,留给子类选择实现。也可以提供默认的实现。
4、ConcreteCreator——工厂方法实现类。用来提供具体的选择实现。
三、我的实现
1、首先我们有一个简单的产品接口和它的2个实现,如下:
package factoryMethod; public interface Product { public void autoFly(); }
package factoryMethod; public class ProductImpl1 implements Product{ public void autoFly() { // TODO Auto-generated method stub System.out.println("product1 is flying!"); } }
package factoryMethod; public class ProductImpl2 implements Product{ public void autoFly() { // TODO Auto-generated method stub System.out.println("product2 is flying!"); } }
2、我们建立了一个工厂,使用这个工厂,就可以实现产品的功能。
package factoryMethod; public abstract class MyFactory { protected abstract Product getMyProduct(); public void fly(){ getMyProduct().autoFly(); } }
如上,我们编写的这个工厂为一个抽象类,我们不知道它的具体实现,但是它已经完成了逻辑调用。它的具体调用,留到子类去实现。
3、那么我们编写2个工厂子类,如下:
package factoryMethod; public class Factory1 extends MyFactory { @Override protected Product getMyProduct() { // TODO Auto-generated method stub return new ProductImpl1(); } }
package factoryMethod; public class Factory2 extends MyFactory { @Override protected Product getMyProduct() { // TODO Auto-generated method stub return new ProductImpl2(); } }
如上,工厂的子类只需要实现父类没有完成功能,而无需改变父类的基本功能。
4、那么客户端调用如下:
package factoryMethod; public class Client { public static void main(String[] args) { MyFactory factory = new Factory1(); factory.fly(); } }
如上,我们是直接通过工厂来调用产品功能,工厂本身并不负责选择实现。选择实现是简单工厂模式的本质。
我们可以看到,工厂方法模式是通过工厂类简单的抽象来实现的。
如果我们需要创建某个接口的对象,但是又不知道具体的实现,那么我们可以使用工厂方法模式。
5、另外,工厂方法模式还有另一种用法,那就是工厂类本身有默认的实现,这种情况下,工厂类可以构造为普通类,而不是抽象类。如下:
package factoryMethod; public class NewFactory { protected Product getMyProduct() { // TODO Auto-generated method stub return new ProductImpl1(); } public void fly() { getMyProduct().autoFly(); } }
6、然后,当我们需要另一个产品的时候,就可以继承NewFactory,重写getMyProduct()方法,如下:
package factoryMethod; public class SonOfNewFacory1 extends NewFactory{ @Override protected Product getMyProduct() { // TODO Auto-generated method stub return new ProductImpl2(); } }
客户端调用就毋须演示了。
7、同样,工厂方法模式可以与简单工厂模式结合起来,在工厂方法模式中选择实现。如下:
package factoryMethod; public class FunctionFactory { protected Product getMyProduct(int type) { Product product = null; if (type == 1) { product = new ProductImpl1(); } else { product = new ProductImpl2(); } return product; } public void fly(int type) { getMyProduct(type).autoFly(); } }
8、如果需要添加一个新的实现,《研磨设计模式》中提到了一种优雅的方式,如下:
package factoryMethod; public class SonOfFunctionFactory1 extends FunctionFactory { @Override protected Product getMyProduct(int type) { // TODO Auto-generated method stub if (type == 3) { return new ProductImpl3(); } //其他的让父类去实现 return super.getMyProduct(type); } }