Java中的访问者设计模式–示例教程

访客模式行为设计模式之一 。 当我们必须对一组相似类型的对象执行操作时,将使用访问者模式。 借助访问者模式,我们可以将操作逻辑从对象移动到另一个类。

例如,假设有一个购物车,我们可以在其中添加不同类型的项目(元素),当我们单击“结帐”按钮时,它将计算要支付的总金额。 现在我们可以将计算逻辑包含在项目类中,或者可以使用访问者模式将此逻辑移到另一个类中。 让我们在访问者模式示例中实现此功能。

为了实现访客模式,首先,我们将创建用于购物车的不同类型的项目(元素)。

ItemElement.java

package com.journaldev.design.visitor;public interface ItemElement {public int accept(ShoppingCartVisitor visitor);
}

注意,accept方法接受Visitor参数,我们可以有一些其他特定于项目的方法,但为简单起见,我不打算讨论太多细节,而仅关注于访问者模式。

让我们为不同类型的项目创建一些具体的类。

Book.java

package com.journaldev.design.visitor;public class Book implements ItemElement {private int price;private String isbnNumber;public Book(int cost, String isbn){this.price=cost;this.isbnNumber=isbn;}public int getPrice() {return price;}public String getIsbnNumber() {return isbnNumber;}@Overridepublic int accept(ShoppingCartVisitor visitor) {return visitor.visit(this);}}

水果.java

package com.journaldev.design.visitor;public class Fruit implements ItemElement {private int pricePerKg;private int weight;private String name;public Fruit(int priceKg, int wt, String nm){this.pricePerKg=priceKg;this.weight=wt;this.name = nm;}public int getPricePerKg() {return pricePerKg;}public int getWeight() {return weight;}public String getName(){return this.name;}@Overridepublic int accept(ShoppingCartVisitor visitor) {return visitor.visit(this);}}

注意具体类中accept()方法的实现,它调用Visitor的visit()方法并将其自身作为参数传递。

我们在Visitor界面中具有针对不同项目类型的visit()方法,将由具体的visitor类实现。

ShoppingCartVisitor.java

package com.journaldev.design.visitor;public interface ShoppingCartVisitor {int visit(Book book);int visit(Fruit fruit);
}

现在,我们将实现访客界面,并且每个项目都有其自己的逻辑来计算费用。

ShoppingCartVisitorImpl.java

package com.journaldev.design.visitor;public class ShoppingCartVisitorImpl implements ShoppingCartVisitor {@Overridepublic int visit(Book book) {int cost=0;//apply 5$ discount if book price is greater than 50if(book.getPrice() > 50){cost = book.getPrice()-5;}else cost = book.getPrice();System.out.println("Book ISBN::"+book.getIsbnNumber() + " cost ="+cost);return cost;}@Overridepublic int visit(Fruit fruit) {int cost = fruit.getPricePerKg()*fruit.getWeight();System.out.println(fruit.getName() + " cost = "+cost);return cost;}}

让我们看看如何在客户端应用程序中使用它。

ShoppingCartClient.java

package com.journaldev.design.visitor;public class ShoppingCartClient {public static void main(String[] args) {ItemElement[] items = new ItemElement[]{new Book(20, "1234"),new Book(100, "5678"),new Fruit(10, 2, "Banana"), new Fruit(5, 5, "Apple")};int total = calculatePrice(items);System.out.println("Total Cost = "+total);}private static int calculatePrice(ItemElement[] items) {ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl();int sum=0;for(ItemElement item : items){sum = sum + item.accept(visitor);}return sum;}}

当我们运行上面的程序时,我们得到以下输出。

Book ISBN::1234 cost =20
Book ISBN::5678 cost =95
Banana cost = 20
Apple cost = 25
Total Cost = 160

注意,如果所有项目中的accept()方法的实现都是相同的,但是可以有所不同,例如,可以使用逻辑检查项目是否为空,那么根本不要调用visit()方法。

访客模式类图

我们的访客模式实现的类图是:

访客模式

这种模式的好处是,如果操作的逻辑发生了变化,那么我们只需要在访问者实现中进行更改,而不必在所有项目类中进行更改。

另一个好处是,将新项目添加到系统很容易,它将仅需要在访问者界面和实现中进行更改,而现有项目类别将不受影响。

访问者模式的缺点在于,在设计时我们应该知道visit()方法的返回类型,否则我们将不得不更改接口及其所有实现。 另一个缺点是,如果访问者接口的实现过多,则很难扩展。

参考: Java中的访问者设计模式 -JCG合作伙伴 Pankaj Kumar在开发人员食谱博客上的示例教程 。

翻译自: https://www.javacodegeeks.com/2013/08/visitor-design-pattern-in-java-example-tutorial.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367060.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

函数递归与二分法

1.什么是函数递归 函数的递归调用是函数嵌套调用的一种特殊形式, 特殊在调用一个函数的过程中又直接或者间接地调用了该函数本身 递归本质就是一个循环的过程, 但是递归必须满足两个原则: 1.每进入下一层递归,问题的规模必须有所减…

使用Oracle WebLogic创建部署计划

创建部署计划 部署计划是JSR-88部署标准的一部分,尽管在该标准中未明确说明。 部署计划是一个XML文档,用于定义自定义WebLogic Server部署环境。 此配置可用于覆盖在应用程序归档文件中定义的特定设置。 有许多原因可能导致您不希望修改应用程序存档的原…

记录一个前端架构的想法

前端,真的是让我哭笑不得的职业,从几年前作为打酱油的理想职业到现在的热门职业,无疑在这个过程中,门槛变高了,而且还是非常高。一大堆的框架和库,像什么vue啦、react啦、angular啦、webpack啦等等等等。让…

java 编程原理_Java网络编程 -- 网络编程基础原理

Hello,今天记录下 Java网络编程 --> 网络编程基础原理。一起学习,一起进步。继续沉淀,慢慢强大。希望这文章对您有帮助。若有写的不好的地方,欢迎评论给建议哈!初写博客不久,我是杨展浩。这是我的第十五…

JavaScript基础之--- 深拷贝与浅拷贝

理解深拷贝和浅拷贝之前,先来看一下JavaScript的数据类型。 1、基本类型和引用类型 //案例1 var num1 1, num2 num1; console.log(num1) //1 console.log(num2) //1 num2 2; //修改num2 console.log(num1) //1 console.log(num2) //2 //案例2 var obj1 {x: 1, …

vue菜鸟从业记:完成项目最后一公里之真机测试和打包上线

最近我朋友王小闰他们公司的项目开发已经进入收尾阶段,前后端并行开发的差不多了,联调也调过了,上篇文章里也讲到了,所谓联调,就仿佛在说“我也不知道我的接口文档写的对不对,我们验证一下吧?我…

血淋淋的事实告诉你:你为什么不应该在JS文件中保存敏感信息

在JavaScript文件中存储敏感数据,不仅是一种错误的实践方式,而且还是一种非常危险的行为,长期以来大家都知道这一点。 而原因也非常简单,我们可以假设你为你的用户动态生成了一个包含API密钥的JavaScript文件: apiCall…

从零开始搭建一个vue.js的脚手架

在谷歌工作的时候,我们要做很多界面的原型,要求快速上手,灵活运用,当时用的一些现有框架,比如angular,太笨重了——尤雨溪(Vue.js 作者) vue.js是现在一个很火的前端框架&#xff0c…

更安全的Web通信HTTPS

1. HTTP协议存在的问题 阅读本篇需要对HTTP协议有最基本的了解。 借用《图解密码技术》里的图片,我们以如下一个购物场景开始介绍: 在网购过程中,如果使用纯粹的HTTP协议,那么用户的账号密码,信用卡,银行卡…

CSS入门指南——页面的水平居中

我们经常看到这样的网页,即内容水平居中在屏幕中间,左右留白。我们来给这样的布局起个名字——水平居中布局 其实要实现这样的布局十分简单,即给中间部分一个宽度,设置margin左右值为auto,如,中间部分class"main&…

mysql explain的使用

一、explain返回各列的含义: 1、table:显示这一行的数据是关于那张表的 2、type:重要的列,显示连接使用了何种类型,从最好到最差的连接类型为const、eq_reg、ref、range、index、ALL 3、possible_keys:显示…

使用 Canvas 生成公众号头图

熟悉“前端晚自修”的朋友们应该知道,我们每期的头图除了上面的文字随着每期变动以外,几乎是一模一样的(因为太懒了~)。这个头图虽然丑了一点,但是也还说的过去,毕竟是我倾尽毕生艺术细胞拼出来的&#xff…

Flask mysql 模版传参_Flask渲染Jinja2模板和传参

### Flask渲染Jinja2模板和传参:1. 如何渲染模板:* 模板放在templates文件夹下* 从flask中导入render_template函数。* 在视图函数中,使用render_template函数,渲染模板。注意:只需要填写模板的名字,不需要…

08 Spring框架 AOP (一)

首先我们先来介绍一下AOP: AOP(Aspect Orient Programming),面向切面编程,是面向对象编程OOP的一种补充。 面向对象编程是从静态角度考虑程序的结构,面向切面编程是从动态的角度考虑程序运行过程。 AOP底层…

移动spa商城优化记(一)---首屏优化篇

背景 随着公司业务的不断壮大,最近老是有用户反应公司APP内的商城打开比较慢,这可不行啊,慢了容易流失用户,流失用户减少公司业绩,公司业绩少我的年终奖就少…………,所以为了公司,也为了自己&a…

hprose for java 教程_hprose for java源码分析-4

4.1 疑窦丛生书接上回。上回说到,从HproseClient.java ------------------------- (#0)invokeHandler.handle()开始,将经历一个漫长的调用过程,下面把整个调用链粘出来,先认识下这个庞然大物。( >>> 表示调用到&#xff…

java批量提取文件夹名称_bat 批量提取指定目录下的文件名

bat 批量提取指定目录下的文件名下面是批量获取指定目录下的文件名的核心代码echo offecho text inputset inputset /p input:echo %input% is inputcd %input%rem echo onfor %%a in (*) do (echo %%a is input)cd ..如下是sql server执行对应脚本文件sqlcmd -Spcserver -dmas…

埃及分数The Rotation Game骑士精神——IDA*

IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题。 估价函数设计思路:观察一步最多能向答案靠近多少。 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一…

美团扫码付的前端可用性保障实践

开篇 2017年,美团金融前端遇到了很多通用性问题,特别是在保障前端可用性的过程中,我们团队也踩了不少“坑”,在梳理完这些问题以后,我们还专门做了第31期线下沙龙给大家进行了分享。不管是在面试过程中与候选人讨论&a…

Servlet上传文件和下载文件示例

Java Web应用程序中的文件上载和下载以及常见任务。 由于最近我写了很多有关Java servlet的文章 ,因此我想提供一个使用servlet上传和下载文件的示例示例。 用例 我们的用例是提供一个简单HTML页面,客户端可以在其中选择要上传到服务器的本地文件。 在提…