2009-04-14 2 views
4

Ваша задача - создать библиотеку классов Project Plan, которая поддерживает отслеживание задач (подобно тому, как работает MS Project). Эта библиотека классов имеет объект Task (среди прочих).Иерархия объектов .NET - к событию или не к событию

Объект Task имеет EstimatedHours (Double), StartDate (DateTime) и EndDate (DateTime) свойства, среди других. A Task объект может иметь одного родителя Task и нескольких детей Task объектов. EstimatedHours, StartDate и EndDate свойства Task, которые имеют дочерние элементы (родительский), зависят от свойств его непосредственных детей. Родитель TaskStartDate - самые ранние женщины StartDate. Родитель TaskEndDate является последним EndDate его детей. Родитель TaskEstimatedHours является суммой его детей EstimatedHours. Поэтому недействительно изменять эти свойства на Task, у которого есть дети.

Как бы вы обрабатывали прецедент, когда значения EstimatedHours, 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 

ответ

4

Правильный подход к решению этой проблемы будет использовать Design Observer Pattern. Подробное объяснение реализации схемы Observer выходит за рамки этой дискуссии. Но вот несколько отличных ссылок для Pattern Observer. Одна ссылка - here, а другая - here.

http://www.dofactory.com/Patterns/PatternObserver.aspx

http://en.wikipedia.org/wiki/Observer_pattern

Надеется, что это помогает.

Ruchit С.

1

Я не считаю, что это часть ответственности модели, а Контролера поверх него.

Добавление событий или шаблонов наблюдателей к модели добавляет сложности в других областях, таких как сериализация, которых вы хотите избежать.

Обязанности класса, который производит модификацию, а не сама модель. Помните: ответственность модели заключается в том, чтобы содержать информацию, а не подразумевать бизнес-правила.

1

Помните, что когда одно событие в цепочке событий генерирует исключение, следующие события не будут вызываться.Так что, если есть другие события, зарегистрированные в данных, это может быть может быть Ваше событие не будет вызываться.

Если для вашего приложения важно, чтобы базовая задача никогда не касалась его детей, не используйте события.

1

Я бы сначала построил объектную модель, чтобы она рассчитывала на лету значения. Я собираюсь дать вам C#, как я больше comftorble с ним (я также с использованием полей вместо свойств, чтобы сохранить образец маленький):

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; 
     } 
    } 
} 

После того как вы это в месте, теперь у вас есть весь код, необходимо запустить вашу систему. Вы можете обнаружить, что система работает достаточно хорошо и оставляет ее так. В противном случае вы можете добавить дополнительные функции для кэширования результата, а затем сбросить кеш при изменении объекта. Независимо от того, что вы делаете, обязательно проконсультируйтесь с ним внимательно, так как вы хотите, чтобы ваше кэширование и срок действия не были более дорогими, а просто вычислялись «на лету».

2

Я не уверен, что это так, как я на самом деле делаю это, но вот другой вариант: вместо того, чтобы позволить задаче иметь детей, используйте два объекта - Task и TaskSet, которые реализуют интерфейс ITask. Задача будет иметь собственные значения StartDate, EndDate и EstimatedHours, но TaskSet будет динамически вычислять эти значения из своих дочерних задач. Используйте службу для добавления и удаления детей в ITask. Для добавления он преобразует задачу в TaskSet при добавлении первого дочернего элемента. Для удаления он преобразует TaskSet обратно в задачу, когда последний удаляется и устанавливает свойства из значений для последнего дочернего элемента.

0

Сообщаю моим разработчикам ASP.NET: «Контроль событий. Методы выполняют работу».

События должны быть немного больше, чем методы вызова IFblocks. Нет попыток/уловов и т. Д.
Методы делают все доступ к данным/манипулирование/валидацию/расчет и т. Д.
Это также создает умы для мышления «многоразового кода».

Это держит вещи раздельными.
Он также отлично сочетается с концепциями MVC.

Контроллеры реагируют на события. Они контролируют. Они называют методы Модели.
Модели выполняют свою работу.

Это не идеальная параллель.
Правда, это упрощенно, но это делает очень хорошие рекомендации.

Смежные вопросы