设计模式(十四)行为型模式---访问者模式(visitor)

2024-06-02 22:20

本文主要是介绍设计模式(十四)行为型模式---访问者模式(visitor),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 访问者模式简介
  • 分派的分类
  • 什么是双分派?
  • 结构
  • UML图
  • 具体实现
    • UML图
    • 代码实现
  • 优缺点

访问者模式简介

  • 访问者模式(visitor pattern)是封装一些作用于某种数据结构中的元素的操作,它可以在不改变这个数据结构(实现例子中的、男女)的前提下,定义作用于这些原则新的操作(实现例子中的成功、失败、待定等结果)。

分派的分类

  • 静态分派:就是程序编译的时候,根据参数类型就可以确定的分派。
  • 动态分派:因为参数是父类或者接口,具体由谁执行需要根据接口传入参数具体类型确定的分派。

什么是双分派?

  • 双分派:就是经历两次上面的分派过程就是双分派。

结构

  • 1.抽象访问者角色(Visitor):定义了对每一个原色(Element)访问的行为,他的参数就是可以访问的元素,他的方法个数理论上和元素个数是一致的,所以访问者模式要求元素类的个数不能改变。
  • 2.具体访问者角色(Concrete Visitor):给出对每一个元素访问时所产生的具体行为(demo中的成功、失败、待定)
  • 3.抽象元素角色(Element):定义了一个接受访问者的方法(accept),其意思就是每一个元素都可以被访问者访问。
  • 4.具体元素就角色(Concrete Element):提供了接受访问方法的具体实现,这个具体实现,通常情况下是使用访问者提供的访问该元素的方法。
  • 5.对象结构角色(Object Structure):可以理解为具体元素的存储容器。

UML图

在这里插入图片描述

具体实现

例子:好声音,对男女选手进行评审。

UML图

在这里插入图片描述

代码实现

  • 抽象元素角色
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 抽象元素角色 提供一个方法让访问者可以访问* @date 2024/5/26 0:18*/
public abstract class Person {/*** @description  提供给访问者访问的防方法,访问者通过参数传递进来。* @author  xxliao* @date  2024/5/26 0:28*/public abstract void result(ActionVisitor actionVisitor);
}
  • 具体元素角色
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 具体元素角色,接受一个访问者方法* @date 2024/5/26 0:18*/
public class Man extends Person{/*** @description  具体元素角色提供给访问者的防方法,访问者通过参数传递进来* @author  xxliao* @date  2024/5/26 0:29*/@Overridepublic void result(ActionVisitor actionVisitor) {// 访问者对象 获取 本元素(man)对象的结果,将本对象自己传递进去,这里使用了双分派actionVisitor.getManResult(this);}
}
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 具体元素角色* @date 2024/5/26 0:19*/
public class Woman extends Person{/*** @description  具体元素角色提供给访问者的防方法,访问者通过参数传递进来* @author  xxliao* @date  2024/5/26 0:29*/@Overridepublic void result(ActionVisitor actionVisitor) {// 访问者对象 获取 本元素(woman)对象的结果,将本对象自己传递进去,这里使用了双分派actionVisitor.getWomanResult(this);}
}
  • 抽象访问者角色
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 抽象访问者角色,角色内定义访问方法,一般来说要包括所有的具体抽象元素* @date 2024/5/26 0:18*/
public abstract class ActionVisitor {/*** @description  Man get result* @author  xxliao* @date  2024/5/26 0:20*/public abstract void getManResult(Man man);/*** @description  Woman get result* @author  xxliao* @date  2024/5/26 0:20*/public abstract void getWomanResult(Woman woman);
}
  • 具体访问者角色
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 具体访问者角色 -成功* @date 2024/5/26 0:22*/
public class SuccessActionVisitor extends ActionVisitor{@Overridepublic void getManResult(Man man) {System.out.println("man --- success");}@Overridepublic void getWomanResult(Woman woman) {System.out.println("woman --- success");}
}
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 具体访问者角色 -失败* @date 2024/5/26 0:22*/
public class FailActionVisitor extends ActionVisitor{@Overridepublic void getManResult(Man man) {System.out.println("man --- fail");}@Overridepublic void getWomanResult(Woman woman) {System.out.println("woman --- fail");}
}
  • 对象结构角色
package com.xxliao.pattern.behavioral.visitor.demo;import java.util.LinkedList;
import java.util.List;/*** @author xxliao* @description: 对象结构,需要定义存储具体元素角色的容器,然后* @date 2024/5/26 0:24*/
public class ObjectStructure {// 定义存储具体元素对象的容器private List<Person>  persons = new LinkedList<>();// 添加具体元素对象public void addPerson(Person person) {persons.add(person);}// 移除具体元素对象public void removePerson(Person person) {persons.remove(person);}/*** @description  显示最后结果* @author  xxliao* @date  2024/5/26 0:35*/public void print(ActionVisitor actionVisitor){for (Person person : persons) {person.result(actionVisitor);}}
}
  • 测试客户端
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 访问者模式 测似客户端* @date 2024/5/26 0:36*/
public class Client {public static void main(String[] args) {// 创建 对象结构ObjectStructure objectStructure = new ObjectStructure();// 添加具体元素对象objectStructure.addPerson(new Man());objectStructure.addPerson(new Woman());// 创建访问者具体对象 --成功SuccessActionVisitor successActionVisitor = new SuccessActionVisitor();// 对象结构 显示最后结果objectStructure.print(successActionVisitor);}
}
  • 测试结果
    在这里插入图片描述

优缺点

  • 优点:.在元素个数不变的情况下,增加新功能(具体访问者对象),做到了开闭原则。
  • 缺点:在元素个数要变化的情况下,所有的具体访问者对象都要修改代码, 不符合开闭原则。

这篇关于设计模式(十四)行为型模式---访问者模式(visitor)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1025254

相关文章

如何开启和关闭3GB模式

https://jingyan.baidu.com/article/4d58d5414dfc2f9dd4e9c082.html

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser

从《深入设计模式》一书中学到的编程智慧

软件设计原则   优秀设计的特征   在开始学习实际的模式前,让我们来看看软件架构的设计过程,了解一下需要达成目标与需要尽量避免的陷阱。 代码复用 无论是开发何种软件产品,成本和时间都最重要的两个维度。较短的开发时间意味着可比竞争对手更早进入市场; 较低的开发成本意味着能够留出更多营销资金,因此能更广泛地覆盖潜在客户。 代码复用是减少开发成本时最常用的方式之一。其意图

Builder模式的实现

概念 在创建复杂对象时,将创建该对象的工作交给一个建造者,这个建造者就是一个Builder。在日常的开发中,常常看到,如下这些代码: AlertDialog的实现 AlertDialog.Builder builder = new AlertDialog.Builder(context);builder.setMessage("你好建造者");builder.setTitle

[分布式网络通讯框架]----ZooKeeper下载以及Linux环境下安装与单机模式部署(附带每一步截图)

首先进入apache官网 点击中间的see all Projects->Project List菜单项进入页面 找到zookeeper,进入 在Zookeeper主页的顶部点击菜单Project->Releases,进入Zookeeper发布版本信息页面,如下图: 找到需要下载的版本 进行下载既可,这里我已经下载过3.4.10,所以以下使用3.4.10进行演示其他的步骤。

《分析模式》“鸦脚”表示法起源,Everest、Barker和Hay

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 《分析模式》这本书里面用的并不是UML表示法。作者Martin Fowler在书中也说了,该书写于1994-1995年,当时还没有UML。作者在书中用的是一种常被人称为“鸦脚”的表示法。  有的同学会有误解,例如有同学发表以下感想: “鸦脚”表示法当然不是Fowler先使用的。F

[最全]设计模式实战(一)UML六大原则

UML类图 UML类图是学习设计模式的基础,学习设计模式,主要关注六种关系。即:继承、实现、组合、聚合、依赖和关联。 UML类图基本用法 继承关系用空心三角形+实线来表示。实现接口用空心三角形+虚线来表示。eg:大雁是最能飞的,它实现了飞翔接口。 关联关系用实线箭头来表示。当一个类"知道"另一个类时,可以用关联。eg:企鹅需要"知道"气候的变化,需要"了解"气候规律。 聚合关

设计模式学习之中介者模式

我们平时写代码的过程,一个类必然会与其他类产生依赖关系,如果这种依赖关系如网状般错综复杂,那么必然会影响我们的代码逻辑以及执行效率,适当地使用中介者模式可以对这种依赖关系进行解耦使逻辑结构清晰,本篇博客,我们就一起学习中介者模式。 定义及使用场景 定义:中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使它们可以松散耦合。当某些对象之间的作用发生改变时,不会立即影响其