سؤال

تتمثل مهمتك في تصميم مكتبة فئة لخطة المشروع التي تدعم تتبع المهام (على غرار كيفية عمل MS Works). هذه المكتبة الفئة لديها Task كائن (من بين أمور أخرى).

ال Task الكائن لديه أ EstimatedHours (Double), StartDate (DateTime)، و EndDate (DateTime) الخصائص، من بين أمور أخرى. أ Task يمكن أن يكون الكائن أحد الوالدين Task, والعديد من الأطفال Task أشياء. ال EstimatedHours, StartDate, ، و EndDate خصائص أ Task الذي لديه أطفال (هو أحد الوالدين) يعتمد على خصائص أطفاله المباشرين. الاباء TaskStartDate هو الأقدم StartDate من أطفالها. الاباء TaskEndDate هو الأحدث EndDate من أطفالها. الاباء TaskEstimatedHours هو مجموع أطفالها 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 جيدا.

تفاعل وحدات التحكم مع الأحداث. انهم يشرفون. يسمون الأساليب النموذجية.
النماذج تفعل العمل.

انها ليست موازية مثالية.
صحيح، من التبسيط، لكنها تجعل المبادئ التوجيهية جيدة جدا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top