首页 > 其他分享 >技术成神之路:设计模式(十三)访问者模式

技术成神之路:设计模式(十三)访问者模式

时间:2024-09-11 22:51:56浏览次数:3  
标签:double void 成神 Visitor 设计模式 public rectangle 访问者

介绍

访问者模式(Visitor Pattern)是一种行为型设计模式,它允许你在不改变对象结构的前提下,定义作用于这些对象的新操作。这种模式通过将操作逻辑从对象结构中抽离出来,使得新的操作可以无缝地添加到现有对象中。

1.定义


访问者模式定义了一个访问者接口,它包含了访问不同元素的操作方法。具体的元素类接受访问者并调用相应的访问方法。通过这种分离,新增的操作可以直接通过访问者来实现,而不需要修改元素类。

2. 主要作用


  • 允许在不修改元素类的情况下,定义新的操作。
  • 提高了系统的可扩展性。
  • 避免了对复杂对象结构的直接修改。

3. 解决的问题


访问者模式解决了如何在不修改对象结构的情况下,向对象添加新的操作的问题。尤其在系统需要频繁添加新操作时,显得尤为重要。

4. 模式原理


包含角色:

  1. Visitor:定义了对各类元素对象的操作接口。
  2. ConcreteVisitor:实现Visitor接口,具体实现访问操作。
  3. Element:定义接受访问者的方法accept(), 通常由具体元素实现。
  4. ConcreteElement:实现Element接口,实现accept()方法。
  5. ObjectStructure:维护Element对象的集合,并提供遍历功能。

看到这么多的角色,就知道访问者模式并不简单,毕竟它是 《设计模式》中较为复杂的一个。不用怕,先以了解为主,因为它在实际开发中毕竟不常用。

UML类图:

技术成神之路:设计模式(十三)访问者模式_设计模式

示例: 假设我们有一个表示不同形状(如圆形和矩形)的对象结构,我们希望对这些形状执行不同的操作(如计算面积和绘制形状)。

定义形状接口和具体形状类:

// Shape接口
interface Shape {
    void accept(Visitor visitor);
}

// 圆形类
class Circle implements Shape {
    double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// 矩形类
class Rectangle implements Shape {
    double width;
    double height;

    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    public double getWidth() {
        return width;
    }

    public double getHeight() {
        return height;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

定义访问者接口和具体访问者类:

// 访问者接口
interface Visitor {
    void visit(Circle circle);
    void visit(Rectangle rectangle);
}

// 具体访问者类 - 计算面积
class AreaVisitor implements Visitor {
    @Override
    public void visit(Circle circle) {
        double area = Math.PI * circle.getRadius() * circle.getRadius();
        System.out.println("Circle area: " + area);
    }

    @Override
    public void visit(Rectangle rectangle) {
        double area = rectangle.getWidth() * rectangle.getHeight();
        System.out.println("Rectangle area: " + area);
    }
}

// 具体访问者类 - 绘制形状
class DrawVisitor implements Visitor {
    @Override
    public void visit(Circle circle) {
        System.out.println("Drawing a Circle with radius " + circle.getRadius());
    }

    @Override
    public void visit(Rectangle rectangle) {
        System.out.println("Drawing a Rectangle with width " + rectangle.getWidth() + " and height " + rectangle.getHeight());
    }
}

使用访问者模式:

public class VisitorPatternDemo {
    public static void main(String[] args) {
        Shape circle = new Circle(5);
        Shape rectangle = new Rectangle(4, 6);

        Visitor areaVisitor = new AreaVisitor();
        Visitor drawVisitor = new DrawVisitor();

        System.out.println("Calculating areas:");
        circle.accept(areaVisitor);
        rectangle.accept(areaVisitor);

        System.out.println("\nDrawing shapes:");
        circle.accept(drawVisitor);
        rectangle.accept(drawVisitor);
    }
}

打印输出:

Calculating areas:
Circle area: 78.53981633974483
Rectangle area: 24.0

Drawing shapes:
Drawing a Circle with radius 5.0
Drawing a Rectangle with width 4.0 and height 6.0

说真的,写到这里我还是懵懵的,但隐约感觉这个设计不错,哈哈哈。

举个栗子,假如你是个想了解学生信息的老师(Visitor),你可以是班主任也可以是体育老师(ConcreteVisitor),因为他们的关注点不同(例如,班主任关注学生的学习成绩,体育老师关注学生的运动能力),学校里的不同类型的学生(Element),具体的学生(ConcreteElement)(例如文艺生A,运动生B)。

此时,假设我们有一个学校系统,其中有多种学生类型和评价标准。

  • 学生接口(Student):定义一个 accept(Visitor visitor) 方法。
  • 具体学生(SpecificStudent):实现 Student 接口,能够接受不同的访问者。
  • 访问者接口(Visitor):定义访问不同学生类型的方法,如 visit(ArtStudent artStudent)visit(SportsStudent sportsStudent)
  • 具体访问者(ConcreteVisitor):实现具体的访问逻辑,比如 AcademicEvaluator 关注学术成绩,PhysicalEducationEvaluator 关注体育表现。

回头再看一遍定义,访问者模式定义了一个访问者接口,它包含了访问不同元素的操作方法,此处的不同元素就是不同的学生,具体的元素类接受访问者并调用相应的访问方法,此处的相应的访问方法就是 学术成绩 和 体育表现,通过这种方式,可以在不改变学生对象结构的前提下,增加新的评价逻辑或操作,而不需要修改学生类本身。

到这里,是不是更进一步了解访问者模式了,不明白也不要紧,记住定义就行了。我突然想到我高中数学老师说的一句话:别管为啥这样写,你就记住,这样写就给分!哈哈。有时候不必太纠结,现在不明白 后面你也会明白的

标签:double,void,成神,Visitor,设计模式,public,rectangle,访问者
From: https://blog.51cto.com/xaye/11984189

相关文章

  • 适配器设计模式
    设计模式(Designpattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解解、保证代码可靠性、程序的重用性。简单理解:设计模式就是各种套路。适配器设计模式:解决接口与接口实现类之间的矛盾问题如......
  • C#设计模式
    C#设计模式入门实战教程 什么是设计模式设计模式是对面向对象设计中反复出现的问题的解决方案。它们提供了被反复使用、多数人知晓的、经过分类编目的代码设计经验总结。设计模式的作用提高代码的可重用性:通过定义一套标准的解决方案,设计模式使得相同或类似的问题可以在......
  • Java中的缓存穿透与雪崩问题:解决方案与设计模式
    Java中的缓存穿透与雪崩问题:解决方案与设计模式大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在分布式系统中,缓存是提高性能的重要手段。然而,缓存系统在实际应用中常常会遇到缓存穿透和缓存雪崩这两种问题。本文将探讨这两种问题的成因以及在Java中......
  • 结构者设计模式
    结构者模式(StructuralDesignPatterns)指的是一组设计模式,旨在帮助设计者将对象或类组合成更大的结构,以便于形成更复杂的系统。这些模式关注如何将对象或类组织起来,以构建更大的结构或系统。主要目的是提高系统的灵活性和可维护性。常见的结构者模式包括:适配器模式(AdapterPa......
  • 设计模式-映射器(Mapper)
    概念在两个独立的对象之间建立通信的对象背景有时,需要在两个子系统之间通信,同时还必须隔离它们,而且还不想建立子系统间的依赖关系。运行机制映射器是子系统之间的绝缘层,控制着子系统间的通信细节;映射器通常需要在层与层之间进行数据交互。可以由使用映射器的第三方系统激......
  • 设计模式-入口(Gateway)
    入口是一个封装外部系统或资源访问的对象背景即使是纯粹的面向对象系统,通常也要处理一些不是对象的事务,例如关系数据库、CICS事务和XML数据结构。问题一般通过API访问外部资源。对API的理解是开发过程的必经之路,不仅软件的可读性差,使软件修改变也变得困难。解决途径......
  • 【LabVIEW学习篇 - 24】:生产者/消费者设计模式
    文章目录生产者/消费者设计模式案例:控制LED等亮灭生产者/消费者设计模式生产者/消费者是多线程编程中最基本的一种模式,使用非常普遍。从软件角度看,生产者就是数据的提供方,而消费者就是数据的消费处理方,二者之间存在一个数据缓存区。在新建中可创建生产者/消费者......
  • 【设计模式】装饰模式
    1.不好的代码(冗杂)//业务操作classStream{public:virtualcharRead(intnumber)=0;virtualvoidSeek(intposition)=0;virtualvoidWrite(chardata)=0;virtual~Stream(){}};//主体类classFileStream:publicStream{public:vir......
  • Java 设计模式-状态模式
    目录一.概述二.主要角色三.代码示例四.优缺点优点:缺点:五.常见应用场景一.概述        状态模式是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。对象看起来好像修改了它的类。状态模式把所有的与一个特定的状态相关的行为放到一个类......
  • Java 设计模式-代理模式
    目录概述一.什么是代理模式1.举例说明二.代理模式作用1.保护代理2.增强功能3.代理交互4.远程代理:三.代理模式3个角色四.静态代理1.代码示例:五.JDK动态代理1.代码示例:六.CGLIB动态代理1.代码示例 七.JDK动态代理和CGLIB动态代理区别八.两种在......