访问者模式

简介: 《大话设计模式》阅读笔记和总结。原书是C#编写的,本人用Java实现了一遍,包括每种设计模式的UML图实现和示例代码实现。目录:设计模式Github地址:DesignPattern说明定义:访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。

《大话设计模式》阅读笔记和总结。原书是C#编写的,本人用Java实现了一遍,包括每种设计模式的UML图实现和示例代码实现。
目录:设计模式
Github地址:DesignPattern

说明

定义:访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

UML图:

img_3b2c8ac8d738a1c682ba09d2b617683d.png
访问者模式UML图.png

代码实现:

Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作

abstract class Visitor{
    public abstract void VisitConcreteElementA(ConcreteElementA elementA);
    public abstract void VisitConcreteElementB(ConcreteElementB elementB);
}

ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每个由Visitor声明的操作。每个操作实现算法的一部分,而该算法片段是对应于结构中对象的类

class ConcreteVisitor1 extends Visitor {

    @Override
    public void VisitConcreteElementA(ConcreteElementA concreteElementA) {
        System.out.println(concreteElementA.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
    }

    @Override
    public void VisitConcreteElementB(ConcreteElementB concreteElementB) {
        System.out.println(concreteElementB.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
    }

}

class ConcreteVisitor2 extends Visitor {

    @Override
    public void VisitConcreteElementA(ConcreteElementA concreteElementA) {
        System.out.println(concreteElementA.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
    }

    @Override
    public void VisitConcreteElementB(ConcreteElementB concreteElementB) {
        System.out.println(concreteElementB.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
    }

}

Element类,定义一个Accept操作,它以一个访问者为参数

abstract class Element{
    public abstract void Accept(Visitor visitor);
}

ConcreteElementA和ConcreteElementB类,具体元素,实现Accept操作

class ConcreteElementA extends Element{

    @Override
    public void Accept(Visitor visitor) {
        visitor.VisitConcreteElementA(this);
    }

    public void OperationA(){

    }
}

class ConcreteElementB extends Element{

    @Override
    public void Accept(Visitor visitor) {
        visitor.VisitConcreteElementB(this);
    }

    public void OperationB(){

    }
}

ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素

class ObjectStructure{
    private List<Element> elements = new ArrayList<>();
    public void Attach(Element element){
        elements.add(element);
    }
    public void Detach(Element element){
        elements.remove(element);
    }
    public void Accept(Visitor visitor){
        for (Element e :elements) {
            e.Accept(visitor);
        }
    }
}

客户端代码

public class VisitorPattern {
    public static void main(String[] args){
        ObjectStructure o = new ObjectStructure();
        o.Attach(new ConcreteElementA());
        o.Attach(new ConcreteElementB());

        ConcreteVisitor1 v1 = new ConcreteVisitor1();
        ConcreteVisitor2 v2 = new ConcreteVisitor2();

        o.Accept(v1);
        o.Accept(v2);
    }
}

运行结果

ConcreteElementA被ConcreteVisitor1访问
ConcreteElementB被ConcreteVisitor1访问
ConcreteElementA被ConcreteVisitor2访问
ConcreteElementB被ConcreteVisitor2访问

示例

例子:程序要求实现当男人和女人在不同状态下的反应。

男人成功时,背后多半有一个伟大的女人。
女人成功时,背后多半有一个伟大的男人。
男人失败时,闷头喝酒,谁也不用劝。
女人失败时,眼泪汪汪,谁也劝不了。
男人恋爱时,凡是不懂也要装懂。
女人恋爱时,遇事懂也装作不懂。
男女对比这么多的原因就是因为人类在性别上就只有男人和女人两类。

UML图:

img_c5acd55cc7017a5c1725f1c1210c8753.png
访问者模式示例UML图.png

代码实现:

抽象元素

public abstract class Person {
    public abstract void Accept(Action action);
}

男人

public class Man extends Person{

    @Override
    public void Accept(Action action) {
        action.GetManConclusion(this);
    }

}

女人

public class Woman extends Person{

    @Override
    public void Accept(Action action) {
        action.GetWomanConclusion(this);
    }

}

抽象状态类

public abstract class Action {
    public abstract void GetManConclusion(Person man);

    public abstract void GetWomanConclusion(Person woman);

}

成功状态

public class Success extends Action{

    @Override
    public void GetManConclusion(Person man) {
        System.out.println("男人成功时");
    }

    @Override
    public void GetWomanConclusion(Person woman) {
        System.out.println("女人成功时");
    }

}

失败状态

public class Failing extends Action{

    @Override
    public void GetManConclusion(Person man) {
        System.out.println("男人失败时");
    }

    @Override
    public void GetWomanConclusion(Person woman) {
        System.out.println("女人失败时");
    }

}

恋爱状态

public class Amativeness extends Action {

    @Override
    public void GetManConclusion(Person man) {
        System.out.println("男人恋爱时");
    }

    @Override
    public void GetWomanConclusion(Person woman) {
        System.out.println("女人恋爱时");
    }

}

结婚状态

public class Marriage extends Action{

    @Override
    public void GetManConclusion(Person man) {
        System.out.println("男人结婚时...");

    }

    @Override
    public void GetWomanConclusion(Person woman) {
        System.out.println("女人结婚时...");
    }

}

对象结构,用于访问男,女元素

public class PersonObjectStructure {
    //对象结构,用于访问男,女元素
    private List<Person> list = new ArrayList<>();

    public void Attach(Person person) {
        list.add(person);
    }

    public void Detach(Person person) {
        list.remove(person);
    }

    public void Display(Action action) {
        for (Person person : list) {
            person.Accept(action);
        }
    }

}

客户端代码

public class Main {
    public static void main(String[] args) {
        PersonObjectStructure objectStructure=new PersonObjectStructure();
        objectStructure.Attach(new Man());
        objectStructure.Attach(new Woman());

        //看男人和女人在成功时的状态
        Success success=new Success();
        objectStructure.Display(success);

        //新增一个结婚状态
        Marriage marriage=new Marriage();
        objectStructure.Display(marriage);
    }
}

运行结果

男人成功时
女人成功时
男人结婚时...
女人结婚时...
目录
相关文章
|
4月前
|
设计模式 Java 容器
聊聊Java设计模式-访问者模式
访问者模式(Visitor Pattern)指将作用域某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作。
29 3
|
5月前
|
算法
行为型 访问者模式
行为型 访问者模式
18 0
|
6月前
访问者模式
访问者模式
32 0
访问者模式
|
7月前
|
设计模式 算法 BI
设计模式~访问者模式(Visitor)-15
在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对
27 0
|
9月前
|
设计模式 Java uml
|
10月前
|
设计模式 Java 关系型数据库
访问者模式解读
访问者模式解读
|
11月前
今天说说你不知道的访问者模式
今天说说你不知道的访问者模式
56 0
|
设计模式 程序员
访问者模式是啥?咋实现呀?
访问者模式是啥?咋实现呀?
|
设计模式 Java Spring
Java设计模式 ->访问者模式
Java设计模式 ->访问者模式
80 0
|
设计模式
我学会了,访问者模式
访问者模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。
89 0
我学会了,访问者模式