• C++设计模式:访客模式


    访客模式:通俗的说, 就是定义一个访问者角色, 当对指定角色进行访问时要通过访问者进行访问。

    访客模式的侵入性适中,仅在被访问的类里面加一个对外提供接待访问者的接口。

    访客模式的优点:

    1. 符合单一职责原则. 具体元素角色负责数据的加载, 而访问者角色负责报表的展现, 两个不同的职责非常明确的分离开来, 各自演绎变化.
    2. 优秀的扩展. 由于职责分开,继续增加 对数据的操作是非常快捷的.

    访客模式应用场景:

    1. 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
    2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
    class Visitor;
    
    //被访问类基类:  网站
    class Website
    {
    public:
        virtual ~Website(){ std::cout << "~Website()" << std::endl;}
        virtual void accept(Visitor&) = 0;
    };
    
    //被访问类具体实现类:  淘宝网
    class TaoBao : public Website
    {
    public:
        void accept(Visitor &v) override;
    
        void shopping();
    };
    
    //被访问类具体实现类: 优酷
    class YouKu : public Website
    {
    public:
        void accept(Visitor &v) override;
    
        void playVideo();
    };
    
    //访客类基类
    class Visitor
    {
    public:
        Visitor() = default;
        Visitor(const std::string &name) : m_name(name){}
    
        virtual ~Visitor(){ std::cout << "~Visitor()" << std::endl;}
        virtual void visit(TaoBao &web) = 0;
        virtual void visit(YouKu &web) = 0;
    
    protected:
        std::string m_name{"unknow"};
    };
    
    //访客具体实现类:  普通游客用户
    class GeneralVisitor : public Visitor
    {
    public:
        void visit(TaoBao &web) override;
        void visit(YouKu &web) override;
    };
    
    //访客具体实现类:  VIP用户
    class VIPVisitor : public Visitor
    {
    public:
        VIPVisitor(const std::string &name) : Visitor(name){}
    
        void visit(TaoBao &web) override;
        void visit(YouKu &web) override;
    
    };
    
    //
    void YouKu::accept(Visitor &v)
    {
        v.visit(*this);
    }
    
    void YouKu::playVideo()
    {
        std::cout << "Watch the video" << std::endl;
    }
    
    void TaoBao::accept(Visitor &v)
    {
        v.visit(*this);
    }
    
    void TaoBao::shopping()
    {
        std::cout << "Online shopping" << std::endl;
    }
    
    void GeneralVisitor::visit(TaoBao &web)
    {
        web.shopping();
    }
    
    void GeneralVisitor::visit(YouKu &web)
    {
        web.playVideo();
    }
    
    void VIPVisitor::visit(TaoBao &web)
    {
        std::cout << m_name << ": ";
        web.shopping();
    }
    
    void VIPVisitor::visit(YouKu &web)
    {
        std::cout << m_name << ": ";
        web.playVideo();
    }
    
    //测试
    int main()
    {
        TaoBao tb;
        YouKu yk;
        GeneralVisitor gVisitor;
        VIPVisitor vVisitor{"zhangsan"};
    
        yk.accept(gVisitor);
        tb.accept(gVisitor);
    
        yk.accept(vVisitor);
        tb.accept(vVisitor);
    
        return 0;
    }
    

    从以上代码来看,当被访问类数量较多时,需要在访客类中对应的编写大量的方法。另外访客类中的方法实现依赖于被访客类的具体类,没有依赖于抽象类。

  • 相关阅读:
    HDU 4370 0 or 1 (最短路)
    POJ 2449 Remmarguts' Date (K短路 A*算法)
    HDU 5984 Pocky ( 2016 CCPC 青岛 C)
    [leetcode-733-Flood Fill]
    [leetcode-746-Min Cost Climbing Stairs]
    OpenCV学习5-----使用Mat合并多张图像
    人体姿态的相似性评价基于OpenCV实现最近邻分类KNN K-Nearest Neighbors
    OpenCV学习4-----K-Nearest Neighbors(KNN)demo
    [leetcode-728-Self Dividing Numbers]
    [leetcode-724-Find Pivot Index]
  • 原文地址:https://www.cnblogs.com/chengjundu/p/11762747.html
Copyright © 2020-2023  润新知