当前位置: 首页 > article >正文

【GeekBand】C++设计模式笔记24_Visitor_访问器

1. “行为变化” 模式

  • 在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变化。“行为变化” 模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合。
  • 典型模式
    • Command
    • Visitor

2. Visitor 访问器

2.1 动机(Motivation)

  • 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。
  • 如何在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题?

2.2 模式定义

表示一个作用于某对象结构中的各元素的操作。使得可以在不改变(稳定)各元素的类的前提下定义(扩展)作用于这些元素的新操作(变化)。
——《设计模式》GoF

2.3 实例代码

2.3.1 非访问器模式
#include <iostream>
using namespace std;

class Element
{
public:
    virtual void Func1() = 0;
    
    // 在基类中增加新方法的接口,那么所有子类中都要实现对应的接口
    virtual void Func2(int data) = 0;
    virtual void Func3(int data) = 0;
    //...
    
    virtual ~Element() {}
};

class ElementA : public Element
{
public:
    void Func1() override {
        //...
    }
    
    void Func2(int data) override {
        //...
    }
};

class ElementB : public Element
{
public:
    void Func1() override {
        //***
    }
    
    void Func2(int data) override {
        //***
    } 
};
2.3.2 访问器模式
#include <iostream>
using namespace std;

class Visitor;

class Element
{
public:
    virtual void accept(Visitor& visitor) = 0;	// 第一次多态辨析

    virtual ~Element() {}
};

class ElementA : public Element
{
public:
    void accept(Visitor &visitor) override {
        visitor.visitElementA(*this);
    }
};

class ElementB : public Element
{
public:
    void accept(Visitor &visitor) override {
        visitor.visitElementB(*this);	// 第二次多态辨析
    }
};

// Visitor 基类
class Visitor {
public:
    virtual void visitElementA(ElementA& element) = 0;
    virtual void visitElementB(ElementB& element) = 0;
    
    virtual ~Visitor() {}
};

//==================================

// 扩展1
class Visitor1 : public Visitor {
public:
    void visitElementA(ElementA& element) override {
        cout << "Visitor1 is processing ElementA" << endl;
    }
        
    void visitElementB(ElementB& element) override {
        cout << "Visitor1 is processing ElementB" << endl;
    }
};
     
// 扩展2
class Visitor2 : public Visitor {
public:
    void visitElementA(ElementA& element) override {
        cout << "Visitor2 is processing ElementA" << endl;
    }
    
    void visitElementB(ElementB& element) override {
        cout << "Visitor2 is processing ElementB" << endl;
    }
};
                
int main()
{
    Visitor2 visitor;
    
    ElementB elementB;
    elementB.accept(visitor);	// double dispatch
    
    ElementA elementA;
    elementA.accept(visitor);

    return 0;
}

2.4 结构(Structure)

在这里插入图片描述

2.5 要点总结

  • Visitor 模式通过所谓双重分发(double dispatch)来实现在不更改(不添加新的操作—编译时)Element 类层次结构的前提下,在运行时透明地为类层次结构上的各个类动态添加新的操作(分支变化)。
  • 所谓双重分发即 Visitor 模式中间包括了两个多态分发(注意其中的多态机制):第一个为 accept 方法的多态辨析;第二个为 visitElementX 方法的多态辨析。
  • Visitor 模式的最大缺点在于扩展类层次结构(增添新的 Element 子类),会导致 Visitor 类的改变。因此 Visitor 模式适用于 “Element 类层次结构稳定,而其中的操作却经常面临频繁改动”。

http://www.kler.cn/a/467199.html

相关文章:

  • 【计算机网络】课程 实验二 交换机基本配置和VLAN 间路由实现
  • MySQL低版本没有函数row_number() over的解决方案
  • LabVIEW在反馈控制时如何解决带约束的控制问题
  • 【网络安全 | 漏洞挖掘】绕过电子邮件确认实现预账户接管
  • Linux vi/vim 编辑器:功能强大的文本处理工具
  • ros常用命令记录
  • 爬虫案例-爬取某度文档
  • 洛谷B4071 [GESP202412 五级] 武器强化
  • Java 数据库连接 - Sqlite
  • 解决openpyxl操纵带公式的excel或者csv之后,pandas无法读取数值的问题
  • 基于PHP+MySQL实现的web端借还书系统
  • android studio老版本下载教程
  • 【AI学习】Transformer深入学习(二):从MHA、MQA、GQA到MLA
  • 阿里云-通义灵码:在 PyCharm 中的强大助力(下)
  • 急需升级,D-Link 路由器漏洞被僵尸网络广泛用于 DDoS 攻击
  • GPIO、RCC库函数
  • 104周六复盘 (188)UI
  • perl包安装的CPAN大坑
  • SQL-【DDL+DML】
  • 30分钟学会HTML
  • vscode下载vetur和vue-helper插件之后删除键(backspace)失效
  • Java十六
  • 【Web】极简快速入门Vue 3
  • 05-spring-理-bean的生命周期
  • RuoYi-Vue从http升级为https(Jar+Nginx)
  • 金毛可以穷养吗?