定义
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
代码实现:
我们以泡茶和冲咖啡为例,二者在某些行为上是共通的。
泡茶的步骤:
1.把水煮沸;2.用沸水冲泡茶叶;3.把茶倒进杯子;4.加入柠檬。
冲咖啡的步骤:
1.把水煮沸;2.用沸水冲泡咖啡;3.把咖啡倒进杯子;4.加入糖和牛奶。
其中步骤1和步骤3是相同的,这时候我们可以在超类中实现而步骤2和步骤4则交由子类实现。这时候我们就可以设计抽象类CaffeineBeverage:
public abstract class CaffeineBeverage {
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
}
而子类coffee和Tea的实现也很简单。
public class Coffee extends CaffeineBeverage {
public void brew() {
System.out.println("Dripping Coffee through filter");
}
public void addCondiments() {
System.out.println("Adding Sugar and Milk");
}
}
public class Tea extends CaffeineBeverage {
public void brew() {
System.out.println("Steeping the tea");
}
public void addCondiments() {
System.out.println("Adding Lemon");
}
}
测试类以及测试结果如下:
public class BeverageTestDrive {
public static void main(String[] args) {
Tea tea = new Tea();
Coffee coffee = new Coffee();
System.out.println("\nMaking tea...");
tea.prepareRecipe();
System.out.println("\nMaking coffee...");
coffee.prepareRecipe();
}
}
Making tea...
Boiling water
Steeping the tea
Pouring into cup
Adding Lemon
Making coffee...
Boiling water
Dripping Coffee through filter
Pouring into cup
Adding Sugar and Milk
prepareRecipe()方法控制了算法,没有人能够改变它,这个方法也会依赖子类提供的某些或所有步骤的实现。
其实在java中模版方法模式也无处不在,我们以最简单的数组比较为例,Arrays.sort(object[] o)这是数组的比较方法,当我们传入一个int数组,他会给这个数组排序,当我们传递一个自定义对象的数组,再调用sort()方法,则会抛出java.lang.ClassCastException异常。
这其实就是模版模式的应用,我们只需要将类实现compareTo接口就可以实现排序,下面我们以自定义的类为例:
public class Duck implements Comparable<Duck> {
String name;
int weight;
public Duck(String name, int weight) {
this.name = name;
this.weight = weight;
}
public String toString() {
return name + " weighs " + weight;
}
public int compareTo(Duck object) {
Duck otherDuck = object;
if (this.weight < otherDuck.weight) {
return -1;
} else if (this.weight == otherDuck.weight) {
return 0;
} else { // this.weight > otherDuck.weight
return 1;
}
}
}
public class DuckSortTestDrive {
public static void main(String[] args) {
Duck[] ducks = {
new Duck("Daffy", 8),
new Duck("Dewey", 2),
new Duck("Howard", 7),
new Duck("Louie", 2),
new Duck("Donald", 10),
new Duck("Huey", 2)
};
System.out.println("Before sorting:");
display(ducks);
Arrays.sort(ducks);
System.out.println("\nAfter sorting:");
display(ducks);
}
public static void display(Duck[] ducks) {
for (Duck d : ducks) {
System.out.println(d);
}
}
}
运行测试类实现的结果:
Before sorting:
Daffy weighs 8
Dewey weighs 2
Howard weighs 7
Louie weighs 2
Donald weighs 10
Huey weighs 2
After sorting:
Dewey weighs 2
Louie weighs 2
Huey weighs 2
Howard weighs 7
Daffy weighs 8
Donald weighs 10
模版模式在java中还会以不同形式出现,相信通过以上的讲解,大家也大概了解了,工厂方法是模版方法的一种特殊版本。
优点:
1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。
缺点:
每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
网友评论