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


 使多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關系。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,知道有一個對象處理它為止。
這里寫圖片描述

責任鏈模式的角色:
1. 抽象處理者角色(Handler):定義出一個處理請求的接口。如果需要,接口可以定義出一個方法以設定和返回對下家的引用。這個角色通常由一個Java抽象類或者Java接口實現。上圖中Handler類的聚合關系給出了具體子類對下家的引用,抽象方法handlerRequest()規范了子類處理請求的操作。
2. 具體處理者角色(ConcreteHandler):具體處理者接到請求后,可以選擇將請求處理掉,或者將請求傳給下家。

 舉個簡單例子:報銷流程,項目經理<部門經理<總經理
 其中項目經理報銷額度不能超過1000,部門經理報銷額度不能超過5000,超過5000的則需要總經理審核。
1 抽象處理角色ConsumeHandler

public abstract class ConsumeHandler
{
private ConsumeHandler nextHandler;

public ConsumeHandler getNextHandler()
{
return nextHandler;
}

public void setNextHandler(ConsumeHandler nextHandler)
{
this.nextHandler = nextHandler;
}

public abstract void doHandler(String user, BigDecimal free);
}

2 具體處理角色

public class ProjectHandler extends ConsumeHandler
{

@Override
public void doHandler(String user, BigDecimal free)
{
if(free.doubleValue() < 1000)
{
if(user.equals("jj"))
System.out.println(user+"報銷不通過");
else
System.out.println(user+"給予報銷:"+free);
}
else
{
if(getNextHandler() != null)
{
getNextHandler().doHandler(user, free);
}
}
}
}

public class DeptHandler extends ConsumeHandler
{

@Override
public void doHandler(String user, BigDecimal free)
{
if(free.doubleValue() < 5000)
{
if(user.equals("qq"))
System.out.println(user+"報銷不通過");
else
System.out.println(user+"給予報銷:"+free);
}
else
{
if(getNextHandler() != null)
{
getNextHandler().doHandler(user, free);
}
}
}
}

public class GeneralHandler extends ConsumeHandler
{

@Override
public void doHandler(String user, BigDecimal free)
{
if(free.doubleValue() >= 5000)
{
if(user.equals("zzh"))
System.out.println(user+"報銷不通過");
else
System.out.println(user+"給予報銷:"+free);
}
else
{
if(getNextHandler() != null)
{
getNextHandler().doHandler(user, free);
}
}
}
}

3 測試代碼

        ConsumeHandler project = new ProjectHandler();
ConsumeHandler dept = new DeptHandler();
ConsumeHandler general = new GeneralHandler();
project.setNextHandler(dept);
dept.setNextHandler(general);
project.doHandler("jj", new BigDecimal(2000));
project.doHandler("jj", new BigDecimal(300));
project.doHandler("qq", new BigDecimal(2000));
project.doHandler("zzh", new BigDecimal(20000));
project.doHandler("qq", new BigDecimal(20000));

測試結果:

jj給予報銷:2000
jj報銷不通過
qq報銷不通過
zzh報銷不通過
qq給予報銷:20000

 和這個例子相同的還有請假管理,比如請假2天內的部門經理可以處理,超過2天不超過5天的可以研發總監處理,超過5天的需要總經理處理。
 責任鏈模式可能是一條直線,一個環鏈甚至一個樹結構的一部分。
 責任鏈模式的缺點:當責任鏈的鏈結構比較長比較復雜的話,會產生很多內存垃圾對象,他們在實際處理中,並沒有發揮任何的作用。

JDK中的責任鏈模式
java.util.logging.Logger#log()
javax.servlet.Filter#doFilter()


參考資料
1. 《23種設計模式
2. 《細數JDK里的設計模式
3. 《重溫設計模式(三)——職責鏈模式(chain of responsibility)


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com