.NET كائن هرمي - إلى الحدث أو عدم الحدث
-
09-09-2019 - |
سؤال
تتمثل مهمتك في تصميم مكتبة فئة لخطة المشروع التي تدعم تتبع المهام (على غرار كيفية عمل MS Works). هذه المكتبة الفئة لديها Task
كائن (من بين أمور أخرى).
ال Task
الكائن لديه أ EstimatedHours
(Double
), StartDate
(DateTime
)، و EndDate
(DateTime
) الخصائص، من بين أمور أخرى. أ Task
يمكن أن يكون الكائن أحد الوالدين Task
, والعديد من الأطفال Task
أشياء. ال EstimatedHours
, StartDate
, ، و EndDate
خصائص أ Task
الذي لديه أطفال (هو أحد الوالدين) يعتمد على خصائص أطفاله المباشرين. الاباء Task
'س StartDate
هو الأقدم StartDate
من أطفالها. الاباء Task
'س EndDate
هو الأحدث EndDate
من أطفالها. الاباء Task
'س EstimatedHours
هو مجموع أطفالها EstimatedHours
. وبعد لذلك، فمن غير صالح لتغيير هذه الخصائص على Task
التي لديها أطفال.
كيف يمكنك معالجة حالة الاستخدام حيث يتم تغيير التجميل أو Startdate أو Enddate في مهمة لها أحد الوالدين؟ (خصائص الوالدين هي انعكاس لأطفالها، لذلك قد يتطلب أي تغييرات على الأطفال خصائص الوالدين لتعكس التغييرات بشكل مناسب)
أحد الخيارات هو الحصول على حدث عندما يتغير كل خاصية. الوالد Task
سوف تستمع لهذه الأحداث على أطفالها المباشرين Task
الكائنات، وإجراء التغييرات المناسبة على خصائصها الخاصة عندما حدثت هذه الأحداث. هل هذا نهج جيد، أم أن هناك طريقة أفضل؟ كيف تريد أنت افعلها؟
إليك فكرة أساسية عن ما Task
قد يبدو الكائن:
Public Class Task
Private mChildren As List(Of Task)
Private mEndDate As DateTime = DateTime.MinVlue
Public Property EndDate() As DateTime
Get
Return mEndDate
End Get
Set(ByVal value As DateTime)
mEndDate = value
'What to do here?
End Set
End Property
Private mEstimatedHours As Double = 0.0
Public Property EstimatedHours() As Double
Get
Return mEstimatedHours
End Get
Set(ByVal value As Double)
mEstimatedHours = value
'What to do here?
End Set
End Property
Private mStartDate As DateTime = DateTime.MinVlue
Public Property StartDate() As DateTime
Get
Return mStartDate
End Get
Set(ByVal value As DateTime)
mStartDate = value
'What to do here?
End Set
End Property
End Class
المحلول
سيكون النهج الصحيح لحل هذه المشكلة هو استخدام نمط تصميم المراقب. توضيح مفصل لتنفيذ نمط المراقب هو خارج نطاق هذه المناقشة. ولكن هنا بعض الروابط الرائعة لنمط المراقب. رابط واحد هو هنا وآخر هو هنا.
http://www.dofactory.com/patterns/patternobserver.aspx.
http://en.wikipedia.org/wiki/observer_pattern.
أتمنى أن يساعدك هذا.
روتشيت س
نصائح أخرى
لست متأكدا من أن هذه هي الطريقة التي كنت أقوم بها بالفعل، ولكن هنا خيار مختلف: بدلا من السماح بمهمة أن يكون لديك أطفال، استخدم كائنين ومهمة ومهمة وثيقة تنفذ واجهة ITASK. ستحصل المهمة على بدء التشغيل الخاص بها، والإنجاز، ويقدرها، ولكن ستعمل مهمة سهم ديناميكيا تلك القيم من مهامها الطفل. استخدم خدمة لإضافة وإزالة الأطفال إلى ITAKE. للإضافة، ستحول مهمة إلى مهمة عند إضافة الطفل الأول. لإزالة، فإنه سيؤدي إلى تحويل المهام مرة أخرى إلى مهمة عند إزالته بعد ذلك، ثم تتم إزالة الطفل الأخير وتعيين الخصائص من القيم في الطفل الأخير.
ضع في اعتبارك أنه عندما يلقي حدث واحد في سلسلة الأحداث استثناء، لن يتم استدعاء الأحداث التالية. لذلك إذا كانت هناك أحداث أخرى مسجلة للبيانات مايو يكون من الممكن عدم استدعاء الحدث الخاص بك.
إذا كان الأمر بالغ الأهمية للتطبيق الخاص بك أن المهمة الأساسية ليست أبدا خارجا مع أطفالها، فلا تستخدم الأحداث.
أود أولا إنشاء نموذج الكائن بحيث يحسب على ذبابة القيم. سأقدم لك C # كما أنا الأكثر مرونة معها (أنا أيضا استخدام الحقول بدلا من الخصائص للحفاظ على العينة الصغيرة):
public class Task
{
public List<Task> Children=new List<Task>();
public Task Parent;
private int _duration;
public int Duration
{
get
{
if (Children.Count>0)
{
return SumChildrenDuration();
}
return _duration;
}
set
{
if (children.Count>0)
throw new Exception("Can only add to leaves");
_duration=value;
}
}
}
بمجرد أن يكون لديك هذا في مكانك الآن لديك كل الكود الذي تحتاجه لتشغيل نظامك. قد تجد أن النظام ينفذ جيدا بما فيه الكفاية واتركه مثل هذا. وإلا يمكنك إضافة وظيفة إضافية إلى ذاكرة التخزين المؤقت للنتيجة ثم إعادة تعيين ذاكرة التخزين المؤقت عند تغيير كائن. مهما كنت متأكدا من ملف التعريف الخاص بك عن كثب كما تريد التأكد من أن التخزين المؤقت الخاص بك والانتعاش غير ثمنه أكثر تكلفة، فحسب فقط على الطاير.
لن أعتبر هذا جزءا من مسؤولية النموذج، بل من وحدة تحكم أعلى منه.
يضيف إضافة أحداث أو أنماط المراقب إلى نموذج تعقيدا في مجالات أخرى، مثل التسلسل، الذي تريد تجنبه.
اجعلها مسؤولية الفصل الذي يجعل التعديل وليس النموذج نفسه. تذكر: مسؤولية النموذج هي أن تحتوي على المعلومات، لا تنطوي على قواعد العمل.
أقول مطوري ASP.NET الخاص بي، "الأحداث تشرف. طرق القيام بالعمل".
يجب أن تكون الأحداث أكثر بقليل من طرق الاتصال ifblocks. لا محاولة / المصيد الخ
الأساليب هل جميع الوصول إلى البيانات / التلاعب / التحقق من الصحة / الحساب الخ
هذا يخلق عقول "كود قابلة لإعادة الاستخدام" في مطوري بلدي أيضا.
إنه يحتفظ بالأشياء المنفصلة.
كما أنه يوازي مفاهيم MVC جيدا.
تفاعل وحدات التحكم مع الأحداث. انهم يشرفون. يسمون الأساليب النموذجية.
النماذج تفعل العمل.
انها ليست موازية مثالية.
صحيح، من التبسيط، لكنها تجعل المبادئ التوجيهية جيدة جدا.