23种设计模式(二十三)行为变化之访问器

    科技2022-08-16  123

    本系列所有文章来自李建忠老师的设计模式笔记,系列如下: 设计模式(一)面向对象设计原则 23种设计模式(二)组件协作之模板方法 23种设计模式(三)组件协作之策略模式 23种设计模式(四)组件协作之观察者模式 23种设计模式(五)单一职责之装饰模式 23种设计模式(六)单一职责之桥模式 23种设计模式(七)对象创建之工厂方法 23种设计模式(八)对象创建之抽象工厂 23种设计模式(九)对象创建之原型模式 23种设计模式(十)对象创建之构建器 23种设计模式(十一)对象性能之单件模式 23种设计模式(十二)对象性能之享元模式 23种设计模式(十三)接口隔离之门面模式 23种设计模式(十四)接口隔离之代理模式 23种设计模式(十五)接口隔离之适配器 23种设计模式(十六)接口隔离之中介者 23种设计模式(十七)状态变化之状态模式 23种设计模式(十八)状态变化之备忘录 23种设计模式(十九)数据结构之组合模式 23种设计模式(二十)数据结构之迭代器 23种设计模式(二十一)数据结构之职责链 23种设计模式(二十二)行为变化之命令模式 23种设计模式(二十三)行为变化之访问器 23种设计模式(二十四)领域规则之解析器

    文章目录

    动机设计方法一设计方法二模式定义要点总结

    动机

      在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。

      如何在不更改类层次结构的前提下,在运行时根据需要透明地位类层次结构上的各个类动态添加新的操作,从而避免上述问题?

    设计方法一

    #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); //第二次多态辨析 } }; 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; }

    设计方法二

    #include <iostream> using namespace std; class Visitor; 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 { //*** } };

    模式定义

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

    要点总结

      Visitor模式通过所谓双重分发(double dispatch)来实现在不更改(不添加新的操作–编译时),Element类层次结构的前提下,在运行时透明地为类层次结构上的各个类动态添加新的操作(支持变化)。

      所谓双重分发即Visitor模式中间包括了两个多态分发(注意其中的多态机制):第一个为accept方法的多态辨析;第二个为visitElementX方法的多态辨析。

      Visitor模式的最大缺点在于扩展类层次结构(增添新的Element子类),会导致Visitor类的改变。因此Vistor模式适用于Element类层次结构稳定,而其中的操作却经常面临频繁改动的情况。

    Processed: 0.009, SQL: 9