pena polimorfismo é um aumento no acoplamento?
-
06-07-2019 - |
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?
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:
- O polimorfismo deve ser usado para simplificar o design -. Que faria neste caso, tão bem visto
- 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.
- Programação de interfaces devem permitir-lhe para esconder os detalhes internos de como o sistema é colocado em conjunto e assim reduzir o acoplamento.
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?