Usando classes "friend" no desenvolvimento de jogos

9

Normalmente, no C ++, a velocidade de desenvolvimento de jogos é valorizada em relação ao encapsulamento, portanto, você vê uma tonelada de membros da classe acessíveis ao público que realmente não deveriam ser públicos.

Parece que, na maioria dos casos, acho que apenas algumas classes muito seletas realmente precisam conhecer o funcionamento interno de outras classes a ponto de modificar ou ler seus dados privados.

Criar getters / setters públicos para esses dados privados expõe coisas que realmente não devem ser modificadas à toa ou à toa.

Um compromisso aqui seria usar classes de amigos? ou há alguma desvantagem nas aulas de amigos que não estou vendo.

David Young
fonte

Respostas:

8

Existem duas grandes desvantagens nas aulas de amizade.

  1. Você não pode escolher o que deseja expor para seus amigos. É tudo ou nada. Isso pode ser problemático se você estiver tentando impor o uso obrigatório de algum tipo de setter não inconseqüente.
  2. Suas duas aulas estão agora um pouco acopladas, no sentido de que o amigo conhece o amigo.

Dito isto, o uso de classes de amigos pode definitivamente melhorar o encapsulamento, especialmente se a alternativa for getters / setters públicos.

Além disso, pergunta relacionada ao SO: /programming/521754/when-to-use-friend-class-in-c

Tetrad
fonte
5

O encapsulamento é bom, mas a separação de preocupações é melhor.

Uma classe acessando "alguma parte privada" de outra classe pode indicar que o código não foi bem projetado em primeiro lugar.

Toda vez que você se encontra no local "caramba, preciso fazer uma aula para um amigo aqui", a pergunta que você deve fazer é: "estou fazendo isso corretamente ou existe uma maneira mais limpa?" (aka "Isso vai me morder mais tarde?").

Se você tem certeza da "simpatia", coloque-a lá sem hesitar.

egarcia
fonte
Entendo que o uso de uma classe de amigo unirá uma classe a outra. Eu queria saber se havia um padrão de design em particular que alivia o problema, porque apenas envolver algo em um getter / setter é potencialmente uma solução pior.
David Young
11
Exemplo interessante é que o padrão Factory no C ++ requer "friend" devido ao uso de construtores privados.
David Young
2

Outra opção é usar o idioma PIMPL , onde parte da implementação da estrutura é um ponteiro para outro tipo. A maioria dos usuários da classe inclui apenas o arquivo de cabeçalho normal, onde a implementação é um ponteiro opaco. As classes que precisam acessar os dados particulares podem incluir o cabeçalho que define o outro tipo e usar a interface que ele fornece.

Esse é um padrão comum para programadores C que desejam funcionalidade semelhante a um amigo. Na minha opinião, ele também se dedica mais a pensar na separação de preocupações (um princípio geralmente bom de design que leva a códigos ortogonais reutilizáveis), em vez de no encapsulamento (uma técnica específica de OO que é útil para implementar a separação de preocupações, mas também geralmente é mal usada). complicar demais as coisas).

Ele tem uma vantagem sobre o amigo por não acoplar o amigo ao amigo. Algumas pessoas podem alegar que isso é uma desvantagem, já que agora qualquer pessoa pode "fazer amizade" com sua classe. Eu acho que é um medo injustificado, já que você ainda está explicitando o relacionamento (incluindo o cabeçalho). Se você tem medo disso, tem medo da sua capacidade (ou do seu colega de trabalho) de tomar decisões arquitetônicas inteligentes. Mas se você não pode tomar essas decisões adequadamente mais tarde, por que está confiando em si mesmo friendagora?

Tem uma desvantagem no custo de tempo de execução. Ao armazenar os dados em um ponteiro, você tem pior coerência de cache e mais contagens de alocação, além de precisar de um destruidor para limpá-los.


fonte
+1 interessante, nunca ouvi falar desse conceito vindo de Java.
David Young