`

设计模式--模板方法

 
阅读更多
模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
 
Template Method Pattern:  Define the skeleton of an algorithm in an  operation, deferring some steps to subclasses. Template Method lets  subclasses redefine certain steps of an algorithm without changing the  algorithm's structure

  模板方法模式是一种基于继承的代码复用技术,它是一种类行为型模式

       模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序,而通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果。模板方法模式提供了一个模板方法来定义算法框架,而某些具体步骤的实现可以在其子类中完成。

 

1 这里有4个类,一个父类,用于抽象出模板方法  另外2个子类 继承父类 ,最后一个是测试类

吃的模板类

package com.dream.template;

/**
 * @author zxg
 * 模板方法模式父类抽象类
 * 1 抽象类
 * 2 基本方法
 * 3 抽象方法
 * 4 模板方法(final)
 * 5 钩子方法 
 */
public abstract class EatTemplate {
	public final void eatProcess(){
		goWhere();
		eatWhat();
		eating();
		if(ifsleep()){
		 after();
		}
	}
	protected  void goWhere(){
	  System.out.println("杭州万塘路");
	}
	protected  abstract void eatWhat();
	protected  abstract void eating();
	protected  void  after(){
	  System.out.println("吃好洗洗睡了");	
	}
	
	/**是否睡觉
	 * 用钩子方法给予子类更大的灵活性,最后将方法汇总构成一个不可改变的模板方法。
	 * @return 
	 */
	protected  boolean ifsleep(){
		return true;
	}
}

 2 吃鱼的实现类

package com.dream.template;

/**
 * @author zxg
 * 1 实现基类的抽象方法  2覆盖钩子方法
 */
public class EatFishTemplate extends EatTemplate{
	/* 
	 * @see com.dream.template.EatTemplate#eatWhat()
	 */
	protected void eatWhat() {
		System.out.println("烤鱼");
		
	}

	protected void eating() {
		System.out.println("在吃烤鱼啊,好好吃奥。。。");
		
	}

	protected void after() {
		System.out.println("吃了鱼可以好好的睡一觉");
		
	}
	protected boolean ifsleep(){
		return false;
	}
	

}

  3 吃龙虾的实现类

 

package com.dream.template;

public class EatLobsterTemplate extends EatTemplate{


	@Override
	protected void eatWhat() {
		System.out.println("吃龙虾");
	}

	@Override
	protected void eating() {
		System.out.println("吃2斤龙虾");
	}

	@Override
	protected void after() {
		System.out.println("吃完龙虾后可以好好睡一觉了");
		
	}

}

  4 测试类

 

package com.dream.template;

import org.junit.Test;

/**
 * @author zxg
 * 抽象方法模式测试类
 */
public class TempatePatternTest {
 /**
 * 吃鱼
 */
@Test
  public void testFishTemplate(){
	  EatTemplate fishTemplate = new EatFishTemplate();
	  fishTemplate.eatProcess();
  }
 /**
 * 吃龙虾
 */
@Test
  public void testLobsterTemplate(){
	  EatTemplate lobsterTemplate = new EatLobsterTemplate();
	  lobsterTemplate.eatProcess();
  }
 
}

 总结 :一般情况下,钩子方法的返回值为true,如果不希望某方法执行,可以在其子类中覆盖钩子方法,将其返回值改为false即可,这种类型的钩子方法可以控制方法的执行,对一个算法进行约束。

       还有一类钩子方法就是实现体为空的具体方法,子类可以根据需要覆盖或者继承这些钩子方法,与抽象方法相比,这类钩子方法的好处在于子类如果没有覆盖父类中定义的钩子方法,编译可以正常通过,但是如果没有覆盖父类中声明的抽象方法,编译将报错。

优点

    1 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。

    2 子类实现算法的某些细节,有助于算法的扩展。

    3 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。

缺点

    1 每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。

适用场景

     1 在某些类的算法中,用了相同的方法,造成代码的重复。

    2 控制子类扩展,子类必须遵守算法规则。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics