哪种设计模式可以使继承链中的类更薄?

时间:2014-07-01 07:02:55

标签: c++ design-patterns refactoring

以下是描述问题的伪代码:

class Client
{
public:
    void F1(A*);    //import
    void F2(A*);    //export
    void F3(A*);    //print
    void ...
    void F100(A*);  //validate
};

Client::F3(A* p)
{
    p->F3();
}

class A
{
public:
    int memberA;
    virtual void F3();
};

class B : public A
{
public:
    int memberB;
    virtual void F3();
};

class C : public B
{
public:
    int memberC;
    virtual void F3();
};

void A:F3()
{
    print(memberA);
}

void B:F3()
{
    A:F3();
    print(memberB);
}

void C:F3()
{
    B:F3();
    print(memberC);
}

客户端正在使用A类及其衍生产品,它有100种使用方式。例如。导入/导出/打印/验证等。

请记住,子类将调用基类加上它自己的东西。

我知道实现这一点的方法是让A / B / C类全部实现这100个功能。例如: F3,打印功能及其实现。

问题在于,如果我在继承链中的所有类中实现所有这100个函数(这些A / B / C只是一个简化的模型,在现实世界中,可能有超过10层的继承),每个单班将变得太胖。

你能帮我重构一下吗?

1 个答案:

答案 0 :(得分:0)

也许你可以使用Visitor Pattern。您的每个函数都代表一个访问者,A及其派生词只有一个接受函数:

struct Visitor {
  void visit(A&);
  void visit(B&);
  void visit(C&);
};

struct F1 : Visitor {
  void visit(A&);
  void visit(B&);
  void visit(C&);
};
// ...
struct F100 : Visitor {
  void visit(A&);
  void visit(B&);
  void visit(C&);
};


class A {
public:
  virtual void accept(Visitor& v) {v.visit(*this);}
}

class B : public A {
public:
  virtual void accept(Visitor& v) {v.visit(*this);}
}

这可能有趣也可能没有意义,具体取决于您必须进行的扩展以及您希望如何封装功能。基本上,这使得更容易实现新函数F101...F200并将函数代码集中在一个类中,但是如果必须实现新类D...Z,则必须调整每个函数,这已经是实现。