天天看點

設計模式-責任鍊模式(Chain of Responsibility Pattern)

推薦:​​Java設計模式彙總​​

責任鍊模式

定義

為請求建立一個接收者對象的鍊。這種模式給予請求的類型,對請求的發送者和接收者進行解耦。

類型

行為型。

UML類圖

設計模式-責任鍊模式(Chain of Responsibility Pattern)

角色

  • 抽象處理者(BaseHandler)角色:定義處理請求的接口,并且有接下來要處理請求的處理者的引用。
  • 具體處理者(ConcreteHandler)角色:實作抽象處理者角色中處理請求的接口。

例子

慕課網講師上線新課程時,慕課網從業人員需要檢查資料是否齊全,将檢查的過程當作是鍊式的,比如先檢查是否有課程手記,當有課程手記時,再檢查是否有課程視訊。

Course類,課程類。

package com.kaven.design.pattern.behavioral.chainofresponsibility;

public class Course {
    private String name;
    private String article;
    private String video;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getArticle() {
        return article;
    }

    public void setArticle(String article) {
        this.article = article;
    }

    public String getVideo() {
        return video;
    }

    public void setVideo(String video) {
        this.video = video;
    }

    @Override
    public String toString() {
        return "Course{" +
                "name='" + name + '\'' +
                ", article='" + article + '\'' +
                ", video='" + video + '\'' +
                '}';
    }
}      

Approver類(抽象處理者角色),​

​deploy()方法​

​​是抽象處理者角色定義的處理請求的接口,​

​approver屬性​

​​是接下來要處理請求的處理者的引用,​

​不要糾結類名​

​。

package com.kaven.design.pattern.behavioral.chainofresponsibility;

public abstract class Approver {
    protected Approver approver;

    public void setNextApprover(Approver approver){
        this.approver = approver;
    }
    public abstract void deploy(Course course);
}      

ArticleApprover類( 具體處理者角色),繼承了Approver類,實作了​

​deploy()方法​

​,檢查是否有手記,有手記就将課程給下一個檢查的處理者檢查。

package com.kaven.design.pattern.behavioral.chainofresponsibility;


import org.springframework.util.StringUtils;

public class ArticleApprover extends Approver {
    public void deploy(Course course) {
        if(!StringUtils.isEmpty(course.getArticle())) {
            System.out.println(course.getName() + "含有手記,準許");
            if (approver != null) {
                approver.deploy(course);
            }
        }
        else{
                System.out.println(course.getName()+"不包含手記,不準許");
                return ;
        }
    }
}      

VideoApprover類( 具體處理者角色),繼承了Approver類,實作了​

​deploy()方法​

​,檢查是否有視訊,有視訊就将課程給下一個檢查的處理者檢查。

package com.kaven.design.pattern.behavioral.chainofresponsibility;

import org.springframework.util.StringUtils;

public class VideoApprover extends Approver {
    public void deploy(Course course) {
        if(!StringUtils.isEmpty(course.getVideo())){
            System.out.println(course.getName()+"含有視訊,準許");
            if(approver != null){
                approver.deploy(course);
            }
        }
        else{
            System.out.println(course.getName()+"不包含視訊,不準許");
            return ;
        }
    }
}      

應用層代碼1:

package com.kaven.design.pattern.behavioral.chainofresponsibility;

public class Test {
    public static void main(String[] args) {
        Approver articleApprover = new ArticleApprover();
        Approver videoApprover = new VideoApprover();

        Course course = new Course();
        course.setName("Java設計模式");
        course.setArticle("Java設計模式手記");
        course.setVideo("Java設計模式視訊");

        articleApprover.setNextApprover(videoApprover);

        articleApprover.deploy(course);
    }
}      

輸出:

Java設計模式含有手記,準許
Java設計模式含有視訊,準許      

應用層代碼2:

package com.kaven.design.pattern.behavioral.chainofresponsibility;

public class Test {
    public static void main(String[] args) {
        Approver articleApprover = new ArticleApprover();
        Approver videoApprover = new VideoApprover();

        Course course = new Course();
        course.setName("Java設計模式");
//        course.setArticle("Java設計模式手記");
        course.setVideo("Java設計模式視訊");

        articleApprover.setNextApprover(videoApprover);

        articleApprover.deploy(course);
    }
}      

輸出:

Java設計模式不包含手記,不準許      

應用層代碼3:

package com.kaven.design.pattern.behavioral.chainofresponsibility;

public class Test {
    public static void main(String[] args) {
        Approver articleApprover = new ArticleApprover();
        Approver videoApprover = new VideoApprover();

        Course course = new Course();
        course.setName("Java設計模式");
        course.setArticle("Java設計模式手記");
//        course.setVideo("Java設計模式視訊");

        articleApprover.setNextApprover(videoApprover);

        articleApprover.deploy(course);
    }
}      

輸出:

Java設計模式含有手記,準許
Java設計模式不包含視訊,不準許      

這裡便完成了一個簡單的責任鍊模式。

适用場景

  • 有多個對象可以處理同一個請求,具體哪個對象處理該請求由運作時刻自動确定。
  • 在不明确指定接收者的情況下,向多個對象中的一個送出一個請求。
  • 可動态指定一組對象處理請求。

優點

  • 請求者不需要知道處理者,也不需要知道如何處理。每個責任對象隻負責自己的責任範圍,其他的交給後繼者。各個元件間完全解耦。
  • 責任鍊模式會把功能分散到單獨的責任對象中,然後在使用時動态的組合形成鍊,進而可以靈活的配置設定責任對象,也可以靈活的添加責任對象。
  • 因為功能處理都分散到了單獨的責任對象中,每個責任對象功能單一,要把整個流程處理完,需要很多的責任對象,會産生大量的細粒度責任對象。
  • 每個責任對象都隻負責自己的部分,這樣就可能出現某個請求,即使把整個鍊走完,都沒有責任對象處理它。這就需要提供預設處理,并且注意構造鍊的有效性。