【问题标题】:refactor codes using visitor pattern使用访问者模式重构代码
【发布时间】:2019-03-18 10:23:49
【问题描述】:

我在尝试重构代码时遇到问题。它位于类似编译器的结构中。 代码结构如下。 我有几个目标平台来生成我的代码,比如 x86。

class Op
{
public:
  virtual doA(vector<int>& vec) = 0;
  virtual doB(unordered_map<int>& map) = 0;
};

---Directory x86----
class X86_Op_A: public Op 
{
public:
  virtual doA(vector<int>& vec){
      // genereate A type operator that do something under x86
  }
  virtual doB(unordered_map<int>& map){
     // genereate A type operator that do something under x86
  }
};

class X86_Op_B: public Op
public:
  virtual doA(vector<int>& vec){
      // genereate B type operator that do something under x86
  }
  virtual doB(unordered_map<int>& map){
     // genereate B type operator that do something under x86
  }
}; 

---Director arm---
class Arm_Op_A: public Op 
class Arm_Op_B: public Op
like the same code described above.

我如何重构代码,使它们看起来像访问者模式,我可以给它我的目标平台和我想做的操作。

我曾尝试考虑编写一个抽象的平台接口并使用不同的目标平面图实现。但是,我仍然觉得很难正确编写代码。如果在这种情况下我不能使用访问者模式,有没有办法重构代码?

【问题讨论】:

  • 欢迎来到 SO。我对你的问题有点困惑。访问者模式允许您在不更改操作对象的类的情况下定义操作。您所需要的只是一个具有成员函数的新类,该函数以Op * 作为参数。这就是你所追求的吗?
  • 我的主要观点是重构我拥有的全部 cpp 文件。目前,在不同的目标平台下,我必须编写一些重复的代码。在我阅读设计模式之后,我想也许我可以使用访问者来帮助减少重复代码。但是当我试图将它应用到我的代码时,我发现很难达到我的目标。所以,我在这里发布我的问题并希望找到解决方案。感谢您的评论。
  • 我在您的问题中看不到任何代码重复。能否提供重复代码的Minimal, Complete, and Verifiable example
  • 很抱歉没有更具体地描述问题。由于原始代码太复杂,我还没有找到更好的方法将其发布到网上。现在,我想出了一些方法来使用构建器设计模式和其他一些技巧来重构我的代码,包括在我的类中存储一些预定义的函数。不管怎样,谢谢你的帮助!当我第一次使用 SO 时,我有一个很棒的体验。

标签: c++ design-patterns refactoring


【解决方案1】:

我希望这会有所帮助!

如果满足以下条件,访问者模式会更好: 1 - 出于某种原因,您想将 doA 和 doB 操作分开在不同的类中; 2 - 您的 X86_Op_A、X86_Op_B、Arm_Op_A、Arm_Op_B 类有其他方法,您不希望 doA 和 doB 操作与这些方法一起使用;

class X86_Op_A;
class X86_Op_B;
class Arm_Op_A;
class Arm_Op_B;

class OpVisitor
{
public:
    OpVisitor();
    virtual ~OpVisitor();
public:
    virtual void visit(X86_Op_A*) = 0;
    virtual void visit(X86_Op_B*) = 0;
    virtual void visit(Arm_Op_A*) = 0;
    virtual void visit(Arm_Op_B*) = 0;
};
#include "OpVisitor.h"
#include "vector"
#include "iostream"

class DoAVisitor :
    public OpVisitor
{
public:
    DoAVisitor(std::vector<int>& vec): m_vec(vec)
    {
    }
    virtual ~DoAVisitor();
public:
    virtual void visit(X86_Op_A*)
    {
        std::cout << "genereate A type operator that do something under x86" << "\n";
    }
    virtual void visit(X86_Op_B*)
    {
        std::cout << "genereate B type operator that do something under x86" << "\n";
    }
    virtual void visit(Arm_Op_A*)
    {
        std::cout << "genereate A type operator that do something under Arm" << "\n";
    }
    virtual void visit(Arm_Op_B*)
    {
        std::cout << "genereate B type operator that do something under x86" << "\n";
    }
protected:
    std::vector<int>& m_vec;
};

#include "OpVisitor.h"
#include "iostream"
#include "unordered_map"

class DoBVisitor :
    public OpVisitor
{
public:
    DoBVisitor(std::unordered_map<int, int>& map): m_map(map)
    {
    }
    virtual ~DoBVisitor();
public:
    virtual void visit(X86_Op_A*)
    {
        std::cout << "genereate A type operator that do something under x86" << "\n";
    }
    virtual void visit(X86_Op_B*)
    {
        std::cout << "genereate B type operator that do something under x86" << "\n";
    }
    virtual void visit(Arm_Op_A*)
    {
        std::cout << "genereate A type operator that do something under Arm" << "\n";
    }
    virtual void visit(Arm_Op_B*)
    {
        std::cout << "genereate B type operator that do something under x86" << "\n";
    }
protected:
    std::unordered_map<int, int>& m_map;
};

#include "Op.h"
#include "OpVisitor.h"

class X86_Op_A :
    public Op
{
public:
    X86_Op_A();
    virtual ~X86_Op_A();
public:
    virtual void Accept(OpVisitor& v)
    {
        v.visit(this);
    }
};
#include "Op.h"
#include "OpVisitor.h"

class X86_Op_B :
    public Op
{
public:
    X86_Op_B();
    virtual ~X86_Op_B();
public:
    virtual void Accept(OpVisitor& v)
    {
        v.visit(this);
    }
};
#include <iostream>
#include "X86_Op_A.h"
#include "DoAVisitor.h"
#include "vector"

int main()
{
    X86_Op_A var;

    std::vector<int> vec;

    DoAVisitor visitor(vec);

    var.Accept(visitor);

    std::cout << "Hello World!\n"; 
}

【讨论】:

  • 感谢您的具体代码!您的代码给了我很多解决问题的直觉,并帮助我理解何时更多地使用访问者设计模式!真的很感谢你的帮助。虽然在我仔细检查了我所有的代码之后,我认为我应该使用其他方式更好地重构我的代码。
猜你喜欢
  • 1970-01-01
  • 2022-10-14
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
相关资源
最近更新 更多