访问者模式 Visitor Pattern

  • 1. 访问者模式概述
    • 1.1 定义
    • 1.2 结构
    • 1.3 适用环境
  • 2. 访问者模式应用案例
    • 2.1 类图
    • 2.2 代码实现
    • 2.3 运行结果
  • 3. 访问者模式优缺点

1. 访问者模式概述

  • 访问者模式是行为型模式,它包含访问者和被访问元素两个主要组成部分。
  • 被访问的元素通常具有不同的类型,且不同的访问者可以对它们进行不同的访问操作。
  • 访问者模式使得用户可以在不修改现有系统的情况下扩展系统的功能,为这些不同类型的元素增加新的元素。

1.1 定义

访问者模式让用户可以在不改变各元素类的前提下定义作用于这些元素的新操作。

Visitor Pattern: Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

1.2 结构

1.3 适用环境

在以下情况下可以使用访问者模式:

  1. 一个对象包含多个类型的对象,希望对这些对象实施一些依赖其具体类型的操作。不同类型的对象可以有不同的访问操作。
  2. 需要对一个对象结构中的对象进行很多不同并且不相关的操作,不希望增加新操作时修改这些类。
  3. 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。

2. 访问者模式应用案例

案例说明:
小汽车由车架、轮胎、座椅等几部分构成,现在需要计算汽车的总重量、汽车的金属重量和汽车的材料所占的体积。汽车的组成部分可能增加,需要计算的内容也可能增加。
现使用访问者模式设计该系统,绘制类图并编码实现。

2.1 类图

2.2 代码实现

  1. Component类:汽车组件类,充当抽象元素类。该抽象类定义了抽象方法 accept(),可以接收一个 Visitor 实现类的实例,用于触发组件计算的动作。
public interface Component {public void accept(CalculateContent content);
}
  1. Car类:具体汽车元素类。
public class Car implements Component {private String name;  //名称private double quality; //质量private double density; //密度public Car(String name, double quality, double density) {this.name = name;this.quality = quality;this.density = density;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getQuality() {return quality;}public void setQuality(double quality) {this.quality = quality;}public double getDensity() {return density;}public void setDensity(double density) {this.density = density;}@Overridepublic void accept(CalculateContent content) {content.calculate(this);}
}
  1. Carframe类:具体车架元素类。
public class Carframe implements Component {private String name; //名称private double quality; //质量private double density; //密度public Carframe(String name, double quality, double density) {this.name = name;this.quality = quality;this.density = density;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getQuality() {return quality;}public void setQuality(double quality) {this.quality = quality;}public double getDensity() {return density;}public void setDensity(double density) {this.density = density;}@Overridepublic void accept(CalculateContent content) {content.calculate(this);}
}
  1. Tyre类:具体轮胎元素类。
public class Tyre implements Component {private String name;private double quality;private double density;public Tyre(String name, double quality, double density) {this.name = name;this.quality = quality;this.density = density;}public String getName() { return name;}public void setName(String name) {this.name = name;}public double getQuality() {return quality;}public void setQuality(double quality) {this.quality = quality;}public double getDensity() {return density;}public void setDensity(double density) {this.density = density;}@Overridepublic void accept(CalculateContent content) {content.calculate(this);}
}
  1. Seat类:具体座位元素类。
public class Seat implements Component {private String name;private double quality;private double density;public Seat(String name, double quality, double density) {this.name = name;this.quality = quality;this.density = density;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getQuality() {return quality;}public void setQuality(double quality) {this.quality = quality;}public double getDensity() {return density;}public void setDensity(double density) {this.density = density;}@Overridepublic void accept(CalculateContent content) {content.calculate(this);}
}
  1. ComponentList类:组件列表类,充当对象结构,允许 Visitor 访问指定的元素。
import java.util.ArrayList;public class ComponentList {private ArrayList<Component> list = new ArrayList<Component>();public void addComponent(Component component) {list.add(component);}public void accept(CalculateContent content) {for(Component component : list) {component.accept(content);}}
}
  1. CalculateContent类:计算内容类,充当抽象访问类。
public abstract class CalculateContent {public abstract void calculate(Car content);public abstract void calculate(Carframe content);public abstract void calculate(Tyre content);public abstract void calculate(Seat content);
}
  1. Totalweight类:具体的计算汽车总重类。
public class Totalweight extends CalculateContent {@Overridepublic void calculate(Carframe content) {double quality = content.getQuality();double weight = quality * 2;System.out.println("车架的重量为:" + weight + "斤");}@Overridepublic void calculate(Tyre content) {double quality = content.getQuality();double weight = quality * 2;System.out.println("轮胎的重量为:" + weight + "斤");}@Overridepublic void calculate(Seat content) {double quality = content.getQuality();double weight = quality * 2;System.out.println("座位的重量为:" + weight + "斤");}//计算汽车总重量@Overridepublic void calculate(Car content) {double quality = content.getQuality();double weight = quality * 2;System.out.println("汽车总重为:" + weight + "斤");}
}
  1. Mentalweight类:具体的计算金属重量类。
public class Metalweight extends CalculateContent {@Overridepublic void calculate(Carframe content) {double quality = content.getQuality();double weight = quality*2;System.out.println("金属车架的重量为:" + weight + "斤");}@Overridepublic void calculate(Tyre content) {}@Overridepublic void calculate(Seat content) {}@Overridepublic void calculate(Car content) {}
}
  1. Materialvolume类:具体的计算各材料体积类。
public class Materialvolume extends CalculateContent {@Overridepublic void calculate(Car content) {double quality = content.getQuality();double density = content.getDensity();double volumn = quality * density;System.out.println("汽车的体积为:" + volumn + "立方");}@Overridepublic void calculate(Carframe content) {double quality = content.getQuality();double density = content.getDensity();double volumn = quality * density;System.out.println("车架所占体积为:" + volumn + "立方");}@Overridepublic void calculate(Tyre content) {double quality = content.getQuality();double density = content.getDensity();double volumn = quality * density;System.out.println("轮胎所占体积为:" + volumn + "立方");}@Overridepublic void calculate(Seat content) {double quality = content.getQuality();double density = content.getDensity();double volumn = quality * density;System.out.println("座位所占体积为:" + volumn + "立方");}
}
  1. Client类:客户端测试类。
public class Client {public static void main(String[] args) {ComponentList list = new ComponentList();list.addComponent(new Car("汽车", 500, 100));list.addComponent(new Carframe("车架", 50, 10));list.addComponent(new Tyre("轮胎", 30, 10));list.addComponent(new Seat("座位", 20, 10));//总重Totalweight totalweight = new Totalweight();list.accept(totalweight);//金属重量System.out.println("========================");Metalweight metalweight = new Metalweight();list.accept(metalweight);//体积System.out.println("========================");Materialvolume materialvolume = new Materialvolume();list.accept(materialvolume);}
}

2.3 运行结果

3. 访问者模式优缺点

  1. 优点
  • 增加新的访问很方便。只需增加一个新的具体访问类,无需修改源代码,符合开闭原则。
  • 访问者模式将有关元素对象的访问行为集中到一个访问者对象中,使类的职责更清晰,有利于对象结构中元素对象的复用,相同对象结构可以提供多个不同的访问者访问。
  1. 缺点
  • 增加新的元素类很困难。
  • 破坏了对象的封装性。

Java设计模式—访问者模式相关推荐

  1. java设计模式---访问者模式

      Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自 己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广 泛,遵循一定的编程模式,才能使自 ...

  2. Java设计模式-访问者模式

    访问者模式   在现实生活中,有些集合对象中存在多种不同的元素,且每种元素也存在多种不同的访问者和处理方式.例如,电影或电视剧中的人物角色,不同的观众对他们的评价也不同:还有顾客在商场购物时放在&qu ...

  3. JAVA设计模式--访问者模式

    目录 一.什么是访问者模式 二.访问者模式的结构 三.访问者模式的适用性 四. 场景举例 五.访问者模式的特点 一.什么是访问者模式 访问者(Visitor)模式是一种对象的行为模式.在访问者模式里, ...

  4. 设计模式---访问者模式

    访问者模式 介绍 定义及使用场景 UML类图 角色 财务案例 个人心得体会 静态分派以及动态分派 静态分派 动态分派 访问者模式中的伪动态双分派 对访问者模式的一些思考 总结 优点 缺点 适用性 参考 ...

  5. Java 设计模式——状态模式

    概述 很多人在说状态模式的时候总拿策略模式来进行对比,可能他们的类图会有一点类似,可我却不认为他们有多么相像.你可以阅读<Java设计模式--策略模式>这篇博客,并与本文对比,以找到蛛丝马 ...

  6. Java设计模式——Builder模式

    前言 之前写Android程序的时候,经常会用到Dialog(对话框)这个控件.我们在使用Dialog,比如AlertDialog的时候就用到了这里要说明的Builder模式.现在我们来看一下这样的一 ...

  7. Java设计模式-工厂模式(3)抽象工厂模式

    在Java设计模式-工厂模式(2)工厂方法模式 我们知道了工厂方法模式解决了简单工厂模式中的缺陷,做到了满足开闭原则,但是时代是进步的,进而又产生新的问题,工厂难道只能生产一种东西吗.我们所见到的工厂 ...

  8. Java设计模式-工厂模式(2)工厂方法模式

    在Java设计模式-工厂模式(1)简单工厂模式 中我们介绍了简单工厂模式,提到了简单工厂模式违背了开闭原则,而"工厂方法模式"是对简单工厂模式的进一步抽象化,其好处是可以使系统在不 ...

  9. Java设计模式-工厂模式(1)简单工厂模式

    Java设计模式-工厂模式(1)简单工厂模式 一.前言 1)例子 2)类图关系 3)代码实现 二.简单工厂模式 2.1.概述: 2.2.类图关系: 2.3.代码修改: 2.4.优缺点 2.5.扩展-简 ...

最新文章

  1. 模6计数器以及模10计数器(Verilog HDL语言设计)(Modelsim仿真与ISE综合)
  2. Java之构造器和构造方法的使用和意义
  3. 《selenium2 python 自动化测试实战》(15)——调用js控制滚动条等操作
  4. iBeacon 初探
  5. 大数相关计算(c语言版)
  6. matlab编程常用,Matlab常用60个编程
  7. Python3常用字符串操作
  8. 2017-2018-1 20155320 嵌入式C语言——时钟
  9. 阿里的easyexcel
  10. 校内计算机无法报名高考,没有奖项可以报名自主招生吗?报考条件建议65问
  11. 双引号在python中什么意思_Python中单引号和双引号的作用
  12. IE 主页被恶意篡改的解决方法
  13. 阿里云服务器如何选择操作系统?操作系统选择方法
  14. 【收藏】最全计算机网络基础思维导图
  15. 特大整数相加(C实现)
  16. 教育部发布2013年全国教育事业发展统计公报
  17. SpringBoot项目--如何不停服更新应用?
  18. 黄金原野身份链 架构智能诚信体系
  19. kotlin中的Map集合类
  20. iPhone 12、iPhone 12 Pro、iPhone 12 Pro Max屏幕尺寸,分辨率,PPI 详细数据对比 iPhone 12 mini

热门文章

  1. 树莓派3B+/4 配置LRP python3环境搭建
  2. Python基础——类与对象
  3. R2S使用OpenWRT的固件,实现锐捷客户端校园网一线四拨号获得四倍网速的操作教程
  4. AtCoder - 1974(arc058_b)
  5. ORB-SLAM程序流程以stero_inertial_euroc.cc主程序为例
  6. Skinmagic--MFC界面美化
  7. 9.9 个 CSS 小技巧,让你有更多时间摸鱼~
  8. 彩色图像--色彩空间 HSI(HSL)、HSV(HSB)
  9. 一文带你了解EV SSL证书申请有多难?
  10. 市场调研-全球与中国重型汽车发动机活塞市场现状及未来发展趋势