你会在这里实施一个战略模式,如果是,怎么做?

时间:2009-09-03 02:24:37

标签: design-patterns oop

考虑生成生产计划的应用程序(下面简化的代码示例)。有一个很大的产品列表,我们在生产计划中进行复杂计算时多次调用product.GetProductionTime()。我们需要product.GetProductionTime()根据我们正在使用的规划算法或我们所处的算法步骤来表现不同.GetProductionTime()中的条件很难看,添加另一个算法并不容易。

我在考虑策略模式。这是一个实施它的好地方吗?如果是的话,你会如何实现它?如果不是,我该怎么办?

public class ProductionPlanningProblem
{
    public List<Product> Products;
    public void GenerateFastProdPlan()
    {
        foreach (Product product in Products)
        {
            //do lots of calculations 
            product.GetProductionTime(PlanType.Fast);
            //do lots of calculations 
        }
    }
    public void GenerateSlowProdPlan()
    {
        foreach (Product product in Products)
        {
            //do lots of calculations 
            product.GetProductionTime(PlanType.Slow);
            //do lots of calculations 
        }
    }
}
public class Product
{
    public int GetProductionTime(Plantype plantype)
    {
        if(plantype.Fast)
            return CalculationFast();
        if (plantype.Slow && SomeOtherConditionsHold)
            return CalculationSlow();
        return CalculationFast();
    }

    private int CalculationFast()
    {
        //do fast calculation depending on many fields of product
        return result;
    }
    private int CalculationSlow()
    {
        //do slow but more accurate calculations depending on many fields of product            
        return result;
    }
}

3 个答案:

答案 0 :(得分:1)

基本上,你想要在GetProductionTime中删除那个大的if / switch语句,并将每个case转换成各种较小的,合理的类。每个类都是一个不同的策略,使用不同的条件调用CalculationFast或CalculationSlow。

例如,如果您的语言支持内部类(Java)和Plantype,则只需要检查产品的状态,以便在快速和快速之间做出决定。慢:

public interface Plantype
{
    public int Calc();
}

public class Product
{
    public class Plantype_one implements Plantype
    {
        public int Calc()
        {
            if (<some simple condition holds for Product instance>) {
                 return CalculationFast();
            } else {
                 return CalculationSlow();
            }
        }
    }
    public class Plantype_two implements Plantype
    {
        public int Calc()
        {
            if (< some different & simple condition holds for Product instance >) {
                 return CalculationFast();
            } else {
                 return CalculationSlow();
            }
        }
    }

    // etc.

    public int GetProductionTime(Plantype plantype)
    {
        return plantype.Calc();
    }

    private int CalculationFast()
    {
        //do fast calculation depending on many fields of product
        return result;
    }
    private int CalculationSlow()
    {
        //do slow but more accurate calculations depending on many fields of product            
        return result;
    }
}

基本上,您的算法可以选择哪种Plantype在给定点有意义并将其传递给GetProductionTime。

内部类方法可能完全错误,取决于Plantype类需要检查的内容,但是你得到了图片。

答案 1 :(得分:0)

可以使用策略模式来实现。我建议您使用以下实现: 在Product类中创建一个接口,用于计算生产时间。 然后实现一个策略类ProdTimeCalculationStrategyBase,它将具有虚拟GetProductTime方法并从中继承所有其他策略类。在每个策略中,您都可以实现自己的计算方法。

之后实施一个特殊的工厂,你的开关将移动。该工厂将根据您将为其提供的产品创建策略计算类的实例。

之后,您的代码将如下所示:当产品被要求计算ProductionTime时,它将向工厂提供所有细节以创建特殊的计算策略。 Factory将返回能够以正确方式计算它的对象。策略返回的结果将提供给产品,并将其返回给调用者。

答案 2 :(得分:0)

如果它删除了代码重复,您只想使用策略模式。您要删除的重复位置在哪里?如果是条件语句,策略模式只会增加复杂性而不解决问题。