多态性是否值得增加耦合?

时间:2009-01-08 21:54:12

标签: c++ polymorphism coupling

我正在编写一个简单的游戏来学习获得更多的C ++经验,我有一个想法,我觉得多态几乎有效,但没有。在这个游戏中,PartyMap中相当线性地移动,但偶尔会在路上遇到Fork。 fork(基本上)是std::vector<location*>。原来我打算在Party成员函数中编写如下代码:

if(!CurrLocation->fork_.empty())
   // Loop through forks and show options to the player, go where s/he wants
else
  (CurrLocation++)

但我想知道以下某些变体是否会更好:

CurrLocation = CurrLocation->getNext();

实际上Fork实际上是从Location派生的,并且重载了一些新函数getNext()。但在后一种情况下,location(一个低级结构)必须是向用户呈现消息而不是“将其传递回来”的那个,我感觉不是很优雅,因为它情侣locationUserInterface::*

您的意见?

4 个答案:

答案 0 :(得分:6)

通过添加一个间接级别可以解决所有问题。我将使用您建议的变体,并通过允许getNext接受解析方向选择的对象来将Party与Party分离。这是一个例子(未经测试):

class Location; 

class IDirectionChooser
{
public:
  virtual bool ShouldIGoThisWay(Location & way) = 0;
};

class Location
{
public:
  virtual Location * GetNext(IDirectionChooser & chooser)
  {
    return nextLocation;
  }

  virtual Describe();
private:
  Location * nextLocation;
};

class Fork : public Location
{
public:
  virtual Location * GetNext(IDirectionChooser & chooser)
  {
    for (int i = 0; i < locations.size(); i++)
      if (chooser.ShouldIGoThisWay(*locations[i]))
        return locations[i];
  }
  virtual Describe();
private:
  vector<Location *> locations;
};

class Party : public IDirectionChooser
{
public:
  void Move()
  {
    currentLocation = currentLocation->GetNext(GetDirectionChooser());
  }

  virtual IDirectionChooser & GetDirectionChooser() { return *this; }

  virtual bool ShouldIGoThisWay(Location & way)
  {
    way.Describe();
    cout << "Do you want to go that way? y/n" << endl;

    char ans;
    cin >> ans;
    return ans == 'y';
  }
};

答案 1 :(得分:1)

只要有意义并简化设计,就应该使用多态。你不应该只是因为它存在并且有一个奇特的名字而使用它。如果它确实使你的设计更简单,那么它值得耦合。

正确性和简洁性应该是每个设计决策的最终目标。

答案 2 :(得分:1)

我认为您自己发现了这些问题,可能会根据您对系统其余部分的了解或其他一些细节来解决这些问题。

如前所述:

  1. 多态性应该用于简化设计 - 在这种情况下它会做,所以很好地发现。
  2. 你有一个耦合问题 - 再次发现,耦合可能导致以后出现问题。然而,这对我说的是你的方式 应用多态可能不是最好的方法。
  3. 对接口进行编程应该允许您隐藏系统如何放在一起的内部细节,从而减少耦合。

答案 3 :(得分:0)

多态性不会带来更大的耦合,我认为它们是不同的问题。

事实上,如果您正在编程接口并遵循控制模式的一般反转,那么您将导致更少或零耦合。

在您的示例中,我没有看到位置如何与UserInterface耦合?

如果是这种情况,可以通过UserInterface和Location之间的另一个抽象级别删除耦合,例如LocationViewAdapter吗?