2010-07-19 7 views
5

Mi chiedo se un oggetto che fa una domanda a un altro oggetto che lo trattiene indirettamente sia un design "cattivo". Ad esempio ...OO Design - L'oggetto fa una domanda alla classe che lo trattiene indirettamente

Requisiti: Il carattere (un oggetto) si sposta su una griglia. Quando tenta di spostarsi in un altro punto, deve sapere se quel punto è già occupato da qualcosa che lo blocca o se quella parte della griglia è completamente inaccessibile. (Nota che il personaggio stesso deve sapere).

Nell'applicazione, uno stato contiene un tilemanager e un character manager. Il tilemanager sa quali mattonelle sono accessibili e quali no. Il character manager conosce le posizioni delle tessere dei personaggi.

Potrebbe essere ragionevole che il carattere richiami una funzione dallo stato, ad esempio AuthorizeMovement, che determina se il movimento è possibile tramite TileManager e CharacterManager e restituisce true in caso affermativo, false in caso contrario?

Questa violazione di principi importanti può causare problemi lungo la strada?

Ovviamente questo è generalizzato e ridotto a ciò che è necessario per capire il problema.

risposta

1

Non vedo alcun problema. Good OO Design ha molti principi. Ma al suo interno hai il grande 4: incapsulamento, ereditarietà, polimorfismo e astrazione. Inoltre, si desidera un'elevata coesione e un basso accoppiamento. Significa che i tuoi oggetti/classi possono adattarsi ovunque e non sono legati a una particolare implementazione o classe.

Con ciò detto, sembra che tu abbia usato il movimento sopra incapsulato e che i personaggi li astraglino in classi separate. Quindi la tua classe Personaggio non sta modificando direttamente la scheda, il che sarebbe male se lo fosse.

Man mano che acquisisci una conoscenza più approfondita del tuo problema, puoi sempre refactoring il codice per migliorare il tuo design per trarre vantaggio da altri principi.

+0

+1 concordato, non è necessariamente male. Ad esempio un osservatore chiede l'oggetto osservato (che contiene un elenco di tutti gli osservatori) per il suo stato dopo una notifica di stato modificato. Basta fare attenzione a infiniti loop/dead lock –

2

Suggerirei che probabilmente è un cattivo progetto, sì. La "bandiera rossa", per così dire, è il riferimento circolare. Hai detto:

... un oggetto porre una domanda a un altro oggetto che indirettamente tiene

Così, la "holding" oggetto ha un riferimento all'oggetto "tenuto", e anche in per "porre una domanda" l'oggetto "tenuto" avrà bisogno di un riferimento all'oggetto "trattenuto".

Questo rende un grafico di dipendenza di oggetti circolare ed è spesso un odore di codice.

Sembrerebbe che un'altra classe debba avere la responsabilità di conoscere sia il carattere che il TileManager e/o CharacterManager.

+0

Poteva semplicemente usare un riferimento debole. Dopotutto, dubito sinceramente che il suo personaggio possa operare indipendentemente dallo stato, quindi in realtà c'è comunque un riferimento qui. – Puppy

+0

@qstrain vedere il mio commento sulla risposta di Jason McCreary. Sono d'accordo con te riguardo all'odore del codice in generale, ma ci sono anche casi d'uso legittimi. –

+0

Sto mettendo in dubbio l'ipotesi che il personaggio debba sapere qualcosa sul movimento stesso. Il personaggio in questo scenario non ha abbastanza informazioni per sapere se e dove può muoversi, il che significherebbe che se il personaggio decide di muoversi, o se gli viene detto di muoversi, anche altri oggetti devono aggiornare il loro stato. Questo sembra troppo complicato. Perché non capovolgere la situazione e inviare messaggi a CharacterManager e/o TileManager per eseguire la mossa. Quindi uno di quegli oggetti potrebbe dire al personaggio dove si trova. Mi sembra molto più naturale in quanto tutte le informazioni fluiscono in una direzione. –

0

Non è contrario al principio OOP. I dettagli della chiamata sono totalmente astratti e dipendono comunque dall'oggetto Stato. Come mai, altrimenti, potresti implementare questa funzione?

L'astrazione e i principi sono strumenti utili. Ma non dovresti dipendere da loro per qualificare il tuo codice come buono. Non ogni astrazione o ogni principio è buono per ogni scenario o ogni possibile implementazione. Sono linee guida, non regole. Se non riesci a vedere rapidamente un'implementazione alternativa, usa questa e poi torna ad essa.

Problemi correlati