Per completare il mio commento sopra:
Il principio guida involontariamente - The Law of Demeter:
Il principio in questione è il Law of Demeter , che afferma molto liberamente (tratto da Wikipedia):
[Objects should] only talk to [their] immediate friends.
In questo senso, il tuo codice sembra violare un principio guida piuttosto importante dell'orientamento agli oggetti. Pertanto, una possibile soluzione sarebbe quella di parlare solo con ScreenManager
e chiedergli di darti il ClientBounds
. Sfortunatamente, potresti non avere il controllo del codice (cioè ScreenManager
, ecc.), Quindi potrebbe essere impossibile. Anche se è possibile, puoi vedere che ScreenManager
non può semplicemente chiamare Game.Window.ClientBounds
senza rompere la Legge, quindi ha bisogno di chiedere Game
per ottenere ClientBounds
. A seconda di chi chiedi, questo diventa non mantenibile rapidamente. L'articolo di Wikipedia continua con il seguente avviso:
Although the LoD increases the adaptiveness of a software system, it may also result in having to write many wrapper methods to propagate calls to components; in some cases, this can add noticeable time and space overhead.
Un approccio diverso al principio: come DTO:
Il libro Pulisci codice di Robert Martin, di solito eccellente, chiama il "concatenamento di treni" di cui sopra, sia per il suo aspetto, così come la possibilità che qualcosa vada storto. Tuttavia, viene fatta una distinzione (si spera che allo zio Bob non importi le mie citazioni qui, con alcune modifiche):
Are these two snippets of code violations
of the Law of Demeter? Certainly
the containing module knows [snip]... That’s a lot of knowledge
for one function to know. The calling function knows how to navigate through
a lot of different objects. Whether this is a violation of Demeter depends on whether or not [list of objects, in your case: Game and Window] are objects or data structures. If they are objects, then their internal structure should be hidden rather than exposed, and so knowledge of their innards is a clear violation of the Law of Demeter. On the other hand, if [they] are just data structures with no behavior, then they naturally expose their internal structure, and so
Demeter does not apply.
Quindi, in sintesi, la Legge di Demetra potrebbe non essere violata, se vediamo gli oggetti intermedi come principalmente DTO (oggetti senza comportamento).
Un possibile suggerimento: IoC
Se stai arrivando al punto in cui questo tipo di cosa diventa un problema, puoi sempre considerare Inversion of Control. In breve, stiamo parlando di eliminare la logica di come ottenere l'oggetto ClientBounds
fuori da TitleScreen
. In generale quindi, TitleScreen
si aspetterebbe di fornire un ClientBounds
attorno al tempo della sua costruzione (sebbene ci siano una varietà di altri approcci, come la proprietà o l'iniezione di parametri del metodo); spostando la responsabilità di conoscere la gerarchia dell'oggetto completo da qualche altra parte (in genere un codice di cablaggio).
Sebbene ciò non risolva necessariamente la violazione del LoD, ti dà l'opportunità di rimuovere alcune duplicazioni dal tuo progetto. Rendi anche TitleScreen
in meno dipendente dall'intera catena di oggetti e potenzialmente più unità testabile.
È completamente possibile farlo a mano, ma per rendere IoC più realistico e sopportabile, le persone normalmente usano framework di dipendenze per l'iniezione, come Unità o Ninject .