首页 > 其他分享 >访问者模式

访问者模式

时间:2023-03-05 21:34:01浏览次数:35  
标签:定义 void 模式 accept 操作 public 访问者

访问者模式

应用场景 (实际问题需求) 与 传统实现方式

例如:
完成一个测评系统:
  将观众分为男人和女人, 对歌手进行测评,当看完某个歌手表演后,得到他们对该歌手不同的评价(评价分不同种类,例如: 成功 失败 等)


传统实现:将评价操作直接定义在男人,女人类中。

传统实现的问题:
1. 不利于维护。
2. 扩展性不好,增加 新的人员类型 , 或者管理方法,导致改动大。

引入访问者设计模式

1. 定义

​ 在访问者模式中, 使用一个访问者接口, 通过定义不同的访问者接口实现类,可以改变被访问者的执行操作,通过这种方式,被访问者的执行算法可以随着访问者改变而改变。此时访问者相当于被访问者可以执行(展示)出的不同种类的操作。

根据模式,被访问对象接收访问者对象(accept方法中参数是访问者对象),通过回调访问者对象中的不同方法,被访问者就可以展示出不同的操作。

这种类型的设计模式属于行为型模式。

2. 意图

主要是将数据结构和数据操作分离。

解决数据结构和操作耦合性问题。

它使你可以在不改变 被访问者类的前提下 扩展被访问者类的不同的操作。

原理类图

在这里插入图片描述

剖析原理 (主要角色及职责)

模式中存在的角色:
	visitor:抽象访问者,为该对象结构中的ConcreteElement的每一个类声明一个visit操作。
	ConcreteVisitor: 一个具体的访问者类,实现每个由Visitor声明的操作,是每个操作实现的部分。
	ObjectStructure: 能枚举Element的元素, 提供一个高层的接口,用来允许访问者访问元素。
	Element : 定义一个accept方法,接收一个访问者对象。
	ConcreteElement: 继承或实现Element,是具体元素,实现 accept方法(调用操作)。

分析实现步骤

先确定 访问者(ConcreteVisitor) 和 被访问者(ConcreteElement) 是哪些:
1. 定义上层Visitor接口 抽象访问者,添加对ConcreteElement的每一个类不同的visit操作。
2. 定义Element 接口,定义 accept方法 表示接受访问者访问。
3. 定义不同的ConcreteVisitor类,每个类代表了不同的操作,实现Visitor 实现 visit 操作。
4. 定义不同的ConcreteElement类,每个类代表了不同的被访问者,操作调用者(接收访问)。实现Element的accept方法。
5. 定义ObjectStructure类:用于管理访问者(ConcreteVisitors)去访问被访问者(ConcreteElements),通常将被访问者放入集合中使用。
6. 定义Client类 用于访问ObjectStructure 进行测试。

代码实现

// 访问者 :  失败 和 成功(测评操作) , 被访问者 : 男人 女人 (观众)

// 定义 Visitor 抽象类 / 接口
public abstract class Action {
    // 对于不同被访问者 执行 不同操作
    abstract void getResult(Man man);
    abstract void getResult(Woman woman);
}
// 定义 Element 抽象类 / 接口
public abstract class Person {
    // 表示接受访问
    abstract void accept(Action action);
}

// 定义 不同的ConcreteVisitor , 不同的ConcreteVisitor定义对于不同的ConcreteElements进行不同的操作
// 定义 success时的操作
public class Success extends Action{
    // success时,对男人的操作
    @Override
    void getResult(Man man) {
        System.out.println("man say success");
    }
    // success时,对女人的操作
    @Override
    void getResult(Woman woman) {
        System.out.println("woman say success");
    }
}
// 定义 Fail时的操作
public class Fail extends Action{
	// Fail时,对男人的操作
    @Override
    void getResult(Man man) {
        System.out.println("man say fail");
    }
	// Fail时,对女人的操作
    @Override
    void getResult(Woman woman) {
        System.out.println("woman say fail");
    }
}
// 定义被访问者 , 实现 accept 操作
// 定义 man, 实现 accept
public class Man extends Person{
    // 表示接受访问者(Action), 通过访问者调用 需要执行的操作
    @Override
    void accept(Action action) {
        action.getResult(this); // 传入 this , 通过本身数据类型,调用action中不同的getResult重载方法。
    }
}
// 定义woman,实现 accept
public class Woman extends Person{
     // 表示接受访问者(Action), 通过访问者调用 需要执行的操作
    @Override
    void accept(Action action) {
        action.getResult(this);
    }
}

// 定义ObjectStructure , 从高层进行访问者访问操作
public class ObjectStructure {
    /**
     * 维护了一个集合
     */
    private List<Person> list = new ArrayList<>();
	// 向集合中添加被访问者元素
    public void attach(Person p) {
        list.add(p);
    }
	// 从集合中移除被访问者元素
    public void detach(Person p) {
        list.remove(p);
    }
	// action 访问 被访问者 , 在 Client 中传入不同的访问者 , 执行不同操作
    public void display(Action action) {
        for (Person person : list) {
            person.accept(action);
        }
    }
}

// Client 调用测试
public class Client {
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();

        objectStructure.attach(new Man());
        objectStructure.attach(new Woman());

        Success success = new Success();
        objectStructure.display(success);

		// 直接添加一个 Wait(评价待定) 类 , 就可以进行不同的操作。
        Wait wait = new Wait();
        objectStructure.display(wait);
    }
}
// 添加Wait类
public class Wait extends Action{
    /**
     * man的 wait评价 方法
     * @param man 传入 Person子类 man
     */
    @Override
    void getResult(Man man) {
        System.out.println("man say wait");
    }
    /**
     * woman的 wait评价方法
     * @param woman 传入Person子类 woman
     */
    @Override
    void getResult(Woman woman) {
        System.out.println("woman say wait");
    }
}

总结

访问者模式主要应用场景:需要对一个(Elements)对象结构中的对象进行很多不同类型操作(这些操作彼此没有关联),同时需要避免让 这些频繁修改增添的操作 直接写在这些类中,可以使用访问者模式。

标签:定义,void,模式,accept,操作,public,访问者
From: https://www.cnblogs.com/oneblogs/p/17181734.html

相关文章

  • 设计模式-javascript实现【迭代器模式】
    定义:迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之......
  • Book-深入设计模式-适配器模式
    Book-深入设计模式-适配器模式https://refactoringguru.cn/design-patterns/adapter适配器模式亦称:封装器模式、Wrapper、Adapter适配器模式是一种结构型设计模式,它......
  • Book-深入设计模式-单例模式
    Book-深入设计模式-单例模式https://refactoringguru.cn/design-patterns/singleton单例模式亦称:单件模式、Singleton单例模式是一种创建型设计模式,让你能够保证一个......
  • Book-深入设计模式-原型模式
    Book-深入设计模式-原型模式https://refactoringguru.cn/design-patterns/prototype原型模式亦称:克隆、Clone、Prototype原型模式是一种创建型设计模式,使你能够复制......
  • Book-深入设计模式-生成器模式
    Book-深入设计模式-生成器模式https://refactoringguru.cn/design-patterns/builder生成器模式亦称:建造者模式、Builder生成器模式是一种创建型设计模式,使你能够分步......
  • Book-深入设计模式-抽象工厂模式
    Book-深入设计模式-抽象工厂模式https://refactoringguru.cn/design-patterns/abstract-factory抽象工厂模式亦称:AbstractFactory抽象工厂模式是一种创建型设计模式,......
  • Book-深入设计模式-工厂方法模式
    Book-深入设计模式-工厂方法模式https://refactoringguru.cn/design-patterns/factory-method工厂方法模式亦称:虚拟构造函数、VirtualConstructor、FactoryMethod工......
  • MySQL中三级模式和二级映像指的是什么?
    MySQL中三级模式和二级映像指的是什么?更新时间:2022-06-09来源:黑马程序员浏览量:2354美国国家标准学会(AmericanNationalStandardsInstitute,ANSI)所属的标准计划......
  • 《设计模式之禅》Strategy_Pattern--策略模式
    写在前面设计模式之禅这本书也是博主看了几本设计模式的开头才决定以这本书作为学习设计模式的资料。像小傅哥的重学Java设计模式,好处是以真实的项目案例的逻辑来搭配设计模......
  • ThinkPHP MVC模式、URL访问控制器和调试模式
    一、什么是MVCM-Model编写model类对数据进行操作V-View编写html文件,页面呈现C-Controller编写类文件(UserAction.class.php)处理输入(写入数据库记录),确保M和V的同步......