参考此处发布的问题,如果这是通过使用组合而不是继承来解决扩展类的可选行为的好方法,请您发表评论。Plannable
行为在这里由策略模式扩展。
因此,类Task
可以选择具有各种行为的任意组合。Plannable
只是其中之一,因此继承在这里显然没有意义。
问题是当 Task 没有特定行为时该怎么办?我看到几种可能的方法:
- 为每个任务实例化具体的策略,并在
Task
不是时实施“虚拟”策略Plannable
(此替代方案如下所示)。在这种情况下,整个代码中都有奇怪的可为空Start
和Finish
变量... - 在案例任务中拥有
nullable
IPlanningStrategy 变量将不会被计划,并且仅当它被“提升”为时才使用具体的 Strategy 实例化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
方法的工作?