Will you implement the strategy here and if so, how?

Consider an application that generates production plans (simplified code example below). There is a large list of products, and we call product.GetProductionTime () many times, doing complex calculations in the production plan. We need product.GetProductionTime () to behave differently based on the scheduling algorithm used or the step of the algorithm we are in. The conditionals in GetProductionTime () are ugly and adding another algorithm isn't easy.

I think about strategy. Is this a good place to implement it? If so, how do you implement it? If not, what can I do?

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

      

+2


source to share


3 answers


Basically, you want to rip out that big if / switch statement into GetProductionTime and turn each case into various smaller, sane classes. Each class will be a different strategy that calls CalculationFast or CalculationSlow using different conditions.

For example, if your language supports internal classes (Java) and Plantype, you only need to check the product status to choose between fast and slow:

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

      



Basically, your algorithm can choose which type of Plantype makes sense at a given point and pass it to GetProductionTime.

The internal approach of the class might be completely wrong depending on what the Plantype class needs to check, but you get the image.

+1


source


This can be done using a strategy template. I suggest the following implementation for you: Create an interface in the Product class that will calculate the production time. Then we will implement the ProdTimeCalculationStrategyBase strategy class, which will have a virtual GetProductTime method and inherit from it all other strategy classes. Within each strategy, you can implement your own calculation method.

After that, do a custom factory that will move your switch. This factory will instantiate a strategy computation class based on what product you provide it with.



After that, your code will act like this: when the product asks to calculate the ProductionTime, it will provide all the details of the factory to create a custom strategy for the calculations. factory will return an object that is capable of evaluating it correctly. The result from the strategy will be passed to the product and it will return it to the caller.

0


source


You would like to use the strategy pattern if it removes duplicate code. Where is the duplication you want to remove? If this is a conditional statement, the strategy pattern will only add complexity without eliminating the problem.

0


source







All Articles