4.工厂方法模式(Factory Method Pattern)
解决的问题
之前我们提到过简单工厂模式,它虽然不属于23种设计模式中的任何一种,但却是一种比较常见和方便的模式。简单工厂模式的最大缺点是违背了开闭原则,因此工厂方法模式诞生了。它和简单工厂模式解决的问题类似,但要更加优雅。
类图结构
在这个类图中,Product
类定义了工厂方法所创建的对象的接口,Creator
声明了一个工厂方法,返回一个Product类型的对象。ConcreteCreator
类重定义了工厂方法模式以返回一个ConcreteProduct
实例。ConcreteProduct
类实现了Product接口,代表了具体的产品类。
好处与坏处
工厂方法模式的好处很明显,它不仅拥有简单工厂模式的优点,也克服了简单工厂模式的缺点,因此才会被列入23种设计模式中。但工厂方法模式其实就是把简单工厂模式内部的逻辑判断移到了客户端来进行。我们可以使用Java的反射特性去读取xml文件来克服这一缺点。同样的,由于使用了大量的类,使得程序更加复杂,在修改代码的时候会变的更加困难。
5.原型模式(Prototype Pattern)
解决的问题
原型模式,说的大白话一点就是复制粘贴大法
。在C++、Java等语言都有Clone的方法。在我们的程序中很多时候都会遇到代码重复的情况。这种时候复制粘贴大法是最好的是实现方式了。原型模式其实就是这样的一种模式。原型模式其实就是从一个对象再创建另一个可定制的对象,而且不需要知道任何创建的细节。
类图结构
类图中,Prototype
类是一个原型类,声明了一个克隆自身的接口。Client
类,即客户端类,让一个原型克隆自身从而实现一个新的对象。ConcretePrototype1
和ConcretePrototype2
是具体的原型类,实现一个克隆自身的操作。
我们来看看具体的代码:
public abstract Prototype{
private String id;
public Prototype(String id){
this.id = id;
}
public String getId(){
return id;
}
public abstract Prototype clone();
}
public class ConcretePrototype1 extends Prototype{
public ConcretePrototype1(String id){
super(id);
}
@Override
public Prototype clone(){
return this.clone();
}
}
事实上,由于克隆十分的常用,Java 中提供了 cloneable 标识该对象可以被拷贝,只需要重写clone()方法即可。
好处与坏处
原型模式的好处显而易见:简单,实现简单。但缺点也出在这里,往往简单的操作都会导致很严重的后果。原型模式的坑还是蛮多的。
6.模版方法模式(Template Method Pattern)
解决的问题
模版方法模式,定义一个操作中的算法的骨架,将一些步骤延迟到子类中。模版方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。主要用于我们需要把一些公共的方法抽象出来的情况。这种情况还是很常见的,我们写代码的过程就是一边写一边重构的过程。
类图结构
可以看到,类图十分的简单。定义一个抽象类放一些公共的方法,定义一个模版方法实现算法的骨架。用ConcreteClass
来完成算法中与特定子类相关的步骤。如下代码:
public abstract class AbstractClass{
public abstract void primitiveOperation1();
public void templateMethod(){
primitiveOperation1();
}
}
public class ConcreteClassA extends AbstractClass{
@Override
public void primitiveOperation1(){
System.out.println("具体类1方法1实现");
}
}
public class ConcreteClassB extends AbstractClass{
@Override
public void primitiveOperation1(){
System.out.println("具体类2方法1实现");
}
}
优点和缺点
模版方法模式的优点:体现了开闭原则,里氏代换原则等等。在我们有需要抽象出的子类的时候我们可以采用该模式。而缺点则是模版方法模式的实现违背了我们常规的思维模式,按照我们的设计习惯,我们一般让抽象类负责声明最抽象的部分,但模版方法模式则反其道而行,会对设计上产生一些不便。