设计模式(四)Factory Method模式
简单来说,用Template Method模式来构建生成实例的工厂,就是Factory Method模式。在这个模式中,父类决定实例的生成方式,但不决定所要生成的具体的类,具体的处理全部交给子类负责。这样就可以将生成实例的框架和实际负责生成实例的类解耦。
下面的示例中,framework包是生成实例的框架。而idcard包是负责加工处理的。
首先根据下面的实例代码来解释一下这种常用的设计模式。
1 package BigJunOba.bjtu.framework; 2 3 public abstract class Product { 4 public abstract void use(); 5 }
Product抽象类属于framework包。这个类用来表示“产品”,定义了use方法,定义了“产品”是“任意的可以use的”东西。
1 package BigJunOba.bjtu.framework; 2 3 public abstract class Factory { 4 5 public final Product create(String owner) { 6 Product p = createProduct(owner); 7 registerProduct(p); 8 return p; 9 } 10 11 protected abstract Product createProduct(String string); 12 protected abstract void registerProduct(Product product); 13 }
Factory抽象类也属于framework包。在这里使用了Template Method模式,protected关键字说明只能被子类继承。最主要的create方法的意思是,通过create方法来生成Product实例。而create方法的实现是先调用createProduct生成产品,然后调用registerProduct方法注册产品。
1 package BigJunOba.bjtu.idcard; 2 3 import BigJunOba.bjtu.framework.Product; 4 5 public class IDCard extends Product { 6 7 private String owner; 8 9 10 IDCard(String owner) { 11 System.out.println("制作" + owner + "的ID卡"); 12 this.owner = owner; 13 } 14 15 @Override 16 public void use() { 17 System.out.println("使用" + owner + "的ID卡"); 18 } 19 20 public String getOwner() { 21 return owner; 22 } 23 }
IDCard类属于idcard包。作为Product的子类,用来表示ID卡。
1 package BigJunOba.bjtu.idcard; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import BigJunOba.bjtu.framework.Factory; 7 import BigJunOba.bjtu.framework.Product; 8 9 public class IDCardFactoty extends Factory{ 10 11 private List<String> owners = new ArrayList<String>(); 12 13 @Override 14 protected Product createProduct(String owner) { 15 return new IDCard(owner); 16 } 17 18 @Override 19 protected void registerProduct(Product product) { 20 owners.add(((IDCard)product).getOwner()); 21 } 22 23 public List<String> getOwners() { 24 return owners; 25 } 26 }
IDCardFactoty类也属于 idcard包。用来实现createProduct和registerProduct两种方法。
1 package BigJunOba.bjtu.test; 2 3 import BigJunOba.bjtu.framework.Factory; 4 import BigJunOba.bjtu.framework.Product; 5 import BigJunOba.bjtu.idcard.IDCardFactoty; 6 7 public class Main { 8 public static void main(String[] args) { 9 Factory factory = new IDCardFactoty(); 10 Product card1 = factory.create("廉酱"); 11 Product card2 = factory.create("桥爷"); 12 card1.use(); 13 card2.use(); 14 } 15 }
测试类属于test包。这里是用工厂来创建ID卡的示例,然后再调用相关的方法。
制作廉酱的ID卡 制作桥爷的ID卡 使用廉酱的ID卡 使用桥爷的ID卡
测试结果如上图所示。
Factory Method模式的类图如上图所示。使用工厂方法设计模式的好处是,本实例中,framework包中没有引入idcard包,在Product类和Factory类中,也没有出现IDCard和IDCardFactory等具体类的名字。因此,即使用也有的框架生成全新的类时,也完全不需要对framework包进行修改。通俗来说,就是“framework包不依赖于idcard包”。