Voici un scénario courant qui est toujours frustrant pour moi.
J'ai un modèle d'objet avec un objet parent. Le parent contient des objets enfants. Quelque chose comme ça.
public class Zoo
{
public List<Animal> Animals { get; set; }
public bool IsDirty { get; set; }
}
Chaque objet enfant a différentes données et méthodes
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public void MakeMess()
{
...
}
}
Lorsque l'enfant change, dans ce cas lorsque la méthode MakeMess est appelée, une valeur dans le parent doit être mise à jour. Disons que lorsqu'un certain seuil d'Animal a gâché, le drapeau IsDirty du zoo doit être défini.
Il existe plusieurs façons de gérer ce scénario (à ma connaissance).
1) Chaque animal peut avoir une référence de zoo parent pour communiquer les changements.
public class Animal
{
public Zoo Parent { get; set; }
...
public void MakeMess()
{
Parent.OnAnimalMadeMess();
}
}
Cela semble être la pire option car il couple Animal à son objet parent. Et si je veux un animal qui vit dans une maison?
2) Une autre option, si vous utilisez un langage qui prend en charge les événements (comme C #) est de demander au parent de s'abonner pour modifier les événements.
public class Animal
{
public event OnMakeMessDelegate OnMakeMess;
public void MakeMess()
{
OnMakeMess();
}
}
public class Zoo
{
...
public void SubscribeToChanges()
{
foreach (var animal in Animals)
{
animal.OnMakeMess += new OnMakeMessDelegate(OnMakeMessHandler);
}
}
public void OnMakeMessHandler(object sender, EventArgs e)
{
...
}
}
Cela semble fonctionner, mais l'expérience devient difficile à maintenir. Si jamais les animaux changent de zoo, vous devez vous désabonner des événements de l'ancien zoo et vous réinscrire au nouveau zoo. Cela ne fait qu'empirer à mesure que l'arbre de composition s'approfondit.
3) L'autre option consiste à déplacer la logique vers le parent.
public class Zoo
{
public void AnimalMakesMess(Animal animal)
{
...
}
}
Cela semble très peu naturel et provoque une duplication de la logique. Par exemple, si j'avais un objet House qui ne partage aucun parent d'héritage commun avec Zoo ..
public class House
{
// Now I have to duplicate this logic
public void AnimalMakesMess(Animal animal)
{
...
}
}
Je n'ai pas encore trouvé de bonne stratégie pour faire face à ces situations. Quoi d'autre est disponible? Comment simplifier cela?