นี่เป็นสถานการณ์ทั่วไปที่ทำให้ฉันต้องจัดการ
ฉันมีโมเดลวัตถุที่มีวัตถุแม่ พาเรนต์มีวัตถุย่อยบางอย่าง บางสิ่งเช่นนี้
public class Zoo
{
public List<Animal> Animals { get; set; }
public bool IsDirty { get; set; }
}
แต่ละวัตถุลูกมีข้อมูลและวิธีการต่าง ๆ
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public void MakeMess()
{
...
}
}
เมื่อลูกเปลี่ยนแปลงในกรณีนี้เมื่อเรียกเมธอด MakeMess ค่าบางอย่างในพาเรนต์จะต้องได้รับการอัปเดต สมมติว่าเมื่อขีด จำกัด ของ Animal ได้สร้างความยุ่งเหยิงดังนั้นธง IsDirty ของ Zoo จึงจำเป็นต้องตั้งค่า
มีสองสามวิธีในการจัดการสถานการณ์นี้ (ที่ฉันรู้)
1)สัตว์แต่ละตัวสามารถมีการอ้างอิงของ Zoo หลักเพื่อสื่อสารการเปลี่ยนแปลง
public class Animal
{
public Zoo Parent { get; set; }
...
public void MakeMess()
{
Parent.OnAnimalMadeMess();
}
}
สิ่งนี้ให้ความรู้สึกว่าเป็นตัวเลือกที่เลวร้ายที่สุดเพราะมันจับคู่สัตว์กับวัตถุหลัก ถ้าฉันต้องการสัตว์ที่อาศัยอยู่ในบ้านล่ะ
2)ตัวเลือกอื่นหากคุณใช้ภาษาที่สนับสนุนกิจกรรม (เช่น C #) คือให้ผู้ปกครองสมัครสมาชิกเพื่อเปลี่ยนกิจกรรม
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)
{
...
}
}
ดูเหมือนว่าจะทำงานได้ แต่จากประสบการณ์ยากที่จะรักษา หากสัตว์มีการเปลี่ยนแปลงของสวนสัตว์คุณต้องยกเลิกการเป็นสมาชิกที่สวนสัตว์เก่าและสมัครใหม่ที่สวนสัตว์ใหม่ สิ่งนี้จะยิ่งแย่ลงเมื่อทรีองค์ประกอบมีความลึกมากขึ้น
3)ตัวเลือกอื่นคือการย้ายลอจิกถึงแม่
public class Zoo
{
public void AnimalMakesMess(Animal animal)
{
...
}
}
ดูเหมือนว่าผิดธรรมชาติมากและทำให้เกิดความซ้ำซ้อนของตรรกะ ตัวอย่างเช่นถ้าฉันมีวัตถุเฮ้าส์ที่ไม่ได้แชร์มรดกทั่วไปกับ Zoo ..
public class House
{
// Now I have to duplicate this logic
public void AnimalMakesMess(Animal animal)
{
...
}
}
ฉันยังไม่พบกลยุทธ์ที่ดีในการรับมือกับสถานการณ์เหล่านี้ มีอะไรอีกบ้าง? สิ่งนี้จะทำให้ง่ายขึ้นได้อย่างไร