您的位置:首页 > 其它

漫谈设计模式笔记:模板模式

2012-06-29 11:20 176 查看
场景: 为了回家过年,我们都要先买火车票,然后坐火车,最后才能和家人团聚。

程序:

这里我们写个简单程序模拟回家过年。新建了一个NewYear类,它有一个celebrateSpringFestival()的方法,我们把买票,坐车,回家庆祝都写在这个方法。

public class NewYear {
public void celebrateSpringFestival(){
//1.买票
System.out.println("买票");

//2.乘火车
System.out.println("乘火车");

//3.庆祝新年
System.out.println("新年快乐!");
}
}


我们回家坐车,可以选择火车,汽车,飞机,因人而异。但不管坐哪种交通,都要先买票,再坐车,最后才回家过年。于是我们又新建一个类PassengerByCoach,由于买票和在家庆祝是一样的,只需要改乘坐交通方式的代码改而已。

代码如下:

public class PassengerByCoach{
public void celebrateSpringFestival(){
//1.买票
System.out.println("买票");

//2.乘汽车
System.out.println("乘汽车");

//3.庆祝新年
System.out.println("新年快乐!");
}
}


如果我们要坐飞机,也是同样的代码,只改乘坐的交通方式的代码。随着交通工具的增多,以后要开发更多的类和测试类。这样,维护起来就麻烦了。为了解决重复代码出现,出现了模板模式的方法。

为了重复使用代码,我们使用继承机制。因为买票和在家庆祝两个功能是一样,所以抽出一个父类,把这些相同逻辑写在父类,因此有了buyTicket()和celebrate()两个方法。而乘坐交通方式写成travel()方法,让子类去实现各自不同的乘坐方式。并且在父类定义一个celebrateSpring()方法供客户端调用,实现买票,坐车,庆祝三个顺序的招待。

父类:

public abstract class HappyNewYear {

//1.买票,final不让子类个性其方法

protected final void buyTicket(){

System.out.println("买票");

};

//2.子类要实现的具体乘坐方式

protected abstract void travel();

//3.庆祝

protected final void celebrate(){

System.out.println("新年快乐!");

};

public void celebrateSpring(){

buyTicket();

travel();

celebrate();

}

}

现在编写子类,实现一个乘坐飞机的子类。

public class PassengerbyAir extends HappyNewYear {

@Override
protected void travel() {
System.out.println("坐飞机");

}

}


同样,可以再写乘坐汽车,乘坐火车的两个子类。

public class PassengerbyCoach extends HappyNewYear {
@Override
protected void travel() {
System.out.println("坐汽车");

}

}

public class PassengerbyTrain extends HappyNewYear {

@Override
protected void travel() {
System.out.println("坐火车");

}

}


结果:

...CiCi准备回家...

买票

坐飞机

新年快乐!

...GiGi准备回家

买票

坐汽车

新年快乐!

...MiMI准备回家

买票

坐火车

新年快乐!

总结:

使用继承,子类中不需要实现那些重复买票和庆祝过年的代码,只需要实现不同的回家方式代码,避免了代码的重复。父类中的celebrate()方法是一个模板方法(也叫框架方法),它把回家过年分为三步,其中方法travle是抽象方法,用于子类实现不同的逻辑,所以我们使用的是模板模式方法。

模板模式有如下功能:

1.能够解决代码冗余问题。在例子中,PassengerbyAir ,PassengerbyCoach ,PassengerbyTrain 没有必要再去实现buyTickey()和celebrate()方法了。

2.易于扩展。我们通过创建新类,实现可定制化的方法就可以扩展功能。如果有人坐船回家,加入PassengerByBoat类并实现travel()方法即可。

3. 父类提供了算法的框架,控制方法执行流程,而子类不能改变算法流程,子类方法调用由父类模板方法决定。

4.父灰可以把那些重要的不允许改变的方法屏蔽掉,不让子类去重写。我们可以声明这些为private 或final.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: