目录
前言
设计模式,又称为软件设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。学习设计模式可以提高程序员的思维能力、编程能力和设计能力,使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
一、🌍访问者(Visitor)模式是什么?🌍
将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。
二、🌍访问者(Visitor)模式的优缺点🌍
优点:
1)扩展性好。能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能;
2)复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度;
3)灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化而不影响系统的数据结构;
4)符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。
缺点:
1)增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”;
2)破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性;
3)违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。
三、🌍访问者(Visitor)模式的结构🌍
访问者模式包含以下主要角色:
⑴ 抽象访问者(Visitor)角色:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作visit(),该操作中的参数类型标识了被访问的具体元素。
⑵ 具体访问者(ConcreteVisitor)角色:实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。
⑶ 抽象元素(Element)角色:声明一个包含接受操作accept()的接口,被接受的访问者对象作为accept()方法的参数。
⑷ 具体元素(ConcreteElement)角色:实现抽象元素角色提供的accept()操作,其方法体通常都是visitor.visit(this),另外具体元素中可能还包含本身业务逻辑的相关操作。
⑸ 对象结构(ObjectStructure)角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由List、Set、Map等聚合类实现。
四、🌍实例演示🌍
1.🌕实例概述🌕
抽象元素角色:
Card接口,表单类,定义接受的观察者方法;
具体元素角色:
ReportCard类,成绩单中的单条数据,实现方法,并对数据进行i处理;
抽象访问者角色:
reportCardViewer接口,定义观察方法接口;
具体访问者角色:T
eacher、Student类,实现方法接口,老师关心是否自己教授的课程成绩和是否有挂科,学生关心总分成绩;
对象结构角色:
ReportCardList类,成绩单类,存放ReportCard类数组,根据访问者调用show方法。
2.🌕代码演示🌕
话不多说,代码附上!
package Visitor;
import java.util.*;
public class VisitorDemo{
public static void main(String[] args) {
ReportCardList reportCardList = new ReportCardList();
reportCardList.addCard(new ReportCard(55, "Math"));
reportCardList.addCard(new ReportCard(40, "Eng"));
reportCardList.addCard(new ReportCard(95, "Sport"));
reportCardList.addCard(new ReportCard(96, "Music"));
reportCardViewer student = new Student();
reportCardViewer mathTeacher = new Teacher("Math");
// 两个访问者分别访问学生成绩单
reportCardList.show(student);
reportCardList.showEnd(student);
reportCardList.show(mathTeacher);
reportCardList.showEnd(mathTeacher);
}
}
//单的接口(相当于Element)
interface Card {
void accept(reportCardViewer viewer);
}
//成绩单中的单条数据
class ReportCard implements Card {
private double grade;
private String subject;
public ReportCard(double grade, String subject) {
super();
this.grade = grade;
this.subject = subject;
}
public void accept(reportCardViewer viewer) {
viewer.view(this);
}
public double getGrade() {
return grade;
}
public String getSubject() {
return subject;
}
}
//成绩单查看者接口(相当于Visitor)
interface reportCardViewer {
// 查看成绩单
void view(ReportCard card);
// 查看最后输出
void showEnd();
}
//老师类,查看成绩单的类之一
class Teacher implements reportCardViewer {
private int subjectNotPassTotal = 0;
private String name;
public Teacher(String name) {
this.name = name;
}
// 老师在看成绩单时,只关注自己教授的学科,和成绩是否挂科
public void view(ReportCard card) {
if(card.getGrade() < 60 ) {
subjectNotPassTotal++;
}
if (card.getSubject().equals(name)) {
System.out.println( name + "老师查看成绩:" + card.getGrade());
}
}
public void showEnd() {
System.out.println("挂科的人数为:" + subjectNotPassTotal);
}
}
//学生类,查看成绩单的类之一
class Student implements reportCardViewer {
private float gradeTotal;
private int subjectCount = 0;
public void view(ReportCard card) {
gradeTotal += card.getGrade();
subjectCount++;
System.out.println("当前总分为:" + gradeTotal);
}
public void showEnd() {
System.out.println("平均分是:" + gradeTotal/subjectCount);
}
}
//成绩单类(相当于ObjectStruture)
class ReportCardList {
// 成绩单列表
private List<Card> cardList = new ArrayList<Card>();
// 添加学科成绩
public void addCard(Card card) {
cardList.add(card);
}
public void show(reportCardViewer viewer) {
for (Card card : cardList) {
card.accept(viewer);
}
}
public void showEnd(reportCardViewer viewer) {
viewer.showEnd();
}
}
3.🌕实验结果🌕
当前总分为:55.0
当前总分为:95.0
当前总分为:190.0
当前总分为:286.0
平均分是:71.5
Math老师查看成绩:55.0
挂科的人数为:2
总结
以上就是今天要讲的内容,本文仅仅简单介绍了行为模式下访问者模式的定义,优缺点以及其的模式结构,并通过实例演示,进一步反应了在一定需求条件下,访问者模式的优点。