首页 > 代码库 > 2.1.2 工厂方法模式(3.3)

2.1.2 工厂方法模式(3.3)

工厂方法模式(factory method pattern)从2方面认识。

编程技巧:这是对参数化工厂方法加以改进的经典技术,以多态来重构if-else、switch-case等分支结构。

设计思路:你一定要注意,工厂方法模式中Client关注的不是的产品(所以静态工厂中Door的例子,不适合),Client关注的是工厂

1.以多态来重构分支结构

静态工厂的缺点是分支结构,需要增添新的分支时,程序不符合OCP。
package creational.factory;
public class DoorFactory{
    public static Door getObject(String typeName)	{//int ID
        if(typeName.equals("D1")){
            return new D1();
        }else if(typeName.equals("D2")){
            return new D2();
        }else{
            return null;
        }
    }
}

package creational.factory;
public class Hand{
    static Door d = null;    
    public static void test(){
        d = DoorFactory.getObject("D2")	;
        d.m();
    }
}
不使用配置文件和反射机制的情况下,

interface IDoorFactory {
	public Door createDoor();
}

class D1Factory implements IDoorFactory {
	public D1 createDoor() {
		return new D1();
	}
}//D2Factory 略


public class Client {
	public static void main(String[] args) {
		IDoorFactory factory = new D1Factory();
		Door door= factory.createDoor();//生产D1
		door.m();
	}
}
将工厂类泛化成抽象类型,以其子类多态地创建不同的产品如Door的子类。
它体现了一种非常重要的思考方式——以多态来重构if-else或switch-case结构。从重构分支结构的角度看,策略模式与[2.1.3工厂方法模式(3.3)]和[4.2状态模式(5.8)]是三胞胎。

2.颠倒黑白

从Client的角度看,IDoorFactory 除了符合三观和高大上外,很装逼。Client避免了依赖D1,变成了依赖D1Factory。如果Client的关注点是各种Door的话,上面的工厂方法模式的用法是生搬硬套。
反过来看,既然Client依赖D1Factory,不依赖D1,说明Client压根不希望对Door系列有太多的了解。
例如你开车ICar,不管什么车你都可以开。现在,Car要找它的4S店/I4S,你的关注点是各种4S店吗?


interface ICar{ //工厂接口	
	public I4S get4S();//管你是那个4S店
	public void move();
}
class BBCar implements ICar{
    public I4S get4S() {
        return new BB4S();
    }

    public void move(){
        System.out.println("BBCar move");
    }
}//QQCar 略

interface I4S{    
    void doShomthing();
}//实现类略
public class Client{
    public static void main(String[] args) {
		ICar car =new BBCar();
		car.move();
		I4S repair = car.get4S();
		repair.doShomthing();
		car.move();
	}
}

由于受通用工具类如God——反射+配置的压制,现在应用程序中使用工厂方法模式比较少见。
不使用配置文件的场合,如JDK的设计中广泛使用,典型例子:

public interface Iterable{

    Iterator iterator();//返回一个迭代器

}


2.1.2 工厂方法模式(3.3)