代码之家  ›  专栏  ›  技术社区  ›  derdo

你会在这里实施一种战略模式吗?如果是,如何实施?

  •  2
  • derdo  · 技术社区  · 15 年前

    考虑一个生成生产计划的应用程序(下面的简化代码示例)。有一个很大的产品列表,我们在生产计划中进行复杂计算时多次调用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 回复  |  直到 15 年前
        1
  •  1
  •   hythlodayr    15 年前

    基本上,您希望在getProductionTime中去掉那个大的if/switch语句,并将每种情况转换为各种更小、更合理的类。每个类都是不同的策略,使用不同的条件调用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类需要检查什么,但是您得到了图片。

        2
  •  0
  •   akf    15 年前

    这是有可能做到的战略模式。我建议您执行以下操作: 在Product类中创建一个接口来计算生产时间。 然后实现一个策略类ProdTimeCalculationStrategyBase,它将具有虚拟的GetProductTime方法并从中继承所有其他策略类。在每种策略中,你都可以实现它自己的计算方法。

    在那之后实施一个特殊的工厂,在那里你的开关将移动。这个工厂将根据你提供给它的产品创建一个策略计算类的实例。

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

        3
  •  0
  •   Steve Kerr    13 年前

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