您的工作是设计一个项目计划类库,它支持跟踪任务(类似于MS Project的工作方式)。该类库具有Task
对象(以及其他对象)。
Task
对象有EstimatedHours
(Double
),StartDate
(DateTime
)和EndDate
(DateTime
)属性等。 Task
对象可以有一个父Task
和几个子Task
个对象。 EstimatedHours
具有子项(是父项)的StartDate
,EndDate
和Task
属性取决于其直接子项的属性。父Task
的{{1}}是其子女中最早的StartDate
。父StartDate
的{{1}}是其子女的最新Task
。父EndDate
的{{1}}是其子EndDate
的总和。因此,在具有子项的Task
上更改这些属性无效。
您如何处理在具有父级的任务上更改EstimatedHours,StartDate或EndDate的用例?(父级的属性是其子级的反映,因此对儿童可能需要调整父母的财产以适当地反映这些变化。
一个选项是为每个属性更改时设置一个事件。父EstimatedHours
将在其直接子EstimatedHours
个对象上侦听这些事件,并在发生这些事件时对其自己的属性进行适当的更改。这是一个好方法,还是有更好的方法? 你怎么做?
以下是Task
对象的基本概念:
Task
答案 0 :(得分:4)
解决此问题的正确方法是使用Observer Design Pattern。实施观察者模式的详细解释超出了本讨论的范围。但是这里有一些观察者模式的好链接。一个链接为here,另一个链接为here。
http://www.dofactory.com/Patterns/PatternObserver.aspx
http://en.wikipedia.org/wiki/Observer_pattern
希望这有帮助。
Ruchit S。
答案 1 :(得分:2)
我不确定这是我实际上是怎么做的,但是这里有一个不同的选择:使用两个对象,一个Task和一个实现ITask接口的TaskSet,而不是让一个Task有子。任务将拥有自己的StartDate,EndDate和EstimatedHours,但TaskSet将从其子任务动态计算这些值。使用服务向ITask添加和删除子项。对于添加,它会在添加第一个子节点时将Task转换为TaskSet。对于删除,它会将TaskSet转换回Task,然后移除最后一个子节点并从最后一个子节点的值设置属性。
答案 2 :(得分:1)
我不认为这是模型责任的一部分,而是在控制器之上。
向模型添加事件或观察者模式会增加其他方面的复杂性,例如序列化,这是您要避免的。
让它成为进行修改的类的责任,而不是模型本身。请记住:模型的责任是包含信息,而不是暗示业务规则。
答案 3 :(得分:1)
请记住,当事件链中的一个事件抛出异常时,不会调用以下事件。因此,如果在数据中注册了其他事件,可能可能无法调用您的事件。
如果对您的应用程序而言基本任务永远不会与其子项脱节,那么请不要使用事件。
答案 4 :(得分:1)
我首先构建对象模型,以便它即时计算值。我打算给你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;
}
}
}
完成此操作后,您现在拥有运行系统所需的所有代码。您可能会发现系统运行良好并且保持这样。否则,您可以添加其他功能来缓存结果,然后在对象更改时重置缓存。无论你做什么,一定要仔细描述它,因为你想要确保你的缓存和到期并不昂贵,只需动态计算。
答案 5 :(得分:0)
我告诉我的ASP.NET开发人员,“事件监督。方法完成工作。”
事件应该比IFblocks调用方法多一点。没有尝试/捕获等
方法执行所有数据访问/操作/验证/计算等
这也为我的开发人员创造了“可重用代码”的思维模式。
它使事物分开。
它也很好地与MVC概念相媲美。
控制器对事件做出反应。他们监督。他们称之为模型方法 模型可以完成工作。
这不是一个完美的平行 没错,它很简单,但却有很好的指导。