软件设计模式之(一)责任链模式

欢迎大家提出意见,一起讨论!

 

转载请标明是引用于 http://blog.csdn.net/chenyujing1234

 例子代码:(编译工具:Eclipse)

http://www.rayfile.com/zh-cn/files/2a49656e-91da-11e1-a750-0015c55db73d/

参考书籍: <<软件秘笈-----设计模式那点事>>

 

责任链模式(Chain of Responsibility Pattern),是一种对象的形为模式。在责任链模式中,很多对象由每一个对象对其下家的引用而连接起来形成一条链。

客户端应用请求在这个链上传递,直到链上某一个对象决定处理此请求。

责任链模式涉及的角色如下。

1抽象处理者角色(Handler):定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回下家的引用。这个角色通常由一个Java抽象类或Java接口实现。

2具体处理者角色(ConcreteHandler):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。

下面以学生请假的流程为例进行说明.

来一起分析学生请假的流程。

1)小学生生病了,发出请假请求。

2)请假请求首先发给班长,看看班长能否处理。如果班长能够处理,则由班长批准请假;否则,交给老师处理。

3)老师接到学生请假请求,首先判断病情是否严重。如果是一般的小病,则老师批准请假;否则,交给校长处理。

4)校长接到学生请假请求,核实属实,则给予请假批准。

在一般情况下是如何分析解决这样的问题的。如图14-2所示,为一般情况学生请假关系类图。

 

软件设计模式之(一)责任链模式_第1张图片

根据设计模式中的依赖倒置原则,即面向抽象编程,而不要而向实现编程,首先定义两个接口:学生请假接口IStudent和请求处理接口IHandler。

在学生请假接口中存在两个方法:分别为病情状态(这个用来标识由谁来处理)和请求消息。而IHandler请求处理接口很简单,就是接收学生请假请求进行处理。

为了更好地扩展我们再增加一不念旧恶请求的抽象处理者AbstractHandler,该抽象处理者实现IHandler接口,实现学生请求处理接口方法,

然后使用模板方法,由子类实现具体的处理过程。

班长、老师和校长都继承抽象处理者AbstractHandler。

责任链的实现关键在于消息在链条上的传递,需要做到以下几点内容:

(1)在处理者中要含有链条中下一节点的引用。在抽象处理者AbstractHandler中增加一个IHandler类型的私有属性,用于保存对下家处理者的引用。

(2)每一个消息处理者都应该含有一个处理消息的标记位,用来标识当前处理者含有处理消息的级别。

(3)最后一点,也是最重要的一点就是,处理消息的方法需要链条化。

根据上面的内容修改完善静态类图,如图

软件设计模式之(一)责任链模式_第2张图片

下面我们就开始实现吧!

一.学生请假实现

1、学生接口------IStudent

首先,我们创建学生请求接口IStudent,该接口类中含有两个接口方法:一个是获得学生病情状态,另一个是获取学生请假内容。

/**
 * 学生接口
 * 
 * @author
 * 
 */
public interface IStudent {
	/**
	 * 获得学生病情状态
	 * 
	 * 0:小事(班长就可以处理)
	 * 
	 * 1:班长处理不了 老师能处理的事
	 * 
	 * 2:老师处理不了 校长能处理的事
	 * 
	 * 
	 */
	public int getState();

	/**
	 * 获得学生请假消息
	 * 
	 * @return
	 */
	public String getRequestMessage();
}


2、学生的实现.

在学生请假实现类中,定义了两个私有属性:病情状态和请假内容,通过构造方法传入。

/**
 * 学生实现类
 * 
 * @author
 * 
 */
public class Student implements IStudent {

	// 病情的大小状态
	private int state = -1;
	// 请假消息
	private final String message;

	public Student(int state, String message) {
		this.state = state;
		this.message = message;
	}

	/**
	 * 获得学生请假状态
	 * 
	 * 0:小事(班长就可以处理)
	 * 
	 * 1:班长处理不了 老师能处理的事
	 * 
	 * 2:老师处理不了 校长能处理的事
	 * 
	 * 
	 */
	public int getState() {
		return this.state;
	}

	/**
	 * 获得学生请假消息
	 * 
	 * @return
	 */
	public String getRequestMessage() {
		return this.message;
	}

}


二.创建抽象请假消息处理者

1、抽象处理者接口----IHandler

/**
 * 抽象处理者接口
 * 
 * @author
 * 
 */
public interface IHandler {
	// 处理请求
	public void handleRequest(IStudent student);

	// 设置下一个处理者
	public void setHandler(IHandler handler);
}


2、抽象者处理----AbstractHandler

它的存在是将处理学生的请求过程抽象化,而对学生请假请求的处理措施则由具体的子类来实现。

/**
 * 抽象处理者
 * 
 * @author
 * 
 */
public abstract class AbstractHandler implements IHandler {
	// 下一个处理者
	private IHandler handler;
	// 请假级别
	private int state = -1;

	// 构造方法 设置级别
	public AbstractHandler(int state) {
		this.state = state;
	}

	// 处理请求 交由子类负责进行具体的处理
	public abstract void process(IStudent student);

	// 处理请求
	public void handleRequest(IStudent student) {
		// 如果学生对象存在
		if (student != null) {
			if (this.state == student.getState()) {
				// 如果请假级别和当前一致 则当前对象进行处理
				this.process(student);
			} else {

				if (this.handler != null) {
					System.out.println("请求上级领导批复!");
					// 如果当前对象处理不了 则交给下一个处理者进行处理
					this.handler.handleRequest(student);
				}
			}
		}
	}

	// 设置下一个处理者
	public void setHandler(IHandler handler) {
		this.handler = handler;
	}

}


三.请假处理者具体实现

1、班长---SquadLeaderHandler

 需要实现处理方法process

/**
 * 班长处理者
 * 
 * @author
 * 
 */
public class SquadLeaderHandler extends AbstractHandler {

	public SquadLeaderHandler() {
		super(0);
	}

	// 子类具体处理请求
	@Override
	public void process(IStudent student) {
		System.out.println("班长 批复:" + student.getRequestMessage());
	}

}


2、老师----TeacherHandler

/**
 * 老师处理者
 * 
 * @author
 * 
 */
public class TeacherHandler extends AbstractHandler {

	public TeacherHandler() {
		super(1);
	}

	// 子类具体处理请求
	@Override
	public void process(IStudent student) {
		System.out.println("老师 批复:" + student.getRequestMessage());
	}

}


3、校长----SchoolMasterHandler

/**
 * 校长处理者
 * 
 * @author
 * 
 */
public class SchoolMasterHandler extends AbstractHandler {

	public SchoolMasterHandler() {
		super(2);
	}

	// 子类具体处理请求
	@Override
	public void process(IStudent student) {
		System.out.println("校长 批复:" + student.getRequestMessage());
	}
}


三.客户端测试

创建Client客户端应用程序,首先需要创建三个请求处理者:班长、老师和校长;

然后处理者根据学生病情的状态,对学生的请假分别做出不同的处理。

为了符“开-闭”原则(即做到扩展开放,对修改关闭的),这里处理者是变化的部分,可能会增加,我们需要抽象和封装。

于是采用外观模式,增加一个外观,让外观与处理者对象打交道,而客户端应用程序调用外观处理学生请假请求。

/**
 * 设置责任链关联
 * 
 * @author
 * 
 */
public class ProcessHandler {

	// 班长处理者
	private final IHandler sqmshandler;
	// 老师处理者
	private final IHandler techhandler;
	// 校长处理者
	private final IHandler scmshandler;

	// 单例模式
	private static ProcessHandler processHandler = new ProcessHandler();

	/**
	 * 构造方法建立请假处理责任链
	 */
	private ProcessHandler() {
		// 创建处理对象
		// 班长
		this.sqmshandler = new SquadLeaderHandler();
		// 老师
		this.techhandler = new TeacherHandler();
		// 校长
		this.scmshandler = new SchoolMasterHandler();
		/**
		 * 建立责任链
		 */
		// 设置班长的下一个处理者:老师
		this.sqmshandler.setHandler(this.techhandler);
		// 设置老师的下一个处理者:校长
		this.techhandler.setHandler(this.scmshandler);

	}

	/**
	 * 获得单例对象实例
	 * 
	 * @return
	 */
	public static ProcessHandler getInstance() {
		return processHandler;
	}

	/**
	 * 发送请假请求
	 * 
	 * @param message
	 */
	public void sendMessage(IStudent student) {
		// 发送给第一个处理者:班长 处理
		this.sqmshandler.handleRequest(student);
	}
}


客户端如下:

/**
 * 主应用程序
 * 
 * @author
 * 
 */
public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// 获得外观对象
		ProcessHandler processHandler = ProcessHandler.getInstance();

		// 创建随机数对象 用来随机产生学生对象
		Random random = new Random();
		for (int i = 0; i < 3; i++) {
			// 获得随机数
			int radom = random.nextInt(3);
			IStudent student = new Student(radom, "学生" + i + "生病了,要请假!");
			System.out.println("#################################");
			// 处理消息
			processHandler.sendMessage(student);
			System.out.println("#################################\n");
		}

	}
}

 

================================================================================================

总结:

一、设计原则

1、"开-闭"原则

它是设计模式的核心原则,在每一个设计模式中都有体现,责任链中的"开-闭"原则体现在可以动态地扩展责任链当中的处理节点。

而无须改动客户端应用,程序结构更加清晰,同时也大大保证了系统运行的稳定性。

2、单一职责原则.

消息处理者只完成各自的本职工作,尽量做到功能单一,这为后期的测试维护工作带来方便,每一个类的功能单一,我们可以一定

定位问题所在,节省了找错时间。

你可能感兴趣的:(设计模式,String,Random,Class,扩展,interface)