Factory Method模式
如果将Template Method模式用于生成实例,它就会演变为Factory Method模式。
在Factory Method模式中,父类决定实例的生成方式,但不决定所要生成的具体类,具体的类全部交个子类处理。这样就可以将生成实例的framework和实际负责生成实例类解耦。
实现
Product.java
public abstract class Product {
public abstract void use();
}
Factory.java
public abstract class Factory {
public final Product create(String owner) {
Product p = createProduct(owner);
registerProduct(p);
return p;
}
protected abstract Product createProduct(String owner);
protected abstract void registerProduct(Product product);
}
IDCard.java
public class IDCard extends Product {
private String owner;
// 包外的类无法new出实例
IDCard(String owner) {
System.out.println("制作" + owner + "的ID卡。");
this.owner = owner;
}
public void use() {
System.out.println("使用" + owner + "的ID卡。");
}
public String getOwner() {
return owner;
}
}
IDCardFactory.java
public class IDCardFactory extends Factory {
private List owners = new ArrayList();
protected Product createProduct(String owner) {
return new IDCard(owner);
}
protected void registerProduct(Product product) {
owners.add(((IDCard)product).getOwner());
}
public List getOwners() {
return owners;
}
}
登场角色
Produce(产品):属于框架一方的角色,是一个抽象类,定义了Factory Method模式中生成的那些实例所持用的接口。
Creator(创建者):属于框架一方的角色,负责生成Produce角色的抽象类。
ConcreteProduce(具体的产品):属于具体加工一方的角色,决定了具体的产品。
ConcreteCreator(具体的创建者):属于具体加工一方的角色,负责生成具体的产品。
要点思考
在Creator角色中不用new
关键字来生成实例,而是调用生成实例的专用方法来生成实例,这样就可以防止父类与其他具体类耦合。
生成实例-方法的三种实现方式
- 指定其为抽象类,要求子类必须实现该方法(本例所示)。
- 为其实现默认处理,如果子类没有实现该方法,将进行默认处理(通过
new
关键字创建实例,此时Produce角色不能被定义为抽象类)。 - 在其中抛出异常(即默认处理为抛出异常,这样如果子类未实现该方法,程序运行时就会出错)。
不论Template Method模式还是Factory Method模式,如果仅阅读一个类的代码,是很难理解这个类的行为的。必须理解父类中所定义的处理的框架和它里面所使用的抽象方法,以及了解这些抽象方法在子类中的实现才行。因此要求我们一定要留有开发文档,记录所使用的设计模式的名称和意图,以向维护这些类的开发人员正确地传达设计这些设计模式的意图。
示例代码出自《图解设计模式》 结城浩