Supposons que vous ayez les éléments suivants:
+--------+ +------+
| Animal | | Food |
+-+------+ +----+-+
^ ^
| |
| |
+------+ +-------+
| Deer | | Grass |
+------+ +-------+
Deer
hérite Animal
et Grass
hérite de Food
.
Jusqu'ici tout va bien. Animal
les objets peuvent manger des Food
objets.
Permet maintenant de mélanger un peu. Ajoutons un Lion
qui hérite de Animal
.
+--------+ +------+
| Animal | | Food |
+-+-----++ +----+-+
^ ^ ^
| | |
| | |
+------+ +------+ +-------+
| Deer | | Lion | | Grass |
+------+ +------+ +-------+
Maintenant, nous avons un problème parce que Lion
peut manger à la fois Deer
et Grass
, mais ce Deer
n'est pas Food
le cas Animal
.
Sans utiliser l'héritage multiple et la conception orientée objet, comment résoudre ce problème?
Pour info: j'ai utilisé http://www.asciiflow.com pour créer les diagrammes ASCII.
object-oriented
object-oriented-design
Michael Irey
la source
la source
IHuntable
, Sheep et Cow sontIHerdable
(contrôlables par l'homme), et Lion implémente uniquement IAnimal, ce qui n'implique aucune de ces interfaces. AOE3 prend en charge l'interrogation de l'ensemble des interfaces prises en charge par un objet particulier (similaire àinstanceof
) qui permet à un programme d'interroger ses capacités.Réponses:
EST une relation = héritage
Lion est un animal
A des relations A = composition
La voiture a une roue
Relations CAN DO = Interfaces
Je peux manger
la source
ICanBeEaten
ouIEdible
OO n'est qu'une métaphore qui s'inspire du monde réel. Mais les métaphores ne vont que si loin.
Normalement, il n'y a pas de bonne façon de modéliser quelque chose dans OO. Il existe une bonne façon de le faire pour un problème particulier dans un domaine particulier et vous ne devriez pas vous attendre à ce que cela fonctionne bien si vous modifiez votre problème, même si les objets du domaine sont les mêmes.
Je pense que c'est une idée fausse la plupart des Comp. Eng. les étudiants ont dans leurs premières années. L'OO n'est pas une solution universelle, juste un outil décent pour certains types de problèmes qui peuvent modéliser raisonnablement votre domaine.
Je n'ai pas répondu à la question, précisément parce que nous manquons d'informations sur le domaine. Mais avec ce qui précède à l'esprit, vous pourriez être en mesure de concevoir quelque chose qui convient à vos besoins.
la source
Vous voulez décomposer davantage les animaux en leurs sous-classes (ou du moins dans la mesure où cela a du sens pour ce que vous faites). Étant donné que vous travaillez avec ce qui ressemble à des animaux de base et à deux types de nourriture (plantes et viande), il est logique d'utiliser des carnivores et des herbivores pour mieux définir un animal et le garder séparé. Voici ce que j'ai rédigé pour vous.
Comme vous pouvez le voir, ils exposent tous deux une méthode de manger, mais ce qu'ils mangent change. Le Lion peut maintenant tuer un cerf, le cerf peut mourir et retourner DeerMeat, et la question originale des OP sur la façon de permettre à un lion de manger un cerf mais pas de l'herbe est résolue sans concevoir un écosystème entier.
Bien sûr, cela devient très rapidement intéressant, car un cerf peut également être considéré comme un type de viande, mais pour garder les choses simples, je créerais une méthode appelée kill () sous le cerf, qui renvoie une viande de cerf, et la mettre comme un classe de béton prolongeant la viande.
la source
Eat(Plant p)
et lesEat(Meat m)
deux violent LSP.Ma conception serait comme ceci:
Parce que les animaux mettent en œuvre IMeat et le cerf est un animal (herbivore), le lion, qui est un animal (carnivore) qui peut manger IMeat, peut également manger du cerf.
Le cerf est un herbivore, il peut donc manger de l'herbe car il met en œuvre IVegetable.
Les carnivores ne peuvent pas manger IVegeable et les herbivores ne peuvent pas manger IMeat.
la source
Quels aliments un animal peut manger ne forment pas réellement une hiérarchie, dans ce cas, la nature n'a pas pu se conformer inexcusablement à une modélisation orientée objet simple (notez que même si c'était le cas, l'animal devrait hériter de la nourriture, car c'est de la nourriture).
La connaissance des aliments qu'un animal peut manger ne peut pas vivre entièrement avec l'une ou l'autre des classes, donc simplement avoir une référence à un membre de la hiérarchie alimentaire ne peut pas être suffisant pour vous dire ce que vous pouvez manger.
C'est une relation plusieurs à plusieurs. Cela signifie que chaque fois que vous ajoutez un animal, vous devez déterminer ce qu'il peut manger et chaque fois que vous ajoutez un aliment, vous devez déterminer ce qui peut le manger. L'existence d'une structure supplémentaire à exploiter dépend des animaux et des aliments que vous modélisez.
L'héritage multiple ne résout pas non plus vraiment très bien cela. Vous avez besoin d'une sorte de collection de choses qu'un animal peut manger, ou d'animaux qui peuvent manger un aliment.
la source
J'aborderai le problème sous un angle différent: la POO concerne le comportement. Dans votre cas, a-t
Grass
-il un comportement dont être enfantFood
? Donc, dans votre cas, il n'y aura pas deGrass
classe, ou du moins, il ne sera pas hérité deFood
. De plus, si vous avez besoin de savoir qui peut manger quoi au moment de la compilation, il est douteux que vous ayez besoin d'Animal
abstraction. De plus, il n'est pas rare de voir des carnivores manger de l'herbe , mais pas pour se nourrir.Donc, je concevoir cela comme (ne va pas déranger avec l'art ASCI):
IEdible
avec propriétéType
, qui est une énumération de viande, de plante, de carcasse, etc. (cela ne changera pas souvent et n'a pas de comportement spécifique, il n'est donc pas nécessaire de le modéliser comme recherche de classe).Animal
avec des méthodesCanEat(IEdible food)
etEat(IEdible food)
, qui sont logiques. Ensuite, des animaux spécifiques peuvent vérifier chaque fois qu'ils peuvent manger de la nourriture donnée dans des circonstances données, puis manger cette nourriture pour se nourrir / faire autre chose. De plus, je modéliserais les classes Carnivore, Herbivore, Omnivore comme modèle de stratégie , plutôt que dans le cadre de la hiérarchie animale.la source
TL; DR: Conception ou modèle avec un contexte.
Je pense que votre question est difficile parce qu'elle manque de contexte du problème réel que vous essayez de résoudre. Vous avez des modèles et des relations, mais vous n'avez pas le cadre dans lequel il doit fonctionner. Sans contexte, la modélisation et les métaphores ne fonctionnent pas bien, laissant la porte ouverte à de multiples interprétations.
Je pense qu'il est plus productif de se concentrer sur la façon dont les données seront consommées. Une fois que vous avez le modèle d'utilisation des données, il est plus facile de revenir en arrière sur ce que devraient être les modèles et les relations.
Par exemple, des exigences plus détaillées nécessiteront différentes relations d'objet:
Animals
eat
ing nonFood
similairesGastroliths
Chocolate
commePoison
pourDogs
, mais pas pourHumans
Si nous commençons par l'exercice de modélisation de la relation simple présentée, l'interface alimentaire peut être la meilleure; et si c'est la somme totale de la façon dont les relations dans le système, alors votre amende. Cependant, quelques exigences ou relations supplémentaires peuvent considérablement affecter les modèles et les relations qui fonctionnaient dans le cas le plus simple.
la source
Approche de composition sur héritage ECS:
Pseudocode:
Nature
est unesystem
boucle qui parcourt ces entités, recherchant quels composants elles possèdent via une fonction de requête généralisée.Nature
obligera les entités qui ont faim de viande à attaquer d'autres entités qui ont de la viande comme nourriture en utilisant leurs armes, sauf si elles ont une affinité avec cette entité. Si l'attaque réussit, l'entité se nourrira de sa victime, auquel cas la victime se transformera en cadavre privé de viande.Nature
incitera les entités qui ont faim de plantes à se nourrir d'entités qui ont des plantes comme aliment, à condition qu'elles existent.Peut-être que nous voulons étendre
Grass
pour avoir un besoin de soleil et d'eau, et nous voulons introduire le soleil et l'eau dans notre monde. Pourtant,Grass
il ne peut pas les rechercher directement, comme il ne l'a pas faitmobility
.Animals
peut également avoir besoin d'eau, mais peut le rechercher activement depuismobility
. Il est assez facile de continuer à étendre et à modifier ce modèle sans casse en cascade de la conception entière, car nous ajoutons simplement de nouveaux composants et étendons le comportement de nos systèmes (ou le nombre de systèmes).la source
Comme la plupart des choses, cela dépend .
Cela dépend de ce que vous voyez «ce problème».
Si vous posez des questions sur le problème général d'implémentation, la réponse dépendra des capacités de votre environnement. Les interfaces IFood et IAnimal pourraient fonctionner, avec une sous-classe EdibleAnimal implémentant les deux interfaces. Si votre environnement ne prend pas en charge les interfaces, faites simplement hériter Animal de la nourriture.
Si vous posez des questions sur ce problème de conception spécifique, faites simplement hériter les animaux de la nourriture. C'est la chose la plus simple qui pourrait fonctionner.
Si vous posez des questions sur ces concepts de conception, la réponse dépend fortement de ce que vous avez l'intention de faire avec le modèle. Si c'est pour un jeu vidéo chien-manger-chien ou même une application pour suivre les horaires d'alimentation dans un zoo, cela pourrait suffire. S'il s'agit d'un modèle conceptuel pour les modèles de comportement animal, c'est probablement un peu superficiel.
la source
L'héritage doit être utilisé pour quelque chose qui est toujours autre chose et ne peut pas changer. L'herbe n'est pas toujours de la nourriture. Par exemple, je ne mange pas d'herbe.
L'herbe joue le rôle d'un aliment pour certains animaux.
la source
Vous venez de découvrir la limitation de base de l'OO.
OO fonctionne bien avec les structures hiérarchiques. Mais une fois que vous vous éloignez des hiérarchies strictes, l'abstraction ne fonctionne pas si bien.
Je connais tout sur les compositions de métamorphose, etc. qui sont utilisées pour contourner ces limitations, mais elles sont maladroites et, plus important encore, conduisent à du code obscur et difficile à suivre.
Les bases de données relationnelles ont été inventées principalement pour échapper aux limites des structures hiérarchiques strictes.
Pour prendre votre exemple, l'herbe pourrait également être un matériau de construction, une matière première pour le papier, un matériau pour les vêtements, une mauvaise herbe ou une récolte.
Un cerf peut être un animal de compagnie, du bétail, un animal de zoo ou une espèce protégée.
Un lion peut également être un animal de zoo ou une espèce protégée.
La vie n'est pas simple.
la source
Quel problème? Que fait ce système? Jusqu'à ce que vous répondiez à cela, je n'ai aucune idée des cours qui pourraient être requis. Essayez-vous de modéliser une écologie, avec des carnivores et des herbivores et des plantes, projetant des populations d'espèces dans le futur? Essayez-vous de faire jouer 20 questions à l'ordinateur?
C'est une perte de temps de commencer la conception avant de définir des cas d'utilisation. J'ai vu cela pris à des extrêmes ridicules lorsqu'une équipe d'une dizaine a commencé à produire un modèle OO d'une compagnie aérienne en utilisant un logiciel à travers des images. Ils ont travaillé pendant deux ans dans la modélisation sans aucun problème commercial réel. Enfin, le client s'est lassé d'attendre et a demandé à l'équipe de résoudre un problème réel. Toute cette modélisation était complètement inutile.
la source