如何在这种C ++设计场景中避免胖/污染界面 - OOPS?

时间:2014-12-23 11:17:08

标签: c++ oop uml

我们正在为小工具DTV编写通用中间件。我们有一个名为ContentMgr的模块,它是一个基类。现在,针对不同的客户需求,我们有VideoconContentMgr(例如) - 它源自ContentMgr。

class ContentMgr
{
  public:

virtual void setContent()
{
  cout<<"Unused function";
}

};

class VideoconContentMgr: public ContentMgr
{
  virtual void setContent()
  {
     cout<<"Do some useful computation;
  }

};

客户端代码 - 基于产品类型 -

/ **如果产品是通用的** / ContentMgr * product = new ContentMgr();

/ **如果产品是videocon ** / ContentMgr * product = new VideoconContentMgr();

我的问题是根据接口隔离原则 - 应该避免脂肪/污染的接口。我怎样才能避免污染的方法 - setContent()。对于通用产品,setContent()没有用。但是,对于videocon产品,它是有用的。如何避免胖/污染方法setContent()?

1 个答案:

答案 0 :(得分:1)

  

对于通用产品,setContent()无用。但是,对于videocon产品,它很有用。

一种解决方案是将成员函数保留在有用的位置 - 仅将其放入VideoconContentMgr,并在特定于VideoconContentMgr子类型的上下文中使用它:

/** if the product is generic **/ ContentMgr *product = new ContentMgr();

/** If the product is videocon **/ {
    VideoconContentMgr *vcm = new VideoconContentMgr();
    vcm->setContent();
    ContentMgr *product = vcm;
}

如果特定于子类的成员函数的有用性超出了初始化时间,请使用类似visitor的方法。特定于子类的代码仍然绑定到子类,但现在添加一个对泛型类不执行任何操作的访问者,并在setContent()类上调用VideoconContentMgr

struct ContentMgrVisitor {
  virtual void visitGeneric(ContentMgr& m) {};
  virtual void visitVideo(VideoconContentMgr& vm) {};
};

struct ContentMgr
{
  virtual void accept(ContentMgrVisitor& v)
  {
    v.visitGeneric(this);
  }
};

struct VideoconContentMgr: public ContentMgr
{
  virtual void setContent()
  {
     cout<<"Do some useful computation;
  }
  virtual void accept(ContentMgrVisitor& v)
  {
     v.visitVideo(this);
  }
};

现在,想要致电setContent的客户可以从访问者那里做到:

class SetContentVisitor : public ContentMgrVisitor {
    void visitVideo(VideoconContentMgr& vm) {
        vm.setContent();
    }
};
...
ContentMgr *mgr = ... // Comes from somewhere
SetContentVisitor scv;
mgr->accept(scv);