设计模式之访问者

news/2024/12/22 2:35:06/

一、访问者设计模式概念

        访问者模式(Visitor) 是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。

 适用场景

  • 如果你需要对一个复杂对象结构 (例如对象树) 中的所有元素执行某些操作, 可使用访问者模式。
  • 可使用访问者模式来清理辅助行为的业务逻辑。
  • 当某个行为仅在类层次结构中的一些类中有意义, 而在其他类中没有意义时, 可使用该模式。

访问者设计模式的结构

  1. 访问者 (Visitor) 接口声明了一系列以对象结构的具体元素为参数的访问者方法。 如果编程语言支持重载, 这些方法的名称可以是相同的, 但是其参数一定是不同的。
  2. 具体访问者 (Concrete Visitor) 会为不同的具体元素类实现相同行为的几个不同版本。
  3. 元素 (Element) 接口声明了一个方法来 “接收” 访问者。 该方法必须有一个参数被声明为访问者接口类型。
  4. 具体元素 (Concrete Element) 必须实现接收方法。 该方法的目的是根据当前元素类将其调用重定向到相应访问者的方法。 请注意, 即使元素基类实现了该方法, 所有子类都必须对其进行重写并调用访问者对象中的合适方法。
  5. 客户端 (Client) 通常会作为集合或其他复杂对象 (例如一个组合 (opens new window)树) 的代表。 客户端通常不知晓所有的具体元素类, 因为它们会通过抽象接口与集合中的对象进行交互。

代码如下:

        问题:做一款生成冰激凌和雪糕的程序,要求可以扩展新的口味,并且可以扩展新的包装方式。
        解决方案:表示一个作用于某对象结构中的各元素的操作。
    它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

#include <iostream>
#include <string>
#include <vector>
class IceCream;
class Popsicle;
class Visitor
{
public:virtual void visitIceCream(const IceCream *iceCream)const = 0;virtual void visitPopsicle(const Popsicle *popsicle)const = 0;
};class Component
{
public:virtual void accept(Visitor* visitor) const = 0;
};class IceCream : public Component
{
public:virtual void accept(Visitor* visitor) const{visitor->visitIceCream(this);}std::string getIceCream()const{return "冰激凌";}
};class Popsicle : public Component
{
public:virtual void accept(Visitor* visitor) const{visitor->visitPopsicle(this);}std::string getPopsicle()const{return "雪糕";}
};class Frosting : public Visitor
{
public:void visitIceCream(const IceCream* iceCream)const override{std::cout << iceCream->getIceCream() << " + 糖霜" << std::endl;}void visitPopsicle(const Popsicle* popsicle)const override{std::cout << popsicle->getPopsicle() << " + 糖霜" << std::endl;}
};class Chocolate : public Visitor
{
public:void visitIceCream(const IceCream* iceCream)const override{std::cout << iceCream->getIceCream() << " + 巧克力" << std::endl;}void visitPopsicle(const Popsicle* popsicle)const override{std::cout << popsicle->getPopsicle() << " + 巧克力" << std::endl;}
};void clientCode(const std::vector<Component*>& components,Visitor* visitor)
{for (const auto& component : components){component->accept(visitor);}
}int main()
{std::vector<Component*> components = { new IceCream,new Popsicle,new Popsicle };Frosting frosting;clientCode(components, &frosting);Chocolate chocolate;clientCode(components, &chocolate);return 0;
}

 二、与其他模式的关系

  • 你可以将访问者模式 (opens new window)视为命令模式 (opens new window)的加强版本, 其对象可对不同类的多种对象执行操作。
  • 你可以使用访问者 (opens new window)对整个组合模式 (opens new window)树执行操作。
  • 可以同时使用访问者 (opens new window)和迭代器模式 (opens new window)来遍历复杂数据结构, 并对其中的元素执行所需操作, 即使这些元素所属的类完全不同。

http://www.ppmy.cn/news/1533550.html

相关文章

S32K312 RTD 4.0.0 版本 OCU 例程配置流程说明

一、前言 由于 RTD 4.0.0 版本并没有 S32K312 相关例程&#xff0c;本文基于已有的 S32K344 OCU 例程&#xff0c;新建 S32K312 工程&#xff0c;讲解 OCU 例程的相关配置流程。 二、基本概念 OCU&#xff08;Output Compare Unit – 输出比较单元&#xff09;本质上是一个计…

Spring Boot 入门指南

在软件开发中&#xff0c;Java 依然是一个流行的编程语言&#xff0c;而 Spring 框架则是 Java 生态系统中最受欢迎的框架之一。 Spring 提供了一个全面的编程和配置模型&#xff0c;使开发人员能够构建高效、可扩展的企业级应用程序。Spring Boot 是 Spring 的一个子项目&…

Linux中的软硬链接和动静态库

硬链接 ln myfile.txt hard_file.link 264962 -rw-rw-r-- 2 zhangsan zhangsan 0 Sep 30 03:16 hard_file.link 264962 -rw-rw-r-- 2 zhangsan zhangsan 0 Sep 30 03:16 myfile.txt 273922 lrwxrwxrwx 1 zhangsan zhangsan 10 Sep 30 03:17 soft_file.link -> …

[含文档+PPT+源码等]精品大数据项目-基于Django实现的高校图书馆智能推送系统的设计与实现

大数据项目——基于Django实现的高校图书馆智能推送系统的设计与实现背景&#xff0c;可以从以下几个方面进行详细阐述&#xff1a; 一、信息技术的发展背景 随着信息技术的飞速发展和互联网的广泛普及&#xff0c;大数据已经成为现代社会的重要资源。在大数据背景下&#xf…

django的模型层介绍与配置

1 Django的Model模型介绍 模型是我们项目中的的数据信息源&#xff0c;它包含着储存数据的必要字段和行为。 通常&#xff0c;每个模型对应数据库中的一张表&#xff0c;每个属性对应一个字段 每个模型都是django.db.models.Model的一个Python 子类。 Django 提供一套自动生成…

【Nacos 架构 原理】服务发现模块之Nacos注册中心服务数据模型

文章目录 服务&#xff08;Service&#xff09;和服务实例&#xff08;Instance&#xff09;定义服务服务元数据定义实例实例元数据持久化属性 集群定义集群 生命周期服务的生命周期实例的生命周期集群的生命周期元数据的生命周期 服务&#xff08;Service&#xff09;和服务实…

在Ubuntu中自动挂载SMB/CIFS共享

文章目录 0. 引言1. 使用credentials文件存储认证信息2. 挂载点的准备3. 必要软件的安装4. 调整挂载参数5. 测试挂载6. 日志调试 0. 引言 本文是自己挂载共享磁盘的实践记录&#xff0c;将详细介绍如何在Linux系统中配置自动挂载SMB/CIFS共享&#xff0c;并提供一些常见问题的…

Egress Gateway 是一个重要的组件,用于管理从服务网格内部到外部服务的流量

在 Istio 服务网格中&#xff0c;Egress Gateway 是一个重要的组件&#xff0c;用于管理从服务网格内部到外部服务的流量。Egress Gateway 充当了一个边界路由器的角色&#xff0c;处理所有从网格内部发出的请求到非网格服务的流量。它可以帮助解决服务网格内外部服务通信的问题…