组件构建构成中,组件行为的变化经常导致组件本身剧烈的变化;“行为变化”将组件本身和组件行为解耦,从而支持组件行为变化。
command,visitor属于行为变化模式。
motivation:软件构件过程中,由于需求的变化,某些类的层次结构中,常常需要增加新的行为,入股直接在基类中进行更改,将会给子类带来繁重的变更负担,甚至改变原有的设计;在不更改层级结构的前提下,在运行时透明地根据需求,为类层次结构上的类动态地添加新的操作。
key interface or class:
1. visitor接口。
feature: 行为进行对象化。
structure:
template codes:
class Element{
public:
//预先知道类结构会进行扩展时
virtual void accept(Visitor & visitor)=0; //第一次动态辨析
virtual func1()=0;
}
class ElementA: public Element{
public:
virtual void accept(Visitor & visitor) override{
visitor.visitElementA(*this);
}
virtual func1(){//...}
}
class ElementB: public Element{
public:
virtual void accept(Visitor & visitor) override{
visitor.visitElementB(*this); //第二次动态辨析
}
virtual func1(){//...}
}
class Visitor{
public:
virtual void visitElementA(ElementA& element)=0;
virtual void visitElementB(ElementB& element)=0;
virtual ~Visitor(){}
}
================以上部分不会被改变============
================以下部分根据需求改变===========
//拓展1
class Visitor1: public Visitor{
public:
virtual void visitElementA(ElementA& element){
//使用该ElementA对象进行操作
}
virtual void visitElementB(ElementB& element){
//使用该ElementB对象进行操作
}
}
int main(){
ElementA elementA;
ElementB elementB;
Visitor1 v1;
elementA.accept(v1); //实现新的操作
}
summary:
1. visitor通过所谓的“双重分发”(double dispatch)来实现不更改类的层次结构的前提下(不添加编译时的操作),在运行时透明地为类层次结构中的各个类添加新的操作;
2.双重分发,即为在visitor模式中包括了两次多态分发,第一次为accept多态辨析,第二次是visitElementX多态辨析;
3.visitor最大的而缺点是子类的增加会导致visitor基类的改变,也就是说只有在所有子类都确定时才能使用visitor模式,因此visitor模式只适用于子类稳定的层次结构。