2010-07-19 5 views
5

Je me demande si un objet posant une question à un autre objet qui le détient indirectement est un "mauvais" design. Par exemple ...OO Design - Objet demande une question à la classe qui le détient indirectement

Exigences: Caractère (un objet) se déplace sur une grille. Quand il essaie de se déplacer vers un autre point, il doit savoir si ce point est déjà occupé par quelque chose qui le bloque, ou si cette partie de la grille est complètement inaccessible. (Notez que le personnage lui-même a besoin de savoir).

Dans l'application, un état contient un gestionnaire d'images et un gestionnaire de caractères. Le tilemanager sait quelles tuiles sont accessibles et lesquelles ne le sont pas. Le gestionnaire de caractères connaît les emplacements des tuiles des personnages. Est-ce que le caractère peut appeler une fonction à partir de l'état, par exemple AuthorizeMovement, qui détermine si le déplacement est possible via TileManager et CharacterManager, et renvoie true si oui, false sinon?

Est-ce que cela enfreint des principes importants, ce qui entraîne des problèmes sur la route?

Évidemment, ceci est généralisé et réduit à ce qui est nécessaire pour comprendre le problème.

Répondre

1

Je ne vois pas de problème. Good OO Design est livré avec de nombreux principes. Mais à la base, vous avez le grand 4: Encapsulation, Héritage, Polymorphisme et Abstraction. En outre, vous souhaitez une cohésion élevée et un faible couplage. Cela signifie que vos objets/classes peuvent s'adapter n'importe où et ne sont pas liés à une implémentation ou une classe particulière. Cela dit, il semble que vous ayez utilisé ce qui précède pour un mouvement encapsulé et que les caractères les séparent en classes séparées. Donc votre classe de personnage ne modifie pas directement le tableau, ce qui serait mauvais si c'était le cas. Au fur et à mesure que vous comprenez mieux votre problème, vous pouvez toujours refactoriser votre code pour améliorer votre conception afin de tirer parti d'autres principes.

+0

+1 d'accord, ce n'est pas nécessairement mauvais. Par exemple, un observateur demande à l'objet observé (qui contient une liste de tous les observateurs) son état après une notification state_changed. Il suffit de faire attention aux boucles infinies/verrous morts –

2

Je dirais que c'est probablement un mauvais design, oui. Le «drapeau rouge», pour ainsi dire, est la référence circulaire. Vous avez dit:

... un objet de poser une question à un autre objet qui détient indirectement

Ainsi, la « holding » objet a une référence à l'objet « occupé », et aussi Afin de «poser une question», l'objet «tenu» aura besoin d'une référence à l'objet «tenant».

Cela crée un graphique de dépendance d'objet circulaire et est souvent une odeur de code.

Il semblerait qu'une autre classe devrait avoir la responsabilité de connaître à la fois le personnage et le TileManager et/ou le CharacterManager.

+0

Il pourrait simplement utiliser une référence faible. Après tout, je doute sincèrement que son personnage puisse fonctionner indépendamment de l'État, alors en réalité, il y a une référence ici de toute façon. – Puppy

+0

@qstrain voir mon commentaire sur la réponse de Jason McCreary. Je suis d'accord avec vous sur l'odeur du code en général, mais il y a aussi des cas d'utilisation légitimes. –

+0

Je remets en question l'hypothèse que le Personnage devrait savoir quelque chose sur le fait de se déplacer. Le personnage de ce scénario n'a pas assez d'informations pour savoir si et où il peut se déplacer, ce qui voudrait dire que si le personnage décide de se déplacer, ou qu'il lui est dit de se déplacer, les autres objets doivent également mettre à jour leur état. Cela semble trop compliqué. Pourquoi ne pas inverser la situation et envoyer un message au CharacterManager et/ou au TileManager pour effectuer le déplacement. Puis un de ces objets pourrait dire au personnage où il se trouve. Cela me semble beaucoup plus naturel car toutes les informations circulent dans une direction. –

0

Ce n'est pas contre le principe de la POO. Les détails de l'appel sont totalement abstraits et vous dépendez de l'objet State de toute façon. Comment diable pourriez-vous mettre en œuvre cette fonction?

L'abstraction et les principes sont des outils utiles. Mais vous ne devriez pas dépendre d'eux pour qualifier votre code comme bon. Toutes les abstractions ou tous les principes ne sont pas bons pour tous les scénarios ou toutes les implémentations possibles. Ce sont des lignes directrices, pas des règles. Si vous ne pouvez pas voir rapidement une implémentation alternative, utilisez celle-ci, puis revenez-y.