java笔记--设计模式之模版方法模式

在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点菜、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是:点菜 --> 吃东西 --> 买单。在这三个步骤中,点菜和买单大同小异,最大的区别在于第二步——吃什么?吃黄焖鸡和吃满汉全席的feel就不一样。

在软件开发中,有时也会遇到类似的情况,某个方法的实现需要多个步骤(类似“请客”),其中有些步骤是固定的(类似“点菜”和“买单”),而有些步骤并不固定,存在可变性(类似“吃东西”)。为了提高代码的复用性和系统的灵活性,可以使用一种称之为模板方法模式的设计模式来对这类情况进行设计,在模板方法模式中,将实现功能的每一个步骤所对应的方法称为基本方法(例如“点菜”、“吃东西”和“买单”),而调用这些基本方法同时定义基本方法的执行次序的方法称为模板方法(例如“请客”)。

在模板方法模式中,可以将相同的代码放在父类中,例如将模板方法“请客”以及基本方法“点菜”和“买单”的实现放在父类中,而对于基本方法“吃东西”,在父类中只做一个声明,将其具体实现放在不同的子类中,在一个子类中提供“吃黄焖鸡”的实现,而另一个子类提供“吃满汉全席”的实现。通过使用模板方法模式,一方面提高了代码的复用性,另一方面还可以利用面向对象的多态性,在运行时选择一种具体子类,实现完整的“请客”方法,提高系统的灵活性和可扩展性。

       模版方法模式 
        定义:一个模版方法用一些抽象的操作定义一个算法,而子类将重新定义这些操作以提供具体行为。

        意图:定义了在一个操作中的一个算法框架,把一些步骤推迟到子类中去实现。模版方法模式让子类不需要改变算法结构 而重新定义特定的算法步骤。

通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序,而通过其子类来覆盖父类的某些步骤,从而使得相同的算法框架可以有不同的执行结果。

       模板方法模式提供了一个模板方法来定义算法框架,而某些具体步骤的实现可以在其子类中完成。

       模板方法模式中的角色:

 (1) AbstractClass(抽象类)在抽象类中定义了一系列基本操作,这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法,用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。

 (2) ConcreteClass(具体子类)它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

       具体实现代码如下:

        抽象类角色

public abstract class ModeMethod {
	/**
	 * 模版方法:请客
	 */
	public void treat() {
		order();// 点菜
		eatSomething();// 吃东西
		payMoney();// 结账
	}

	private void order() {
		System.out.println("今天我请客,我来点菜了啊");
		System.out.println("打开菜单,书写菜名");
		System.out.println("点餐完毕");
	}

	abstract void eatSomething();

	private void payMoney() {
		System.out.println("吃好了,我来付款了啊");
		System.out.println("结账走人");
	}
}

具体子类角色

子类1

public class Guest1 extends ModeMethod{

	@Override
	void eatSomething() {
		System.out.println("请客人1吃的 黄焖鸡");
		
	}
}
子类2
public class Guest2 extends ModeMethod{
   

	@Override
	void eatSomething() {
		System.out.println("请客人2吃的 冬笋老鸭汤,红烧带鱼,玉米排骨,干锅牛蛙....");
		
	}
}

测试类

public class MainTest {

	public static void main(String[] args) {
		ModeMethod guest1 = new Guest1();//向上转型
		guest1.treat();
		ModeMethod guest2 = new Guest2();
		guest2.treat();
	}

}
结果如下:

今天我请客,我来点菜了啊
打开菜单,书写菜名
点餐完毕
请客人1吃的 黄焖鸡
吃好了,我来付款了啊
结账走人
今天我请客,我来点菜了啊
打开菜单,书写菜名
点餐完毕
请客人2吃的 冬笋老鸭汤,红烧带鱼,玉米排骨,干锅牛蛙....
吃好了,我来付款了啊
结账走人


  在模板方法模式中,由于面向对象的多态性,子类对象在运行时将覆盖父类对象,子类中定义的方法也将覆盖父类中定义的方法,因此程序在运行时,具体子类的基本方法将覆盖父类中定义的基本方法。

文章参考:http://blog.csdn.net/lovelion/article/details/8299794


如果对上面所述有什么疑惑,请不吝指出,谢谢!

你可能感兴趣的:(设计模式)