Ecco uno scenario comune che è sempre frustrante per me affrontare.
Ho un modello a oggetti con un oggetto genitore. Il genitore contiene alcuni oggetti figlio. Qualcosa come questo.
public class Zoo
{
public List<Animal> Animals { get; set; }
public bool IsDirty { get; set; }
}
Ogni oggetto figlio ha vari dati e metodi
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public void MakeMess()
{
...
}
}
Quando il figlio cambia, in questo caso quando viene chiamato il metodo MakeMess, è necessario aggiornare un valore nel genitore. Diciamo che quando una certa soglia di Animal ha fatto un casino, allora deve essere impostata la bandiera IsDirty dello Zoo.
Esistono alcuni modi per gestire questo scenario (di cui sono a conoscenza).
1) Ogni animale può avere un riferimento Zoo genitore per comunicare i cambiamenti.
public class Animal
{
public Zoo Parent { get; set; }
...
public void MakeMess()
{
Parent.OnAnimalMadeMess();
}
}
Questa sembra l'opzione peggiore in quanto accoppia Animal con l'oggetto principale. E se volessi un animale che vive in una casa?
2) Un'altra opzione, se stai usando una lingua che supporta gli eventi (come C #) è quella di abbonarsi al genitore per cambiare gli eventi.
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)
{
...
}
}
Questo sembra funzionare, ma per esperienza diventa difficile da mantenere. Se gli animali cambiano mai Zoo, devi annullare l'iscrizione agli eventi nel vecchio Zoo e iscriverti nuovamente al nuovo Zoo. Questo peggiora solo quando l'albero della composizione diventa più profondo.
3) L'altra opzione è quella di spostare la logica su al genitore.
public class Zoo
{
public void AnimalMakesMess(Animal animal)
{
...
}
}
Questo sembra molto innaturale e causa la duplicazione della logica. Ad esempio, se avessi un oggetto House che non condivide alcun genitore ereditario comune con Zoo ..
public class House
{
// Now I have to duplicate this logic
public void AnimalMakesMess(Animal animal)
{
...
}
}
Non ho ancora trovato una buona strategia per affrontare queste situazioni. Cos'altro è disponibile? Come può essere reso più semplice?