大話設計模式筆記(二十五)の訪問者模式

訪問者模式

定義

表示一個做用於某對象結構中的各元素的操做。它使你能夠在不改變各元素的類的前提下定義做用於這些元素的新操做。算法

UML圖

特色

  • 訪問者模式適用於數據結構相對穩定的系統,它把數據和做用於結構上的操做之間的耦合解脫開,使得操做集合能夠相對自由的演化
  • 訪問者模式的目的是要把處理從數據結構分離出來
  • 若是有比較穩定的數據結構,又易於變化的算法的話,使用訪問者模式就是比較合適的,由於訪問者模式使得算法操做的增長變得容易
  • 訪問者模式的優勢就是增長新的操做很容易,由於增長新的操做就意味着增長一個新的訪問者。訪問者模式將有關的行爲集中到一個訪問者對象中
  • 訪問者的缺點其實也就是使增長新的數據結構變得困難。

舉個栗子

人,分爲男人和女人,分別描述他/她成功、失敗、戀愛時的不一樣緣由。。。數據結構

UML圖

Talk is cheap, show me the code

(屁話少說,放碼過來)

/**
 * 狀態
 * Created by callmeDevil on 2019/12/22.
 */
public abstract class Action {
    // 獲得男人結論或反應
    public abstract void getManConclusion(Man concreteElementA);
    // 獲得女人結論或反應
    public abstract void getWomanConclusion(Woman concreteElementB);
}
/**
 * 成功
 * Created by callmeDevil on 2019/12/22.
 */
public class Success extends Action {

    @Override
    public void getManConclusion(Man concreteElementA) {
        System.out.println(String.format("%s %s時,背後多半有一個偉大的女人。",
                concreteElementA.getClass().getSimpleName(), this.getClass().getSimpleName()));
    }

    @Override
    public void getWomanConclusion(Woman concreteElementB) {
        System.out.println(String.format("%s %s時,背後多半有一個不成功的男人。",
                concreteElementB.getClass().getSimpleName(), this.getClass().getSimpleName()));
    }

}
/**
 * 失敗
 * Created by callmeDevil on 2019/12/22.
 */
public class Failing extends Action {

    @Override
    public void getManConclusion(Man concreteElementA) {
        System.out.println(String.format("%s %s時,背後多半有一個不偉大的女人。",
                concreteElementA.getClass().getSimpleName(), this.getClass().getSimpleName()));
    }

    @Override
    public void getWomanConclusion(Woman concreteElementB) {
        System.out.println(String.format("%s %s時,背後多半有一個成功的男人。",
                concreteElementB.getClass().getSimpleName(), this.getClass().getSimpleName()));
    }

}
/**
 * 戀愛
 * Created by callmeDevil on 2019/12/22.
 */
public class Amativeness extends Action {

    @Override
    public void getManConclusion(Man concreteElementA) {
        System.out.println(String.format("%s %s時,背後多半是個高富帥。",
                concreteElementA.getClass().getSimpleName(), this.getClass().getSimpleName()));
    }

    @Override
    public void getWomanConclusion(Woman concreteElementB) {
        System.out.println(String.format("%s %s時,背後多半是個會打扮。",
                concreteElementB.getClass().getSimpleName(), this.getClass().getSimpleName()));
    }

}
/**
 * 人
 * Created by callmeDevil on 2019/12/22.
 */
public abstract class Person {
    // 接受
    public abstract void accept(Action visitor);
}
/**
 * 男人
 * Created by callmeDevil on 2019/12/22.
 */
public class Man extends Person{
    @Override
    public void accept(Action visitor) {
        // 首先在客戶端程序中將具體狀態做爲參數傳遞給「男人」類完成了一次分派,而後「男人」類調用
        // 做爲參數的「具體狀態」中的方法「男人反應」,同時將本身(this)做爲參數傳遞進去,這便完成
        // 了第二次分派。這種技術手段稱爲「雙分派」。
        visitor.getManConclusion(this);
    }
}
/**
 * 女人
 * Created by callmeDevil on 2019/12/22.
 */
public class Woman extends Person{
    @Override
    public void accept(Action visitor) {
        visitor.getWomanConclusion(this);
    }
}
/**
 * 對象結構
 * Created by callmeDevil on 2019/12/22.
 */
public class ObjectStructure {

    private List<Person> elements = new ArrayList<>();

    // 增長
    public void attach(Person element) {
        elements.add(element);
    }

    // 移除
    public void detach(Person element) {
        elements.remove(element);
    }

    // 查看顯示
    public void display(Action visitor) {
        for (Person element : elements) {
            element.accept(visitor);
        }
    }

}
public class Test {
    public static void main(String[] args) {
        ObjectStructure obj = new ObjectStructure();
        // 對象結構中加入要對比的男人和女人
        obj.attach(new Man());
        obj.attach(new Woman());

        // 成功的反應
        Success success = new Success();
        obj.display(success);

        // 失敗的反應
        Failing failing = new Failing();
        obj.display(failing);

        // 戀愛的反應
        Amativeness amativeness = new Amativeness();
        obj.display(amativeness);
    }
}

運行結果ide

Man Success時,背後多半有一個偉大的女人。
Woman Success時,背後多半有一個不成功的男人。
Man Failing時,背後多半有一個不偉大的女人。
Woman Failing時,背後多半有一個成功的男人。
Man Amativeness時,背後多半是個高富帥。
Woman Amativeness時,背後多半是個會打扮。
相關文章
相關標籤/搜索