Pergunta

Eu estou escrevendo um jogo simplista de aprender obter alguma experiência mais C ++, e eu tenho uma idéia de onde eu me sinto polimorfismo quase obras, mas não o faz. Neste jogo, o Party move bastante linearmente através de um Map, mas pode ocasionalmente encontrar um Fork na estrada. Um garfo é (basicamente) um std::vector<location*>.Originally eu ia código algo como o seguinte para a função membro Party:

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

Mas eu queria saber se alguma variante do seguinte poderia ser melhor:

CurrLocation = CurrLocation->getNext();

Com Forquilha realmente sendo derivado de Localização e sobrecarga alguma nova função getNext(). Mas, no último caso, o location (uma estrutura de baixo nível) teria que ser o único a apresentar a mensagem para o usuário em vez de "passar este back-up", que eu não sensação é elegante como casais location para UserInterface::* .

As suas opiniões?

Foi útil?

Solução

Todos os problemas podem ser resolvidos, adicionando um nível de engano. Gostaria de usar a sua variante sugeriu, e desacoplar Localização do Partido, permitindo getNext para aceitar um objeto que resolve escolhas direcionais. Aqui está um exemplo (não testado):

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

Outras dicas

Você deve usar polimorfismo enquanto faz sentido e simplifica o seu design. Você não deve usá-lo apenas porque ela existe e tem um nome fantasia. Se ele faz o seu projeto mais simples, então vale a pena o acoplamento.

A exatidão e simplicidade deve ser o objetivo final de cada decisão de projeto.

Eu acho que você viu as questões a si mesmo e provavelmente pode trabalhá-lo para fora com o seu conhecimento do resto do sistema ou alguns mais detalhes aqui para nos olhar.

Como já foi mencionado:

  1. O polimorfismo deve ser usado para simplificar o design -. Que faria neste caso, tão bem visto
  2. Você tem um problema com o acoplamento - novamente bem manchado, acoplamento pode levar a problemas mais tarde. No entanto, o que isso me diz é que a maneira em que você está aplicando o polimorfismo pode não ser o melhor caminho.
  3. Programação de interfaces devem permitir-lhe para esconder os detalhes internos de como o sistema é colocado em conjunto e assim reduzir o acoplamento.
não

O polimorfismo não emprestar para acoplamento maior, eu acho que eles são questões separadas.

De fato, se você está programando a interfaces e seguindo inversão geral de padrões de controle, então você vai conduzir a uma menor ou nula acoplamento.

Em que você exemplo, eu não vejo como localização é acoplado a UserInterface?

Se este for o caso, pode o acoplamento ser removido através de um outro nível de abstração entre UserInterface e localização, tais como LocationViewAdapter?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top