Ecrire vos noms, verbes, adjectifs est une excellente approche, mais je préfère penser à la conception de classe comme à la question de savoir quelles données doivent être cachées ?
Imaginez que vous ayez un Query
objet et un Database
objet:
L' Query
objet vous aidera à créer et à stocker une requête - stocker, c'est la clé ici, car une fonction pourrait vous aider à en créer une tout aussi facilement. Peut - être que vous pourriez rester: Query().select('Country').from_table('User').where('Country == "Brazil"')
. Peu importe la syntaxe exacte - c'est votre travail! - la clé est que l'objet vous aide à cacher quelque chose , dans ce cas les données nécessaires pour stocker et générer une requête. La puissance de l'objet vient de la syntaxe de son utilisation (dans ce cas un enchaînement intelligent) et de ne pas avoir besoin de savoir ce qu'il stocke pour le faire fonctionner. Si cela est fait correctement, l' Query
objet peut générer des requêtes pour plus d'une base de données. Il stockerait en interne un format spécifique mais pourrait facilement être converti en d'autres formats lors de la sortie (Postgres, MySQL, MongoDB).
Maintenant, réfléchissons à l' Database
objet. Qu'est-ce que cela cache et stocke? Eh bien, il est clair qu'il ne peut pas stocker le contenu complet de la base de données, car c'est pourquoi nous avons une base de données! Alors quel est le point? L'objectif est de cacher le fonctionnement de la base de données aux personnes qui utilisent l' Database
objet. De bonnes classes simplifieront le raisonnement lors de la manipulation de l'état interne. Pour cet Database
objet, vous pouvez masquer le fonctionnement des appels réseau, effectuer des requêtes ou des mises à jour par lots, ou fournir une couche de mise en cache.
Le problème est que cet Database
objet est ÉNORME. Il représente comment accéder à une base de données, donc sous les couvertures, il pourrait tout faire. Il est clair que la mise en réseau, la mise en cache et le traitement par lots sont assez difficiles à gérer en fonction de votre système, il serait donc très utile de les cacher. Mais, comme beaucoup de gens le remarqueront, une base de données est incroyablement complexe, et plus vous êtes éloigné des appels de base de données bruts, plus il est difficile de régler les performances et de comprendre comment les choses fonctionnent.
C'est le compromis fondamental de la POO. Si vous choisissez la bonne abstraction, cela simplifie le codage (String, Array, Dictionary), si vous choisissez une abstraction trop grande (Database, EmailManager, NetworkingManager), cela peut devenir trop complexe pour vraiment comprendre comment cela fonctionne, ou quoi attendre. Le but est de cacher la complexité , mais une certaine complexité est nécessaire. Une bonne règle de base est de commencer par éviter les Manager
objets, et à la place de créer des classes qui ressemblent à structs
- tout ce qu'ils font est de contenir des données, avec quelques méthodes d'aide pour créer / manipuler les données afin de vous faciliter la vie. Par exemple, dans le cas de EmailManager
start avec une fonction appelée sendEmail
qui prend un Email
objet. C'est un point de départ simple et le code est très facile à comprendre.
Comme pour votre exemple, réfléchissez aux données qui doivent être réunies pour calculer ce que vous recherchez. Si vous vouliez savoir jusqu'où un animal marchait, par exemple, vous pourriez avoir des classes AnimalStep
and AnimalTrip
(collection of AnimalSteps). Maintenant que chaque voyage a toutes les données Step, alors il devrait être capable de comprendre des choses à ce sujet, cela a peut-être du AnimalTrip.calculateDistance()
sens.