美文网首页C++设计模式设计模式 BY C++
C++ 设计模式 —— 22.访问者模式

C++ 设计模式 —— 22.访问者模式

作者: JeremyYv | 来源:发表于2020-01-16 15:37 被阅读0次
    • 访问者模式:一种行为型设计模式

    • 应用场景:
      一个对象由很多部分组成,对这个对象的操作会对各部分依次操作。而在不同情景下,对各部分操作也不同。
      为了新增操作时无需了解对象内部结构,且具备可扩展性,将操作抽离为访问者类,类中实现对各部分具体的操作方法。
      然后在对象中提供一个接口用以访问者访问,在该接口总,对象会调用访问者中对应各部分的操作方法,操作对象中的各部分。

    • 举例:
      一台电脑中有很多组件,CPU、GPU、硬盘。维修人员对电脑进行整体维修时,需要对各部件依次进行维修,而且每部件具体的维修方式不同。不同的维修人员对相同的部件维修方式可能也不同。
      维修人员就是访问者。访问者类中实现了针对不同部件的维修方式。
      电脑就是被访问者。被访问者提供访问接口,使用访问者类中实现的不同部件维修方式,对内部部件进行访问。


    以下是访问者模式的简单代码实现
    #include <iostream>
    #include <list>
    using namespace std;
    
    class Visitor;
    
    //组成Computer的各组件基类
    class Element
    {
    public:
        Element(string strName):m_strName(strName){}
        string GetName()
        {
            return m_strName;
        }
    
        //组件接受访问者访问的接口
        virtual void AcceptVisitor(Visitor* pVisitor) = 0;
    
    private:
        //组件的标识名称
        string m_strName;
    };
    
    //访问者基类,针对不同组件,提供不同的访问接口
    class Visitor
    {
    public:
        virtual void VisitCPU(Element* pEle) = 0;
        virtual void VisitGPU(Element* pEle) = 0;
        virtual void VisitDISK(Element* pEle) = 0;
    };
    
    //Computer类,由各组件组成,访问者访问Computer时将依次访问各组件
    class Computer
    {
    public:
        ~Computer()
        {
            for(Element* pElement: m_listEle)
            {
                delete pElement;
            }
        }
    
        void AddElement(Element* pEle)
        {
            m_listEle.push_back(pEle);
        }
    
        void DelElement(Element* pEle)
        {
            m_listEle.remove(pEle);
        }
    
        //访问者访问Computer时将依次访问各组件
        void AcceptVisitor(Visitor* pVisitor)
        {
            for(Element* pElement: m_listEle)
            {
                pElement->AcceptVisitor(pVisitor);
            }
        }
    
    private:
        list<Element*> m_listEle;
    };
    
    //访问者实现类,实现各自的访问方法
    class VisitorA : public Visitor
    {
    public:
        void VisitCPU(Element* pEle)
        {
            printf("Visitor A record CPU's name:%s\n", pEle->GetName().c_str());
        }
    
        void VisitGPU(Element* pEle)
        {
            printf("Visitor A do nothing to GPU:%s\n", pEle->GetName().c_str());
        }
    
        void VisitDISK(Element* pEle)
        {
            printf("Visitor A change DISK:%s\n", pEle->GetName().c_str());
        }
    };
    
    class VisitorB : public Visitor
    {
    public:
        void VisitCPU(Element* pEle)
        {
            printf("Visitor B do nothing to CPU:%s\n", pEle->GetName().c_str());
        }
    
        void VisitGPU(Element* pEle)
        {
            printf("Visitor B record GPU's name:%s\n", pEle->GetName().c_str());
        }
    
        void VisitDISK(Element* pEle)
        {
            printf("Visitor B do nothing to DISK:%s\n", pEle->GetName().c_str());
        }
    };
    
    //组件的实现类,调用访问者相应的访问方法
    class CPU:public Element
    {
    public:
        CPU(string strName):Element(strName){}
        void AcceptVisitor(Visitor* pVisitor)
        {
            pVisitor->VisitCPU(this);
        }
    };
    
    class GPU:public Element
    {
    public:
        GPU(string strName):Element(strName){}
        void AcceptVisitor(Visitor* pVisitor)
        {
            pVisitor->VisitGPU(this);
        }
    };
    
    class Disk:public Element
    {
    public:
        Disk(string strName):Element(strName){}
        void AcceptVisitor(Visitor* pVisitor)
        {
            pVisitor->VisitDISK(this);
        }
    };
    
    主函数中的使用
    int main()
    {
        Computer oComputer;
        oComputer.AddElement(new CPU("i9-10980XE"));
        oComputer.AddElement(new GPU("Titan RTX"));
        oComputer.AddElement(new Disk("HOF PRO M.2"));
    
        VisitorA oVisitorA;
        VisitorB oVisitorB;
    
        oComputer.AcceptVisitor(&oVisitorA);
        oComputer.AcceptVisitor(&oVisitorB);
    
        return 0;
    }
    
    控制台输出结果
    Visitor A record CPU's name:i9-10980XE
    Visitor A do nothing to GPU:Titan RTX
    Visitor A change DISK:HOF PRO M.2
    Visitor B do nothing to CPU:i9-10980XE
    Visitor B record GPU's name:Titan RTX
    Visitor B do nothing to DISK:HOF PRO M.2
    

    如有错误,欢迎指正

    相关文章

      网友评论

        本文标题:C++ 设计模式 —— 22.访问者模式

        本文链接:https://www.haomeiwen.com/subject/drwfzctx.html