20-訪問者模式

訪問者模式

一、定義

封裝一些作用於某種數據結構中的各元素的操作,它可以在不改變數據結構的前提下定義作用於這些元素的新的操作

通用類圖
在這裏插入圖片描述
Visitor是抽象訪問者,聲明訪問者可以訪問那些元素,在程序中visit方法的參數定義那些對象是可以被訪問的;ConcreteVisitor是具體訪問者,它定義訪問者訪問到一個類後要做什麼事情;Element是抽象元素,生命接收哪一些類訪問者訪問,通過accept方法中的參數定義;ConcreteElement是具體元素,實現accept方法,通常是visitor.visit(this);ObjectStruture是結構對象,是元素產生着,一般容納在多個不同類、不同接口的容器。在項目
中,一般很少抽象出這個角色

訪問者模式通用源碼

  1. 抽象元素

    public abstract class Element {
        //定義業務邏輯
        public abstract void doSomething();
        //允許誰來訪問
        public abstract void accept(IVisitor visitor);
    }
    
  2. 具體元素

    public class ConcreteElement1 extends Element{
        //完善業務邏輯
        public void doSomething(){
            //業務處理
        }
        //允許那個訪問者訪問
        public void accept(IVisitor visitor){
            visitor.visit(this);
        }
        }
        public class ConcreteElement2 extends Element{
            //完善業務邏輯
            public void doSomething(){
            //業務處理
        }
        //允許那個訪問者訪問
        public void accept(IVisitor visitor){
            visitor.visit(this);
        }
    }
    
  3. 抽象訪問者

    public interface IVisitor {
        //可以訪問哪些對象
        public void visit(ConcreteElement1 el1);
        public void visit(ConcreteElement2 el2);
    }
    
  4. 具體訪問者

    public class Visitor implements IVisitor {
        //訪問el1元素
        public void visit(ConcreteElement1 el1) {
            el1.doSomething();
        }
        //訪問el2元素
        public void visit(ConcreteElement2 el2) {
            el2.doSomething();
        }
    }
    
  5. 結構對象

    public class ObjectStruture {
        //對象生成器,這裏通過一個工廠方法模式模擬
        public static Element createElement(){
            Random rand = new Random();
            
            if(rand.nextInt(100) > 50){
                return new ConcreteElement1();
            }else{
                return new ConcreteElement2();
            }
        }
    }
    
  6. 場景類

public class Client {
    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            //獲得元素對象
             Element el = ObjectStruture.createElement();
            //接受訪問者訪問
            el.accept(new Visitor());
        }
    }
}

二、訪問者模式的優點

  • 符合單一職責原則

    具體元素角色負責數據的加載,Visitor類負責報表的展現,兩個不同的職責分離開,各自演繹變化。

  • 優秀的擴展性

    由於職責分開,繼續增加對數據的操作是非常快捷的。

  • 靈活度非常高

三、訪問者模式的缺點

  • 具體元素(ConcreteElement)對訪問者公佈細節

    訪問者要訪問一個類就必須瞭解其內部細節,不符合迪米特法則

  • 具體元素變更比較困難

    具體元素的增加、刪除、修改需要對修改所有的Visitor

  • 違背了依賴倒置原則

    訪問者依賴的是具體元素,而不是抽象元素,破壞了依賴倒置原則,擴展比較難

四、訪問則模式的的使用場景

  • 一個對象結構包含很多類對象,他們有不同的接口,而你想對這些對象實施一些依賴於其具體類的操作(對不同類型的對象執行不同的操作),也就會說用迭代器模式已經不能勝任的場景。

  • 需要對一個對象結構中的對象進行很多不同並且不相關的操作,而你想避免讓這些操作”污染“這些對象的類

    即 業務規則要求遍歷多個不同的對象時。迭代器模式只能訪問同類或同接口的數據,而訪問者模式是對迭代器模式的擴充,可以遍歷不同的對象,然後執行不同的操作,也就是針對訪問的對象不同,執行不同的操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章