1

参考此处发布的问题,如果这是通过使用组合而不是继承来解决扩展类的可选行为的好方法,请您发表评论。Plannable行为在这里由策略模式扩展。

因此,类Task可以选择具有各种行为的任意组合。Plannable只是其中之一,因此继承在这里显然没有意义。

问题是当 Task 没有特定行为时该怎么办?我看到几种可能的方法:

  1. 为每个任务实例化具体的策略,并在Task不是时实施“虚拟”策略Plannable(此替代方案如下所示)。在这种情况下,整个代码中都有奇怪的可为空StartFinish变量...
  2. 在案例任务中拥有nullableIPlanningStrategy 变量将不会被计划,并且仅当它被“提升”为时才使用具体的 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的 .

您可以想象parameter1Effort(或者说,完成任务所需的剩余小时数),并说parameter2LastDate(表示约束日期,即完成任务的最后允许日期)。这个参数自然属于特定Task的,但前提是它实现了这个特定StrategyA的。

似乎在Task课外实例化策略没有意义?或者这应该是某种Factory方法的工作?

4

1 回答 1

0

TaskIMO,您在课堂上暴露了太多信息。我会这样做:

public class Task
{
    // what is title being used for?
    public string Title { get; set; }

    private IPlanningStrategy planningStrategy;

    public Task(IPlanningStrategy initialPlanningStrategy)
    {
        // Initialize it outside of constructor
        if(initialPlanningStrategy == null)
        {  
           throw new NullArgumentException(); // or return. 
        }
        planningStrategy = initialPlanningStrategy;
    }

    public void CalculatePlan(){
        // check null and return.
        planningStrategy.CalculatePlan();
    }

}

您的客户不应该知道开始,结束,我不认为这是算法容器的责任。

此外,如果您的 NoPlanStrategy 没有做任何事情,为什么要引入它。去掉它。

于 2012-11-22T00:37:45.743 回答