Hier ist ein häufiges Szenario, das für mich immer frustrierend ist.
Ich habe ein Objektmodell mit einem übergeordneten Objekt. Das übergeordnete Objekt enthält einige untergeordnete Objekte. Etwas wie das.
public class Zoo
{
public List<Animal> Animals { get; set; }
public bool IsDirty { get; set; }
}
Jedes untergeordnete Objekt verfügt über verschiedene Daten und Methoden
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public void MakeMess()
{
...
}
}
Wenn sich das untergeordnete Element ändert, muss in diesem Fall beim Aufrufen der MakeMess-Methode ein Wert im übergeordneten Element aktualisiert werden. Sagen wir, wenn eine bestimmte Schwelle von Animal's ein Chaos verursacht hat, muss das IsDirty-Flag des Zoos gesetzt werden.
Es gibt einige Möglichkeiten, mit diesem Szenario umzugehen (von denen ich weiß).
1) Jedes Tier kann eine übergeordnete Zoo-Referenz haben, um Änderungen mitzuteilen.
public class Animal
{
public Zoo Parent { get; set; }
...
public void MakeMess()
{
Parent.OnAnimalMadeMess();
}
}
Dies scheint die schlechteste Option zu sein, da Animal an das übergeordnete Objekt gekoppelt wird. Was ist, wenn ich ein Tier will, das in einem Haus lebt?
2) Wenn Sie eine Sprache verwenden, die Ereignisse unterstützt (z. B. C #), können Sie auch festlegen, dass das übergeordnete Element Ereignisse ändert.
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)
{
...
}
}
Dies scheint zu funktionieren, ist aber aus Erfahrung schwer zu pflegen. Wenn Tiere den Zoo wechseln, müssen Sie die Termine im alten Zoo abbestellen und sich erneut im neuen Zoo anmelden. Dies wird nur schlimmer, wenn der Kompositionsbaum tiefer wird.
3) Die andere Möglichkeit besteht darin, die Logik auf das übergeordnete Element zu verschieben.
public class Zoo
{
public void AnimalMakesMess(Animal animal)
{
...
}
}
Dies erscheint sehr unnatürlich und führt zu einer Verdoppelung der Logik. Wenn ich zum Beispiel ein House-Objekt hätte, das kein gemeinsames übergeordnetes Vererbungselement mit Zoo teilt.
public class House
{
// Now I have to duplicate this logic
public void AnimalMakesMess(Animal animal)
{
...
}
}
Ich habe noch keine gute Strategie gefunden, um mit diesen Situationen umzugehen. Was gibt es noch? Wie kann das einfacher gemacht werden?