• 设计模式-访问者模式


    访问者模式Visitor):

        表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

    1.访问者模式适用于数据结构相对稳定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。
    2.访问者模式的目的是要把处理从数据结构分离出来。很多系统可以按照算法和数据结构分开,如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易。反之,如果这样的系统的数据结构对象易于变化,经常要有新的数据对象增加进来,就不适合使用访问者模式。
    3.其实访问者模式的有点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问对象中。
    4.访问者模式的缺点其实也就是使得增加新的数据结构变得困难。

    访问者实现代码:

    VisitorMode.h

    #pragma once
    #include <list>
    #include <string>
    #include <iostream>
    using namespace std;
    
    class CConcreteElementA;
    class CConcreteElementB;
    //Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作。
    class CVisitor
    {
    public:
    	virtual void VisitConcreteElementA(CConcreteElementA *pConcreteElementA) = 0;
    	virtual void VisitConcreteElementB(CConcreteElementB *pConcreteElementB) = 0;
    };
    
    //ConcreteVisitor1和ConcreteVisitor2类,具体访问者类,实现每个由Visitor声明的操作。每个
    //操作实现算法的一部分,而该算法片段仍是对应于结构中对象的类。
    
    class CConcreteVisitor1 : public CVisitor
    {
    public:
    	void VisitConcreteElementA(CConcreteElementA *pConcreteElementA);
    	void VisitConcreteElementB(CConcreteElementB *pConcreteElementB);
    };
    
    class CConcreteVisitor2 : public CVisitor
    {
    public:
    	void VisitConcreteElementA(CConcreteElementA *pConcreteElementA);
    	void VisitConcreteElementB(CConcreteElementB *pConcreteElementB);
    };
    
    
    //Element类,定义一个Accept操作,它以一个访问者为参数
    class CElement
    {
    public:
    	virtual void Accept(CVisitor *pVisitor) = 0;
    };
    
    class CConcreteElementA : public CElement
    {
    private:
    	string m_strName;
    public:
    	CConcreteElementA(const string &strName);
    	void Accept(CVisitor *pVisitor);
    	void OperationA(){}//A的单独方法
    	string GetName();
    };
    //ConcreteElementA和ConcreteElementB类,具体元素,实现Accept操作。
    class CConcreteElementB : public CElement
    {
    private:
    	string m_strName;
    public:
    	CConcreteElementB(const string &strName);
    	void Accept(CVisitor *pVisitor);
    	void OperationB(){}//B的单独方法
    	string GetName();
    };
    
    //ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素。
    class CObjectStructure
    {
    private:
    	list<CElement*>m_lElements;
    public:
    	CObjectStructure();
    	~CObjectStructure();
    	void Attach(CElement *pElement);
    	void Detach(CElement *pElement);
    	void Accept(CVisitor *pVisitor);
    };
    VisitorMode.CPP

    #include "stdafx.h"
    #include "VisitorMode.h"
    
    
    void CConcreteVisitor1::VisitConcreteElementA(CConcreteElementA *pConcreteElementA)
    {
    	cout<<"1-A:"<<pConcreteElementA->GetName()<<endl;
    }
    
    void CConcreteVisitor1::VisitConcreteElementB(CConcreteElementB *pConcreteElementB)
    {
    	cout<<"1-B:"<<pConcreteElementB->GetName()<<endl;
    }
    
    void CConcreteVisitor2::VisitConcreteElementA(CConcreteElementA *pConcreteElementA)
    {
    	cout<<"2-A:"<<pConcreteElementA->GetName()<<endl;
    }
    void CConcreteVisitor2::VisitConcreteElementB(CConcreteElementB *pConcreteElementB)
    {
    	cout<<"2-B:"<<pConcreteElementB->GetName()<<endl;
    }
    
    
    CConcreteElementA::CConcreteElementA(const string &strName)
    {
    	m_strName = strName;
    }
    
    void CConcreteElementA::Accept(CVisitor *pVisitor)
    {
    	pVisitor->VisitConcreteElementA(this);
    }
    
    string CConcreteElementA::GetName()
    {
    	return m_strName;
    }
    
    CConcreteElementB::CConcreteElementB(const string &strName)
    {
    	m_strName = strName;
    }
    
    void CConcreteElementB::Accept(CVisitor *pVisitor)
    {
    	pVisitor->VisitConcreteElementB(this);
    }
    
    string CConcreteElementB::GetName()
    {
    	return m_strName;
    }
    
    CObjectStructure::CObjectStructure()
    {
    	m_lElements.clear();
    }
    CObjectStructure::~CObjectStructure()
    {
    	for each (CElement * i in m_lElements)
    	{
    		delete i;
    	}
    }
    
    void CObjectStructure::Attach(CElement *pElement)
    {
    	m_lElements.push_back(pElement);
    }
    void CObjectStructure::Detach(CElement *pElement)
    {
    	m_lElements.remove(pElement);
    }
    void CObjectStructure::Accept(CVisitor *pVisitor)
    {
    	for each (CElement * i in m_lElements)
    	{
    		i->Accept(pVisitor);
    	}
    }
    客户端调用代码:

    #include "stdafx.h"
    #include "VisitorMode.h"
    using namespace std;
    
    int main()
    {
    	CObjectStructure *pO = new CObjectStructure();
    	pO->Attach(new CConcreteElementA("man"));
    	pO->Attach(new CConcreteElementB("woman"));
    
    	CConcreteVisitor1 *pV1 = new CConcreteVisitor1();
    	CConcreteVisitor2 *pV2 = new CConcreteVisitor2();
    	
    	pO->Accept(pV1);
    	pO->Accept(pV2);
    
    	delete pO;
    	delete pV1;
    	delete pV2;
        return 0;
    }
    执行结果:



  • 相关阅读:
    Perl-晶晨2021届笔试题
    数字IC设计流程
    后端一些常考知识点
    sklearn: 利用TruncatedSVD做文本主题分析
    用截断奇异值分解(Truncated SVD)降维
    numpy.linalg.norm(求范数)
    岭回归和lasso回归及正则化
    什么是范数?
    MySQL三大范式和反范式
    汇编知识之EIP寄存器
  • 原文地址:https://www.cnblogs.com/csnd/p/12062315.html
Copyright © 2020-2023  润新知