在需要给每个类增加一个新操作时,成员函数实现方式和访问者实现方式有何区别?
成员函数实现方式需要给类层级结构的每个类增加一个实现,这需要修改原来的代码,不符合开闭原则。而访问者实现方式则只需新建一个访问者,完全不影响原来的代码,因此在这种情况下,访问者实现方式更优。
当需要给每个类增加一个新操作时,有两种常见的实现方式:成员函数实现方式和访问者模式实现方式。这两种方式各有优缺点,适用于不同的场景。下面我们来具体分析这两种实现方式的区别。
在成员函数实现方式中,你需要直接在类内部添加新的成员函数来实现所需的功能。这种方式是最直观和最直接的方法。
访问者模式是一种行为设计模式,它允许你向现有的类结构中添加新的操作,而不必修改这些类。这种模式通过定义一个包含多个访问方法的访问者接口来实现,每个具体的访问者类实现了这个接口,并针对每个具体的类提供一个访问方法。
假设我们有一个简单的类层次结构,包括 Shape
抽象基类和两个派生类 Circle
和 Square
。
#include <iostream>
class Shape {
public:
virtual void draw() const = 0;
};
class Circle : public Shape {
public:
void draw() const override {
std::cout << "Drawing a circle." << std::endl;
}
};
class Square : public Shape {
public:
void draw() const override {
std::cout << "Drawing a square." << std::endl;
}
};
// 新增成员函数
void Shape::highlight() const {
std::cout << "Highlighting shape." << std::endl;
}
#include <iostream>
class Shape {
public:
virtual void accept(Visitor* visitor) const = 0;
};
class Visitor {
public:
virtual void visit(const Circle& circle) = 0;
virtual void visit(const Square& square) = 0;
};
class Circle : public Shape {
public:
void draw() const {
std::cout << "Drawing a circle." << std::endl;
}
void accept(Visitor* visitor) const override {
visitor->visit(*this);
}
};
class Square : public Shape {
public:
void draw() const {
std::cout << "Drawing a square." << std::endl;
}
void accept(Visitor* visitor) const override {
visitor->visit(*this);
}
};
class HighlightVisitor : public Visitor {
public:
void visit(const Circle& circle) override {
std::cout << "Highlighting a circle." << std::endl;
}
void visit(const Square& square) override {
std::cout << "Highlighting a square." << std::endl;
}
};
选择哪种实现方式取决于项目的具体情况。如果你预计未来不会频繁地增加新的操作,并且类结构相对稳定,那么直接使用成员函数的方式可能更为合适。相反,如果你预期会有较多的新操作加入,并且希望保持类结构的稳定性,那么访问者模式可能是更好的选择。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。