设计模式:工厂方法
一、前言
前面我们说过模板方法被用在了工厂方法里面,为什么呢?工厂是制造产品的,需要按照一定的流程去创造产品,因此这一定的流程创造产品就是我们的模板了。工厂方法可以说用的很多,在我们的第一个设计模式,迭代器里面,我们其实就用到过,只不过我们不知道而已,下面我们先看一下工厂方法的本质,然后再逐一分析。
二、代码
我们直接看代码,然后就有一定的理解了。
Factory代码:
1 package zyr.dp.factory; 2 3 public abstract class Factory { 4 public abstract Product createProduct(String owner); 5 public abstract void registerProduct(Product p); 6 public abstract void getAllProductOwner(); 7 public Product create(String owner){ 8 Product p=createProduct(owner); 9 registerProduct(p); 10 return p; 11 } 12 }
IDCardFactory 实现类:
1 package zyr.dp.factory; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class IDCardFactory extends Factory { 7 List owners=new ArrayList(); 8 public Product createProduct(String owner) { 9 System.out.println("为 "+owner+" 创造产品成功..."); 10 return new IDCardProduct(owner); 11 } 12 13 public void registerProduct(Product p) { 14 String owner=((IDCardProduct)p).getOwner(); 15 owners.add(owner); 16 System.out.println("注册 "+owner+" 的产品成功..."); 17 } 18 19 public void getAllProductOwner() { 20 for(int i=0;i<owners.size();i++){ 21 System.out.println("产品用户:"+owners.get(i)); 22 } 23 } 24 }
Product方法:
1 package zyr.dp.factory; 2 3 public abstract class Product { 4 public abstract void use(); 5 }
IDCardProduct 方法:
1 package zyr.dp.factory; 2 3 public class IDCardProduct extends Product { 4 5 String owner; 6 IDCardProduct(String owner){ 7 this.owner=owner; 8 } 9 public void use() { 10 System.out.println("用户 "+owner+" 正在使用产品..."); 11 } 12 public String getOwner() { 13 return owner; 14 } 15 }
Main类:
1 package zyr.dp.factory; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 Factory f=new IDCardFactory(); 7 Product p=f.create("朱彦荣"); 8 p.use(); 9 System.out.println("--------------------"); 10 p=f.create("李山秀"); 11 p.use(); 12 System.out.println("--------------------"); 13 f.getAllProductOwner(); 14 } 15 16 }
运行结果:
至此我们可以看到在工厂抽象类里面定义了创造产品和注册产品,然后在实现类里面真的进行创造和注册产品,这里的创造产品,我们使用了:
1 public Product createProduct(String owner) { 2 System.out.println("为 "+owner+" 创造产品成功..."); 3 return new IDCardProduct(owner); 4 }
对于这一句我们是不是似曾相识呢,还记得在迭代器里面我们在集合类的实现类里面也用到了这一句,将迭代器地实现类的对象返回给了迭代器的接口类型,并且在集合类的接口里面我们定义了这样的方法;在工厂类里面,我们使用了相同的模式来操作,因此迭代器间接地使用了工厂方法来创造迭代器对象。在这里我们思考可不可以将工厂类和产品类这两个抽象类改成接口,答案是不能,因为我们使用了模板,模板的定义就要求我们能在父类中定义实际的概括性的操作(模板方法),而接口只能定义协议,不能定义实现;第二个问题,在工厂类里面我们可不可以直接创造产品,答案是不能,因为如果在工厂类的创造产品方法中我们使用new Product();来做的话,Product就不能为抽象类了,因为抽象类不能new出对象。对于产品类的实现的构造方法里面我们可以看到使用了默认的定义域,这样只能在本包中使用该方法,保证了使用权限安全。
最后对于抽象类,可以有构造函数,其实必须有构造函数(没写的时候默认有),因为,子类的初始化需要首先调用抽象类的构造函数,然后是子类的构造函数;但是抽象类的构造函数不能定义成抽象的,因为如果这样的话,将不能被实现,因此没有抽象的构造函数。
三、总结
到这里我们一共学习了四种模式,迭代器、适配器、模板方法、工厂方法,其中迭代器使用了工厂方法,工厂方法使用了模板方法,都是用了继承、接口、抽象等机制,适配器也有两种适配方式。因此我们可以看到设计模式不是独立的,而是相互之间有着关系和区别的,在学习的时候我们要善于总结设计模式之间的共同之处和不同之处,活学活用,才能在以后的大型项目开发中选择正确的开发方式,事半功倍。