L'idée de base derrière la POO est que les données et le comportement (sur ces données) sont inséparables et qu'ils sont couplés à l'idée d'un objet d'une classe. Les objets ont des données et des méthodes qui fonctionnent avec ça (et d’autres données). Évidemment, selon les principes de la POO, les objets qui ne sont que des données (comme les structures C) sont considérés comme des anti-modèles.
Jusqu'ici tout va bien.
Le problème est que j'ai remarqué que mon code semble aller de plus en plus dans la direction de cet anti-pattern ces derniers temps. Il me semble que plus j'essaye de cacher des informations entre des classes et des conceptions faiblement couplées, plus mes classes deviennent un mélange de classes de données pures sans comportement et de tout comportement sans classes de données.
Je conçois généralement les classes de manière à minimiser leur connaissance de l'existence des autres classes et leur connaissance des interfaces des autres classes. J'applique cela de manière descendante, les classes de niveau inférieur ne connaissent pas les classes de niveau supérieur. Par exemple:
Supposons que vous ayez une API de jeu de cartes générale. Vous avez une classe Card. Maintenant, cette Cardclasse doit déterminer la visibilité pour les joueurs.
Une façon est d'avoir boolean isVisible(Player p)sur la Cardclasse.
Une autre est d'avoir boolean isVisible(Card c)sur la Playerclasse.
Je n'aime pas particulièrement la première approche, qui accorde des connaissances sur les Playerclasses supérieures à une Cardclasse inférieure .
Au lieu de cela, j'ai opté pour la troisième option où nous avons une Viewportclasse qui, à partir d' Playerune liste de cartes, détermine quelles cartes sont visibles.
Cependant, cette approche prive les classes Cardet les Playerclasses d'une fonction membre possible. Une fois que vous faites cela pour d' autres choses que la visibilité des cartes, il vous reste Cardet les Playerclasses qui contiennent uniquement des données que toutes les fonctionnalités sont mis en œuvre dans d' autres classes, qui sont pour la plupart des classes sans données, seulement des méthodes, comme le Viewportci - dessus.
Cela va clairement à l’encontre de l’idée principale de la programmation orientée objet.
Quelle est la bonne façon? Comment faire pour minimiser les interdépendances entre les classes et les connaissances et couplages supposés, sans pour autant aboutir à une conception bizarre où toutes les classes de bas niveau contiennent uniquement des données et les classes de haut niveau contiennent toutes les méthodes? Quelqu'un at-il une troisième solution ou perspective sur la conception de classe qui évite tout le problème?
PS Voici un autre exemple:
Supposons que vous ayez une classe DocumentIdimmuable, qu’un seul BigDecimal idmembre et un getter pour ce membre. Maintenant, vous devez avoir une méthode quelque part, qui donne un DocumentIdretour Documentpour cet identifiant depuis une base de données.
Le faites vous:
- Ajoutez une
Document getDocument(SqlSession)méthode à laDocumentIdclasse, introduisant soudainement des connaissances sur votre persistance ("we're using a database and this query is used to retrieve document by id"), l’API utilisée pour accéder à une base de données, etc. De plus, cette classe nécessite maintenant la persistance du fichier JAR pour la compilation. - Ajoutez une autre classe avec la méthode
Document getDocument(DocumentId id), en laissant laDocumentIdclasse morte, sans comportement, comme une classe semblable à la structure.