参考发布的问题here,请您评论一下,如果这是一个很好的方法来解决扩展类的可选行为,那么使用组合而不是继承。 Plannable
行为在这里由策略模式扩展。具有虚拟混淆策略的策略模式
因此,类Task
可以可选地具有各种行为的任意组合。 Plannable
只是其中之一,因此继承在这里显然没有意义。
问题是当Task没有特别的行为时该怎么做?我看到一些可能的方法:
- 实例化每项任务的具体策略,而当
Task
不是Plannable
实现“虚拟”的策略(本项选择如下图所示)。还有奇怪的可空Start
和Finish
变量遍布代码,在这种情况下... - 有
nullable
IPlanningStrategy变量的情况下的任务,不能有计划,只有当它被“提升”战略的具体实例是Plannable
。
替代(1)应该是这样的:
public class Task
{
public string Title { get; set; }
private IPlanningStrategy planningStrategy;
public Task()
{
planningStrategy = new NoPlanStrategy();
}
public Task(IPlanningStrategy initialPlanningStrategy)
{
planningStrategy = initialPlanningStrategy;
}
public void SetPlanningStrategy(IPlanningStrategy newPlanningStrategy)
{
planningStrategy = newPlanningStrategy;
}
public DateTime? Start { get { return planningStrategy.Start; } }
public DateTime? Finish { get { return planningStrategy.Finish; } }
}
public interface IPlanningStrategy
{
public void CalculatePlan();
public DateTime? Start { get; }
public DateTime? Finish { get; }
}
// "Dummy" strategy, used when Task does not have Planning behaviour
//
public class NoPlanStrategy : IPlanningStrategy
{
public void CalculatePlan() { }
public DateTime? Start { get { return null; } }
public DateTime? Finish { get { return null; } }
}
public class PlanStrategyA : IPlanningStrategy
{
private int parameter1;
private int parameter2;
private DateTime? start;
private DateTime? finish;
public PlanStrategyA(int p1, int p2)
{
parameter1 = p1;
parameter2 = p2;
start = finish = null;
}
public void CalculatePlan()
{
// ... uses parameter1 & parameter2
// ... to calculate start and finish
}
public DateTime? Start { get { return start; } }
public DateTime? Finish { get { return finish; } }
}
public class PlanStrategyB : IPlanningStrategy
{
public int parameter3;
// ... the rest is similar to PlanningStrategyA
}
现在我看到不同的**非常重要的**问题就在这里。除了算法外,我的每一个具体的Strategy类都保留着,这当然是所有实现此算法的任务共享的附加参数,它们只属于特定的Task
。
你能想象parameter1
为Effort
(或者说,以完成任务所需要的剩余小时数),并说parameter2
为LastDate
(相当于限制日期,即最后允许的日期完成的任务)。这个参数自然属于特定的Task
,但只有当它实现这个特定的StrategyA
。
看来,实例化外部Task
类策略没有意义吗?或者这应该是一些Factory
方法的工作?
感谢您的回答。如果可以具有可空的'Task.planninStrategy',那么当然,我不需要“dummy”'NoStrategy'类,并且可以被删除。关于第二点,我的客户对'开始'和'完成'非常感兴趣,因为如果Task是Plannable,整个Planning的行为就是向他们展示Start和Finish。但是,'Start'和'Finish'可以用与'Task.CalculatePlan()'类似的方式表示,即。检查null并返回'开始/完成'如果不为空? – buggy08
是的,你可以做到这一点,如果你需要返回开始/完成把它们放在一个对象中,更改你的界面,以返回你的客户期望满足此合同的任何信息。相应地处理异常。 – DarthVader
这里有更多的问题:-)我刚刚扩展问题... – buggy08