【设计模式】一、模板方法模式

前言

面向对象的三大特点:封装(对象隐藏了数据与具体实现细节)、继承、多态。

设计模式的目的是“重用”,避免重复造轮子。

模式的定义:某一上下文环境中的一类问题 “常用/通用”的解决方法。

每个模式的四个基本要素:模式名称、问题、方法、效果。四个基本要素全面描述了特定的上下文中,相关的类、对象如何协作解决问题。

一、第一个模式——模板方法模式Template Method

1.DRY原则(Don't repeat yourself)

软件开发过程中,时刻发生着变化,如需求变换、技术变换等。 如果我们编写重复的代码,会带来很多问题:

  • 在重复的代码中进行相同的修改;
  • 开发成本增加,新问题和就问题可能非常相近,只有一些小细节不相同,重复的代码导致无法实现代码的重用,增大工作量;
  • 不利于测试;
  • 不利于阅读与维护。
2.使用继承
例如,要实现春节期间购票、回家、庆祝的类,而回家方式各有不同,包括汽车、火车、飞机。如果为乘汽车、火车、飞机的人分别定义类实现购票、回家、庆祝的功能,就会造成重复,因为这三类中只有回家方法不同,而购票、庆祝这两个方法是相同的。我们何不抽象出一个父类,将相同的逻辑写在父类里。可以在父类中定义购票、庆祝这两个方法,以实现不变的部分;子类根据需要实现各自不同的 travel( ) 方法。
package jyy.DesignPattern.template;

//定义一个抽象类作为父类,其中包括一个抽象方法travel(),剩下的两个方法为final类型的方法
public abstract class HappyPeople {
	public void celebrateSpringFestival(){
		//确保以下三个函数的执行顺序
		subscribeTicket();
		travel();
		celebrate();
	}
	protected final void subscribeTicket(){
		//......函数方法的具体内容
	}
	protected abstract void travel();//抽象函数,等待子类继承这个父类是重写其具体实现,在这里无需定义具体实现
	
	protected final void celebrate(){
		//.......函数方法的具体内容
	}
}

package jyy.DesignPattern.template;

public class PassengerByAir extends HappyPeople{
	@Override
	protected void travel(){
		//实现travel()的具体方法
		System.out.println("Traveling by Air");
	}
}

父类中的方法celebrateSpringFestival()方法是一个模板方法/框架方法,把过年回家分为三步,其中方法travel()是抽象部分,用于方便子类实现不同的功能逻辑。

3.模板方法模式
定义在一个操作中的一个算法框架,把一些步骤推迟到子类中实现。使得子类不需要改变算法结构而重新定义 特定 的算法步骤。
模板方法有如下功能:
  • 能够解决冗余问题。上面例子中,避免了重复实现购票、庆祝两个方法
  • 易于扩展。如有人坐船回家,直接继承父类并重写travel方法即可
  • 父类提供了算法框架,控制方法执行流程,而子类不能改变算法流程。
  • 父类可以将重要的、不允许改变的方法屏蔽掉,不让子类重写(override)。可以将这些方法声明为final或者private
4.引入回调(callback)

定义:一段可执行逻辑的引用,我们把该引用传递到另外一段逻辑里提供适时调用。
目的:避免类的泛滥。
例如:在对数据库的查询操作都是相同的(得到数据库连接Connection对象,创建Statement实例,执行查询语句,返回查询结果并处理异常),只是对 查询结果的处理上不同。但是如果抽象出处理查询结果的方法供子类延迟实现的话,由于各种各样的查询太多,导致我们需要创建很多子类去处理这些查询结果。引起子类的泛滥。因此要用回调来解决此类问题。

代码片段如下:
package jyy.DesignPattern.template;

import java.sql.*;

/**
 *定义SimpleJdbcQueryTemplate类为模板方法类
 *ResultSetHandler为回调接口 
 */
public class SimpleJdbcQueryTemplate {
	public <T> T query(String queryString,ResultSetHandler<T> rsHandler){
		//define variables...
		try{
			Connection connection =  getCollection();//获得数据库连接
			statement=connection.prepareStatement(queryString)//创建PrepareStatement实例
			ResultSet rs=statement.executeQuery();执行查询并返回结果
			return rsHandler.handle(rs);//调用回调rsHandlerde handle(ResultSet rs) 方法来处理查询结果并返回
		}catch (SQLException ex){
			//.....
		}finally{
			//
		}
	}
}

ResultSetHandler接口:
import java.sql.ResultSet;

public interface ResultSetHandler<T> {//这里使用泛型,这样就没必要每次都写强制类型转换语句了。泛型是在运行时动态得到对象类型的一种能力。
	public T handle(ResultSet rs);
}
执行具体查询时,实现接口,通过query()回调接口。
boolean called=new SimpleJdbcQueryTemplate().query("select * from db" , new ResultSetHandler<Boolean>(){
	public Boolean handle(ResultSet rs){
		//logical to resolve query result...
		//return ....
	}
});











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值