1. 程式人生 > >設計模式之責任鏈模式(Chain of Responsibility Pattern)

設計模式之責任鏈模式(Chain of Responsibility Pattern)

  • 責任鏈模式定義
    責任鏈的重點是在“鏈”上,由一條鏈去處理相似的請求在鏈中決定誰來處理這個請求,並返回相應的結果。其定義為:Avoid coupling the sender of a request to its receiver by giving more than one project a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. 使多個物件都有機會處理請求,從而避免了請求的傳送者和接收者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞改請求,直到有物件處理它為止。
  • 責任鏈模式通用類圖
    在這裡插入圖片描述
  • 責任鏈模式通用程式碼
    首先是抽象處理者,①定義一個請求的處理方法handlerMessage。②定義一個鏈的編排方法。③定義具體的請求者必須實現的方法。
public abstract class Handler {

	private Handler nextHandler;

	@SuppressWarnings("unlikely-arg-type")
	public final Response hanleMessage(Request request) {

		Response response = null;

		if (this.getHandlerLevel().equals(request.getRequestLevel())) {
			response = this.echo(request);
		} else {
			if(this.nextHandler != null) {
				response = this.nextHandler.hanleMessage(request);
			}else {
				
			}
		}
		return response;
	}

	public void setNext(Handler _handler) {
		this.nextHandler = _handler;
	}

	protected abstract Level getHandlerLevel();

	protected abstract Response echo(Request request);
}

public class Level {

}

public class Request {

	public Level getRequestLevel() {
		return null;
	}
}

public class Response {

}

具體的處理者1

public class ConcreteHandler1 extends Handler {

	@Override
	protected Level getHandlerLevel() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected Response echo(Request request) {
		// TODO Auto-generated method stub
		return null;
	}
}

具體的處理者2

public class ConcreteHandler2 extends Handler{

	@Override
	protected Level getHandlerLevel() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected Response echo(Request request) {
		// TODO Auto-generated method stub
		return null;
	}
}

具體的處理者3

public class ConcreteHandler3 extends Handler{

	@Override
	protected Level getHandlerLevel() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected Response echo(Request request) {
		// TODO Auto-generated method stub
		return null;
	}
}

呼叫類

public class Client {

	public static void main(String[] args) {
		
		// 宣告處理節點
		Handler h1 = new ConcreteHandler1();
		Handler h2 = new ConcreteHandler2();
		Handler h3 = new ConcreteHandler3();
		
		// 處理順序
		h1.setNext(h2);
		h1.setNext(h3);
		
		// 返回結果
		Response response = h1.hanleMessage(new Request());
	}
}
  • 責任鏈模式例項類圖
    其實責任鏈模式在我們工作中還是比較常見的,比如提交請假申請的流程就可以看做一個責任鏈模式,首先老大給批准,接下來經理批准,最後總監批准,這個過程就是一個鏈。
    在這裡插入圖片描述
  • 責任鏈模式例項程式碼
    首先是抽象處理者
public abstract class Handler {
	/**
	 * 持有下一個處理請求的物件
	 */
	protected Handler successor = null;

	/**
	 * 取值方法
	 */
	public Handler getSuccessor() {
		return successor;
	}

	/**
	 * 設定下一個處理請求的物件
	 */
	public void setSuccessor(Handler successor) {
		this.successor = successor;
	}

	/**
	 * @return 成功或失敗的具體通知
	 */
	public abstract String handleRequest(String user, int dayNum);

}

接下來分別是TeamLeader,Manager和GeneralManager

public class TeamLeader extends Handler {

	@Override
	public String handleRequest(String user, int dayNum) {

		String str = "";
		// TL許可權比較小
		if (dayNum < 3) {
			if ("張三".equals(user)) {
				str = "成功:TL同意【" + user + "】請假" + dayNum + "天";
			} else {
				// 其他人一律不同意
				str = "其他人一律不同意";
			}
		} else {
			// 請假超過三天的
			if (getSuccessor() != null) {
				return getSuccessor().handleRequest(user, dayNum);
			}
		}
		return str;
	}
}
public class Manager extends Handler{

	@Override
	public String handleRequest(String user, int dayNum) {

		String str = "";
		// 經理許可權相對較大
		if (dayNum < 5) {
			if ("張三".equals(user)) {
				str = "成功:經理同意【" + user + "】請假" + dayNum + "天";
			} else {
				// 其他人一律不同意
				str = "其他人一律不同意";
			}
		} else {
			// 請假超過五天的
			if (getSuccessor() != null) {
				return getSuccessor().handleRequest(user, dayNum);
			}
		}
		return str;
	}

}
public class GeneralManager extends Handler {

	@Override
	public String handleRequest(String user, int dayNum) {

		String str = "";
		// 總監許可權最大
		if (dayNum < 10) {
			if ("張三".equals(user)) {
				str = "成功:總監同意【" + user + "】請假" + dayNum + "天";
			} else {
				// 其他人一律不同意
				str = "其他人一律不同意";
			}
		} else {
			// 如果還有後繼的處理物件,繼續傳遞
			if (getSuccessor() != null) {
				return getSuccessor().handleRequest(user, dayNum);
			}
		}
		return str;
	}
}

呼叫類

public class Client {

	public static void main(String[] args) {

		Handler h1 = new TeamLeader();
		Handler h2 = new Manager();
		Handler h3 = new GeneralManager();
		
		//開始測試
        String test1 = h1.handleRequest("張三", 2);
        System.out.println("test1 = " + test1);
        String test2 = h3.handleRequest("李四", 2);
        System.out.println("test2 = " + test2);
        System.out.println("---------------------------------------");
        
        String test3 = h2.handleRequest("張三", 4);
        System.out.println("test3 = " + test3);
        String test4 = h3.handleRequest("李四", 4);
        System.out.println("test4 = " + test4);
        System.out.println("---------------------------------------");
        
        String test5 = h3.handleRequest("張三", 7);
        System.out.println("test5 = " + test5);
        String test6 = h3.handleRequest("李四", 7);
        System.out.println("test6 = " + test6);
	}

}

輸出結果

test1 = 成功:TL同意【張三】請假2天
test2 = 其他人一律不同意
---------------------------------------
test3 = 成功:經理同意【張三】請假4天
test4 = 其他人一律不同意
---------------------------------------
test5 = 成功:總監同意【張三】請假7天
test6 = 其他人一律不同意

參考書籍:設計模式之禪
例項程式碼放在這裡