Utilizzo di classi "amiche" nello sviluppo del gioco


9

In genere nella velocità di sviluppo del gioco C ++ viene valutata l'incapsulamento, quindi si vedono un sacco di membri della classe accessibili al pubblico che in realtà non dovrebbero essere pubblici.

Mi sembra di trovare nella maggior parte dei casi che solo pochi casi molto selezionati hanno davvero bisogno di conoscere il funzionamento interno di un'altra classe al punto da modificare o leggere i loro dati privati.

La creazione di getter / setter pubblici per questi dati privati ​​espone cose che in realtà non dovrebbero essere modificate volenti o nolenti.

Sarebbe un compromesso utilizzare le classi di amici? o c'è qualche svantaggio per le classi di amici che non vedo.

Risposte:


8

Ci sono due principali svantaggi per le classi amichevoli.

  1. Non puoi scegliere quello che vuoi esporre ai tuoi amici. È tutto o niente. Ciò può rivelarsi problematico se si sta tentando di imporre l'uso obbligatorio di un tipo di setter non insignificante.
  2. Le tue due classi sono ora un po 'accoppiate, nel senso che l'amico conosce l'amico.

Detto questo, l'uso delle classi di amici può sicuramente migliorare l'incapsulamento, soprattutto se l'alternativa è getter / setter pubblici.

Inoltre, domanda correlata su SO: /programming/521754/when-to-use-friend-class-in-c


5

L'incapsulamento è piacevole, ma la separazione delle preoccupazioni è migliore.

Una classe che accede a "una parte privata" di un'altra classe potrebbe indicare che il codice non è ben progettato in primo luogo.

Ogni volta che ti trovi nel punto "Accidenti, devo fare una lezione di amici qui", la domanda che dovresti porti è "Sto facendo questo correttamente o c'è un modo più pulito?" (aka "Mi morderà nel culo più tardi?").

Se sei sicuro della "cordialità", mettilo lì senza esitazione.


Capisco come l'utilizzo di una classe di amici associerà strettamente una classe all'altra. Mi chiedevo se ci fosse un modello di progettazione in particolare che allevia il problema, perché semplicemente avvolgere qualcosa in un getter / setter è potenzialmente una soluzione peggiore.
David Young,

1
Un esempio interessante è che il modello Factory in C ++ richiede "amico" a causa dell'uso di costruttori privati.
David Young,

2

Un'altra opzione è utilizzare il linguaggio PIMPL , in cui parte dell'implementazione della struttura è un puntatore a un altro tipo. La maggior parte degli utenti della classe includerà semplicemente il normale file di intestazione, in cui l'implementazione è un puntatore opaco. Le classi che richiedono l'accesso ai dati privati ​​possono includere l'intestazione che definisce l'altro tipo e utilizzare l'interfaccia fornita.

Questo è un modello comune per i programmatori C che desiderano funzionalità simili agli amici. A mio avviso, si impegna anche più attentamente a pensare alla separazione delle preoccupazioni (un principio di progettazione generalmente buono che porta a un codice ortogonale riutilizzabile) piuttosto che all'incapsulamento (una tecnica specifica OO che è utile per implementare la separazione delle preoccupazioni, ma spesso anche utilizzata in modo improprio complicare troppo le cose).

Ha un vantaggio rispetto all'amico che non abbina affatto l'amico all'amico. Alcune persone potrebbero affermare che è uno svantaggio, dal momento che chiunque può "fare amicizia" con la tua classe. Penso che sia una paura ingiustificata, dal momento che stai ancora rendendo esplicita la relazione (includendo l'intestazione). Se ne hai paura, hai paura della tua (o del tuo collega) capacità di prendere decisioni architettoniche intelligenti. Ma se non riesci a prendere quelle decisioni correttamente in seguito, perché ti fidi di te stesso friendora?

Ha uno svantaggio del costo di runtime. Memorizzando i dati in un puntatore si ha una peggiore coerenza della cache e un numero maggiore di allocazioni e è anche necessario un distruttore per ripulirlo.


+1 interessante, non ho sentito parlare di questo concetto proveniente da uno sfondo Java.
David Young,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.