責(zé)任鏈模式
1.責(zé)任鏈模式含義
責(zé)任鏈模式,有的地方也會叫職責(zé)鏈模式。它指的是,為請求者和被請求者之間創(chuàng)建一條對象處理鏈路,避免請求發(fā)送者與接受者耦合在一起。
在責(zé)任鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發(fā)出這個請求的客戶端并不知道鏈上的哪一個對象最終處理這個請求,這使得系統(tǒng)可以在不影響客戶端的情況下動態(tài)地重新組織和分配責(zé)任
責(zé)任鏈模式里的責(zé)任,指的是類對象所承擔(dān)的職責(zé),當(dāng)每一個對象對其下家引用,就會形成一條鏈路,那么這一條鏈上的所有的對象的職責(zé)也就串起來了,這樣就形成了責(zé)任鏈,責(zé)任鏈的名字就是這樣來的。
2.責(zé)任鏈代碼示例
2.1Request類
Request類用于封裝請求的相關(guān)內(nèi)容
public class Request {
private String requestType;
private String requestContent;
private int number;
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public String getRequestContent() {
return requestContent;
}
public void setRequestContent(String requestContent) {
this.requestContent = requestContent;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
2.2Manager類
Manager類是被請求類,用于處理請求
public class Manager {
protected String name;
public Manager(String name) {
this.name = name;
}
public void getResult(String managerLevel, Request request){
if ("經(jīng)理".equals(managerLevel)) {
if ("請假".equals(request.getRequestType()) && request.getNumber() <= 2){
System.out.println(String.format("%s%s請假%d被批準", name, request.getRequestContent(), request.getNumber()));
} else {
System.out.println(String.format("%s%s請假%d我無權(quán)處理", name, request.getRequestContent(), request.getNumber()));
}
} else if ("總監(jiān)".equals(managerLevel)) {
if ("請假".equals(request.getRequestType()) && request.getNumber() <= 5){
System.out.println(String.format("%s%s請假%d被批準", name, request.getRequestContent(), request.getNumber()));
} else {
System.out.println(String.format("%s%s請假%d我無權(quán)處理", name, request.getRequestContent(), request.getNumber()));
}
} else if ("總經(jīng)理".equals(managerLevel)) {
if ("請假".equals(request.getRequestType()) ){
System.out.println(String.format("%s%s請假%d被批準", name, request.getRequestContent(), request.getNumber()));
} else if ("加薪".equals(request.getRequestType()) && request.getNumber() <= 500){
System.out.println(String.format("%s%s數(shù)量%d被批準", name, request.getRequestContent(), request.getNumber()));
} else if ("加薪".equals(request.getRequestType()) && request.getNumber() > 500){
System.out.println(String.format("%s%s數(shù)量%d再說吧", name, request.getRequestContent(), request.getNumber()));
}
}
}
}
可以看到,Manager類的getResult方法里面,有大量的條件判斷分支,這就導(dǎo)致了Manager這個類的職責(zé)太大了,違反了單一職責(zé)的原則,如果增加新的職位,比如總經(jīng)理秘書,那么就要修改原代碼,并對這個復(fù)雜的分支再加上新的條件分支,也違背了開閉原則。所以需要對這個類進行改造,而改造這個類,就使用責(zé)任鏈模式。
2.3Manager類重構(gòu)
1.首先將Manager類改為抽象類,抽象類中設(shè)置一個Manage屬性,并定義抽象的請求處理方法。
public abstract class Manager {
protected String name;
protected Manager superior;
public Manager(String name) {
this.name = name;
}
public void setSuperior(Manager superior) {
this.superior = superior;
}
public abstract void requestApplications(Request request);
}
2.新建Manager的子類CommonManger,負責(zé)處理原Manager類中的第一個if條件分支
public class CommonManager extends Manager{
public CommonManager(String name) {
super(name);
}
@Override
public void requestApplications(Request request) {
if ("請假".equals(request.getRequestType()) && request.getNumber() <= 2){
System.out.println(String.format("%s%s請假%d被批準", name, request.getRequestContent(), request.getNumber()));
} else {
if (superior != null) {
superior.requestApplications(request);
}
}
}
}
3.新建Manager的子類Majordomo類,負責(zé)處理原Manager類中的第二個if條件分支
public class Majordomo extends Manager{
public Majordomo(String name) {
super(name);
}
@Override
public void requestApplications(Request request) {
if ("請假".equals(request.getRequestType()) && request.getNumber() <= 5){
System.out.println(String.format("%s%s請假%d被批準", name, request.getRequestContent(), request.getNumber()));
} else {
if (superior != null) {
superior.requestApplications(request);
}
}
}
}
4.新建Manager的子類GeneralManager類,負責(zé)處理原Manager類中的第三個if分支
public class GeneralManager extends Manager{
public GeneralManager(String name) {
super(name);
}
@Override
public void requestApplications(Request request) {
if ("請假".equals(request.getRequestType()) ){
System.out.println(String.format("%s%s請假%d被批準", name, request.getRequestContent(), request.getNumber()));
} else if ("加薪".equals(request.getRequestType()) && request.getNumber() <= 500){
System.out.println(String.format("%s%s數(shù)量%d被批準", name, request.getRequestContent(), request.getNumber()));
} else if ("加薪".equals(request.getRequestType()) && request.getNumber() > 500){
System.out.println(String.format("%s%s數(shù)量%d再說吧", name, request.getRequestContent(), request.getNumber()));
}
}
}
5.測試類
public class MainApp {
public static void main(String[] args) {
CommonManager jingli = new CommonManager("經(jīng)理");
Majordomo zongjian = new Majordomo("總監(jiān)");
GeneralManager zjingli = new GeneralManager("總經(jīng)理");
jingli.setSuperior(zongjian);
zongjian.setSuperior(zjingli);
Request request = new Request();
request.setRequestType("請假");
request.setRequestContent("秋秋請假");
request.setNumber(1);
jingli.requestApplications(request);
Request request2 = new Request();
request2.setRequestType("請假");
request2.setRequestContent("秋秋請假");
request2.setNumber(4);
jingli.requestApplications(request2);
Request request3 = new Request();
request3.setRequestType("加薪");
request3.setRequestContent("秋秋要加薪");
request3.setNumber(500);
jingli.requestApplications(request3);
Request request4 = new Request();
request4.setRequestType("加薪");
request4.setRequestContent("秋秋要加薪");
request4.setNumber(10000);
jingli.requestApplications(request4);
}
}
運行結(jié)果
經(jīng)理秋秋請假請假1被批準
總監(jiān)秋秋請假請假4被批準
總經(jīng)理秋秋要加薪數(shù)量500被批準
總經(jīng)理秋秋要加薪數(shù)量10000再說吧
從Manager類的改造結(jié)果來看,原來Manager類的條件分支被均勻的分散到新Manager類的三個子類中,新的Manager的三個子類中又相繼調(diào)用了條件分支的下一個子類,最終三個子類串聯(lián)起來,形成了一個責(zé)任鏈。這樣每個子類所承擔(dān)的職責(zé)僅有一個if條件分支,職責(zé)單一,如果要新增新的條件分支,比如新增總經(jīng)理秘書的分支,此時只需要新建一個Manager的子類,總經(jīng)理秘書類,即可完成新分支的創(chuàng)建,不會修改原來的分支,符合開閉原則。
3.總結(jié)
責(zé)任鏈中最關(guān)鍵的就是,當(dāng)客戶提交一個請求的時候,請求是沿著鏈傳遞下去的,直到有一個對象來處理這個請求。請求者不用管哪個對象來處理,反正請求最終會被這個責(zé)任鏈給處理掉。
這就使得接收者和發(fā)送者都沒有對方的明確信息,且鏈中的對象自己也并不知道鏈的結(jié)構(gòu)。結(jié)果是責(zé)任鏈可以簡化為對象的相互連接,它們僅需保持一個指向其后繼者的引用,而不需要保持它所有的候選接受者的引用,這就大大降低了耦合度。
由于鏈式結(jié)構(gòu)是在客戶端定義的,所以客戶端可以隨時地增加或修改處理一個請求的結(jié)構(gòu),增強了給對象指派職責(zé)的靈活性。
不過責(zé)任鏈處理也要考慮全面,防止某個請求一直到鏈的末端都沒有被正確處理。文章來源:http://www.zghlxwxcb.cn/news/detail-608875.html
以上就是責(zé)任鏈模式的內(nèi)容了,責(zé)任鏈這個名字聽著高大上,但其實原理還是很簡單的,不要被名字嚇到。文章來源地址http://www.zghlxwxcb.cn/news/detail-608875.html
到了這里,關(guān)于Java設(shè)計模式-責(zé)任鏈模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!