图解设计模式之Factory Method模式
示例程序
示例为制作身份证的程序
Product类和Factory类组成了生成实例的框架;IDCard类和IDCardFactory类负责实际的加工及处理。该程序的UML图如下:
Product 类
package FactoryMethod.framework;
public abstract class Product {
public abstract void use();
}
Factory 类
package FactoryMethod.framework;
public abstract class Factory {
// Template Method
public final Product create(String owner){
Product product = createProduct(owner);
registerProduct(product);
return product;
}
protected abstract Product createProduct(String owner);
protected abstract void registerProduct(Product product);
}
IDCard 类
package FactoryMethod.idcard;
import FactoryMethod.framework.*;
public class IDCard extends Product {
private String owner;
IDCard(String owner) {
System.out.println("制作" + owner + "的ID卡");
this.owner = owner;
}
@Override
public void use() {
System.out.println("使用" + owner + "的ID卡");
}
public String getOwner(){
return this.owner;
}
}
IDCardFactory 类
package FactoryMethod.idcard;
import FactoryMethod.framework.*;
import java.util.ArrayList;
import java.util.List;
public class IDCardFactory extends Factory {
private List<String> owners = new ArrayList<>();
@Override
protected Product createProduct(String owner) {
return new IDCard(owner);
}
@Override
protected void registerProduct(Product product) {
owners.add(((IDCard)product).getOwner());
}
public List getOwners(){
return owners;
}
}
Main
package FactoryMethod;
import FactoryMethod.framework.Factory;
import FactoryMethod.framework.Product;
import FactoryMethod.idcard.IDCardFactory;
public class Main {
public static void main(String[] args) {
Factory factory = new IDCardFactory();
Product card1 = factory.create("小明");
Product card2 = factory.create("小红");
Product card3 = factory.create("小王");
card1.use();
card2.use();
card3.use();
}
}
程序输出结果如下:
制作小明的ID卡
制作小红的ID卡
制作小王的ID卡
使用小明的ID卡
使用小红的ID卡
使用小王的ID卡
Factory Method模式中的角色
Product
Product角色属于框架的一方,属于抽象类;示例程序中由Product类扮演这一个角色
Creator
Creator角色属于框架的一方,是负责生成Product角色的抽象类。示例程序中由Factory类扮演这一角色。
ConcreteProduct
ConcreteProduct 角色是具体的产品类,示例程序中由IDCard类扮演这一个角色。
ConcreteCreator
ConcreteCreator 角色是具体加工产品的类,示例程序由IDCardFactory扮演这一角色。同时,在示例程序中,IDCardFactory与IDCard类使用了模板方法模式。
Factory Method模式的UML
对于Factory Method模式的思考
为什么使用Factory Method模式,Factory Method模式有什么优点?
第一点:
框架与具体加工是分开的。拿示例程序举例:在framework包中,只有Factory和Product抽象类,具体加工则由继承他们的IDCardFactory与IDCard类来实现。试想如果出现了新的类型的产品,比如Battery或者是Cap等Product。我们无需对framework包里的内容进行任何的修改,也就是说,framework包不依赖于idcard包。实现了低耦合。
第二点:
在Factory Method模式中,工厂方法用来创建客户所需要的产品,同时也隐藏了创建的细节。用户只需要关心生产产品的工厂即可,而不需要关心创建的细节。如示例程序Main类中,我们并没有引入IDCard类,用户只需要关心工厂类即可,即便引入了IDCard类,也只能通过IDCardFactory类来创造出实例。
示例中的IDCard的构造函数为什么不是public?
这就是为了让除了idcard包外的类无法new出IDCard类的实例。这样就可以做到强迫外部类必须使用IDCardFactory来生成IDCard的实例