Non , un objet ne doit pas nécessairement représenter une entité.
En fait, je dirais que lorsque vous cessez de considérer les objets comme des entités physiques, vous obtenez enfin les avantages promis par la programmation orientée objet.
Ce n'est pas le meilleur exemple, mais la conception de la cafetière est probablement celle où la lumière a commencé à s'allumer pour moi.
Les objets concernent les messages. Ils concernent les responsabilités. Ils ne concernent pas les voitures, les utilisateurs ou les commandes.
Je sais que nous enseignons à OO de cette façon, mais après quelques essais, nous réalisons à quel point il est fondamentalement frustrant de savoir où vont les choses lorsque vous essayez de faire MVC, MVVM ou MVWther. Vos modèles sont ridiculement gonflés ou vos contrôleurs le sont. Pour la navigabilité, il est bon de savoir que tout ce qui touche les véhicules se trouve dans le fichier Vehicle.ext, mais lorsque votre application concerne les véhicules, vous vous retrouvez inévitablement avec 3 000 lignes de spaghettis dans ce fichier.
Lorsque vous avez un nouveau message à envoyer, vous avez au moins un nouvel objet, et peut-être une paire d’eux. Donc, dans votre question sur un ensemble de méthodes, je dirais que vous parlez éventuellement d'un ensemble de messages. Et chacun pourrait être son propre objet, avec son propre travail à faire. Et ça va. Cela deviendra évident lorsque vous séparerez les éléments qui doivent vraiment être ensemble. Et vous les mettez ensemble. Mais vous ne perdez pas immédiatement toutes les méthodes dans un tiroir vaguement approprié pour des raisons de commodité si vous souhaitez profiter de OO.
Parlons de sacs de fonctions
Un objet peut être juste une collection de méthodes et être toujours OO, mais mes "règles" sont assez strictes.
La collection devrait avoir une responsabilité unique, et cette responsabilité ne peut pas être aussi générique que "Fait des choses aux moteurs". Je pourrais faire une telle chose comme une façade de couche de service, mais je suis parfaitement conscient que je suis paresseux pour des raisons de navigabilité / découverte, pas parce que j'essaye d'écrire du code OO.
Toutes les méthodes doivent être au même niveau d'abstraction. Si une méthode récupère des objets Motor et qu'une autre renvoie Horsepower, la différence est probablement trop grande.
L'objet doit fonctionner sur le même "type" de données. Cet objet manipule les moteurs (start / stop), celui-ci fait des manivelles, celui-ci gère le séquencement de l'allumage, celui-ci prend une forme html. Ces données pourraient éventuellement être des champs sur l'objet et cela semblerait cohérent.
Je construis généralement des objets de ce type lorsque je fais des transformations, de la composition ou que je ne veux tout simplement pas m'inquiéter de la mutabilité.
Je trouve que me concentrer sur les responsabilités des objets me conduit à la cohésion. Il doit y avoir une certaine cohésion pour être un objet, mais il n’est pas nécessaire qu’il y ait des champs ou beaucoup de comportement pour que ce soit un objet. Si je construisais un système qui nécessitait ces 5 méthodes de moteur, je commencerais avec 5 objets différents qui font ces choses. Au fur et à mesure que je trouvais des points communs, je pouvais soit commencer à fusionner les choses, soit utiliser des objets "auxiliaires" communs. Cela me fait basculer dans les préoccupations ouvertes / fermées. Comment puis-je extraire cette fonctionnalité afin de ne plus jamais avoir à modifier ce fichier, mais à l'utiliser quand c'est nécessaire?
Les objets sont des messages
Les champs importent peu à un objet - obtenir et définir des registres ne change pas le monde en dehors du programme. Collaborer avec d'autres objets permet de faire le travail. Cependant, la force de OO réside dans le fait que nous pouvons créer des abstractions afin de ne pas avoir à penser à tous les détails en même temps. Les abstractions qui fuient ou qui n’ont pas de sens sont problématiques. Nous réfléchissons donc profondément (peut-être trop) à la création d’objets correspondant à nos modèles mentaux.
Question clé: Pourquoi ces deux objets doivent-ils se parler?
Pensez à l'objet en tant qu'organe d'une personne: il a un objectif par défaut et ne modifie le comportement que lorsqu'il reçoit un message spécifique dont il se soucie.
Imaginez un scénario où vous êtes sur le passage piéton et où une voiture arrive rapidement. En tant qu'objet du cerveau, je détecte un facteur de stress. Je dis à l'hypothalamus d'envoyer de la corticotrophine. La glande pituitaire reçoit ce message et libère l'hormone corticotrophe surrénalienne. Les glandes surrénales reçoivent ce message et créent de l'adrénaline. Lorsque l'objet musculaire reçoit ce message d'adrénaline, il se contracte. Quand le coeur reçoit le même message, il bat plus vite. Toute une chaîne d'acteurs est impliquée dans le démarrage du comportement complexe du sprint dans la rue et ce sont les messages qui importent. L'objet cérébral sait comment amener l'hypothalamus à envoyer l'alerte, mais il ne connaît pas la chaîne d'objets qui finira par provoquer le comportement. De même, le cœur n'a aucune idée de l'origine de l'adrénaline,
Ainsi, dans cet exemple ( simplifié ), l’objet de la glande surrénale doit seulement savoir comment prendre de l’ACTH et produire de l’adrénaline. Cela n'a pas besoin de champs pour le faire, pourtant cela me semble toujours un objet.
Maintenant, si notre application est conçue uniquement pour courir dans la rue, je n’ai peut-être pas besoin de l’hypophyse et des objets de la glande surrénale. Ou j'ai seulement besoin d'un objet de l'hypophyse qui ne représente qu'une petite partie de ce que nous pourrions conceptuellement considérer comme le "modèle de l'hypophyse". Ces concepts existent tous en tant qu’entités conceptuelles, mais c’est un logiciel et nous pouvons créer AdrenalineSender ou MuscleContractor ou autre, et ne pas trop nous soucier de l’incomplétude de notre modèle.