Frage

Ich schreibe ein stark vereinfachte Spiel etwas mehr C ++ Erfahrung zu lernen zu bekommen, und ich habe eine Idee, wo ich Polymorphismus fühlen fast funktioniert, aber nicht. Bei diesem Spiel bewegt sich die Party ziemlich linear durch einen Map, sondern eine Fork in der Straße gelegentlich auftreten kann. Eine Gabel ist (im Grunde) ein std::vector<location*>.Originally ich so etwas wie die folgenden in dem einer Party Elementfunktion codieren würde:

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

Aber ich frage mich, ob eine Variante der folgenden könnte besser sein:

CurrLocation = CurrLocation->getNext();

Mit Gabel tatsächlich von Ort abgeleitet werden, und einige neue Funktion getNext() Überlastung. Aber im letzteren Fall die location (eine niedrige Level-Struktur) hätte denjenigen sein, um die Nachricht zu dem Benutzer zu präsentieren, anstatt „passing diese wieder nach oben“, was ich fühle mich nicht elegant ist, wie es Paare location UserInterface::* .

Ihre Meinung?

War es hilfreich?

Lösung

Alle Probleme können durch das Hinzufügen eines Dereferenzierungsebene gelöst werden. Ich würde Ihre vorgeschlagene Variante verwenden und entkoppeln Lage von Partei, indem getNext ein Objekt zu akzeptieren, die Richtungs Entscheidungen löst. Hier ist ein Beispiel (nicht getestet):

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';
  }
};

Andere Tipps

Sie sollten Polymorphismus verwenden, solange es Sinn macht und vereinfacht Ihr Design. Sie sollten es nicht nur benutzen, weil es existiert und hat einen ausgefallenen Namen. Wenn es Ihr Design einfacher macht, dann ist es die Kupplung wert.

Correctness und Einfachheit sollte das ultimative Ziel jedes Design-Entscheidung sein.

Ich glaube, Sie haben die Probleme selbst entdeckt und kann es wahrscheinlich mit Ihrem Wissen über den Rest des Systems oder ein paar mehr Details hier für uns zu sehen trainieren.

Wie bereits erwähnt wurde:

  1. Polymorphismus verwendet werden soll, um das Design zu vereinfachen -., Die es in diesem Fall tun würde, so gut spotted
  2. Sie haben ein Problem mit der Kupplung - wieder gut gepunktet, Kupplung kann später zu Problemen führen. Dies ist jedoch für mich, was sagt, ist, dass die Art und Weise, in denen Sie die Polymorphismus Anwendung möglicherweise nicht der beste Weg sein.
  3. Programmieren Schnittstellen sollten Ihnen ermöglichen, die internen Details, wie das System gestellt wird, zusammen zu verstecken und so die Kupplung zu reduzieren.

Polymorphismus nicht zu einem größeren Kupplung verleihen, ich denke, sie sind getrennte Fragen.

In der Tat, wenn Sie Schnittstellen programmieren und folgende allgemeine Umkehrung der Steuermuster, dann werden Sie auf weniger oder Null-Kupplung führen.

Sie Beispiel, ich sehe nicht, wie Standort Userinterface gekoppelt ist?

Wenn dies der Fall ist, kann die Kupplung durch eine weitere Abstraktionsebene zwischen Userinterface und Ort, wie LocationViewAdapter entfernt werden?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top