具体策略的战略模式 [英] Strategy Pattern with Dummy concrete strategy

查看:154
本文介绍了具体策略的战略模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Refering to posted question here, could you please comment if this is good approach to solve OPTIONAL behaviour for extending class, by using composition, not inheritance. Plannable behaviour is here extended by Strategy pattern.

所以,课程任务可以可选地具有各种行为的任何组合。 可计划只是其中之一,因此继承在这里显然没有意义。

So, class Task could optionally have any combination of various behaviours. Plannable is just one of them, therefore inheritance does obviously not making sense here.

问题是如何做任务没有特殊的行为?我看到几种可能的方法:

Question is what to do when Task does not have particular behaviour ? I see few possible approaches:


  1. 为每个任务实例化具体的策略,并在任务不是可计划(此选项如下所示)。在这种情况下,有奇怪的可空的开始完成变量,<...>

  2. 具有可空值案例任务中的IPlanningStrategy变量将不会被计划,并且仅在升级为可计划

  1. Instantiate concrete strategy for each task, and implement "Dummy" strategy when Task is not Plannable (this alternative is shown below). There are weird nullable Start and Finish variables all over the code, in this case...
  2. Having nullable IPlanningStrategy variable in the case task won't be planned, and instantiate with concrete Strategy only when it is "promoted" to be Plannable.

替代(1)应该是这样的:

Alternative (1) should be something like this:

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

}

现在我看到不同的**非常重要的**这里的问题。我的具体策略类中的每一个都包含算法,当然这对于实现该算法的所有任务来说都是共享的,附加参数仅属于特定的任务

Now I see different ** VERY IMPORTANT** problem here. Each of my concrete Strategy class holds, beside algorithm, which is of course shared for all tasks implementing this algorithm, additional parameters, which belongs only to particular Task.

您可以想象 parameter1 as Effort (或者说,完成任务所需的剩余时间),并说 parameter2 as LastDate (表示约束日期,即最后允许的日期完成任务)。这个参数自然属于特定的 Task ,但只有当它实现了这个特定的 StrategyA

You can imagine parameter1 as Effort (or, say, number of remaining hours required to complete task), and say parameter2 as LastDate (representing constraint date, ie. last allowable date to finish task). This parameters naturally belongs to particular Task, but only if it implements this particular StrategyA.

似乎在 Task 之外的实例化策略没有意义?或者这应该是一些工厂方法的工作?

It seems that instantiate strategy outside Task class does not make sense ? Or this should be job for some Factory method ?

推荐答案

IMO你在任务类中暴露了太多信息。我会做如下:

IMO you are exposing too much information in your Task class. I would do as follows:

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

}

您的客户不知道开始,完成我不会看到作为算法的容器的责任。

Your client shouldnt know start, finish, i dont see that as responsibility of a container for algorithms.

此外,如果您的NoPlanStrategy没有做任何事情,为什么要介绍它。 removeit。

Moreover, if your NoPlanStrategy not doing anything, why introduce it. removeit.

这篇关于具体策略的战略模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆