Apply discount changes with Strategy pattern

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
3
down vote

favorite
1












I am implementing strategy pattern. I have defined a strategy as interfaces and concrete classes to implement the strategy. Based on user selection/configuration, the algorithm to apply the discount changes.



 public interface IStrategy

double calculate(double x, double y);



concrete classes implementing the gold strategy is listed below -



public class clsGoldDiscountStrategy : IStrategy

public double calculate(double x, double y)

return (x * y) * 0.8;


}


concrete classes implementing the platinumstrategy is listed below -



public class clsPlatinumDiscountStrategy : IStrategy

public double calculate(double x, double y)

return (x * y) * 0.7;




The business logic to apply



public class clsBL

public double costPrice get; set;
public double qty get; set;
IStrategy _strategy;

public clsBL(IStrategy strategy)

_strategy = strategy;


public double GetfinalPrice(double cp, double qty)

return _strategy.calculate(cp, qty);





//Main method



static void Main(string args)

Console.WriteLine("Enter the discount Plan (Gold/Platinum)");
string filter = Console.ReadLine().ToUpper();
double result = 0;

if (filter.Length > 0)

switch (filter)

case "GOLD":
//Gold
clsBL blgold = new clsBL(new clsGoldDiscountStrategy());
blgold.costPrice = 5;
blgold.qty = 10;

result = blgold.GetfinalPrice(blgold.costPrice, blgold.qty);
break;

case "PLATINUM":
//Platinum
clsBL blplatinum = new clsBL(new clsPlatinumDiscountStrategy());
blplatinum.costPrice = 10;
blplatinum.qty = 8;

result = blplatinum.GetfinalPrice(blplatinum.costPrice, blplatinum.qty);
break;
default:
Console.WriteLine("Enter the discount value as either gold or platinum");
break;


Console.WriteLine("The result for " + filter + " is " + result);


else

Console.WriteLine("Enter the discount value");
return;



Console.ReadLine();











share|improve this question















migrated from stackoverflow.com 3 hours ago


This question came from our site for professional and enthusiast programmers.


















    up vote
    3
    down vote

    favorite
    1












    I am implementing strategy pattern. I have defined a strategy as interfaces and concrete classes to implement the strategy. Based on user selection/configuration, the algorithm to apply the discount changes.



     public interface IStrategy

    double calculate(double x, double y);



    concrete classes implementing the gold strategy is listed below -



    public class clsGoldDiscountStrategy : IStrategy

    public double calculate(double x, double y)

    return (x * y) * 0.8;


    }


    concrete classes implementing the platinumstrategy is listed below -



    public class clsPlatinumDiscountStrategy : IStrategy

    public double calculate(double x, double y)

    return (x * y) * 0.7;




    The business logic to apply



    public class clsBL

    public double costPrice get; set;
    public double qty get; set;
    IStrategy _strategy;

    public clsBL(IStrategy strategy)

    _strategy = strategy;


    public double GetfinalPrice(double cp, double qty)

    return _strategy.calculate(cp, qty);





    //Main method



    static void Main(string args)

    Console.WriteLine("Enter the discount Plan (Gold/Platinum)");
    string filter = Console.ReadLine().ToUpper();
    double result = 0;

    if (filter.Length > 0)

    switch (filter)

    case "GOLD":
    //Gold
    clsBL blgold = new clsBL(new clsGoldDiscountStrategy());
    blgold.costPrice = 5;
    blgold.qty = 10;

    result = blgold.GetfinalPrice(blgold.costPrice, blgold.qty);
    break;

    case "PLATINUM":
    //Platinum
    clsBL blplatinum = new clsBL(new clsPlatinumDiscountStrategy());
    blplatinum.costPrice = 10;
    blplatinum.qty = 8;

    result = blplatinum.GetfinalPrice(blplatinum.costPrice, blplatinum.qty);
    break;
    default:
    Console.WriteLine("Enter the discount value as either gold or platinum");
    break;


    Console.WriteLine("The result for " + filter + " is " + result);


    else

    Console.WriteLine("Enter the discount value");
    return;



    Console.ReadLine();











    share|improve this question















    migrated from stackoverflow.com 3 hours ago


    This question came from our site for professional and enthusiast programmers.
















      up vote
      3
      down vote

      favorite
      1









      up vote
      3
      down vote

      favorite
      1






      1





      I am implementing strategy pattern. I have defined a strategy as interfaces and concrete classes to implement the strategy. Based on user selection/configuration, the algorithm to apply the discount changes.



       public interface IStrategy

      double calculate(double x, double y);



      concrete classes implementing the gold strategy is listed below -



      public class clsGoldDiscountStrategy : IStrategy

      public double calculate(double x, double y)

      return (x * y) * 0.8;


      }


      concrete classes implementing the platinumstrategy is listed below -



      public class clsPlatinumDiscountStrategy : IStrategy

      public double calculate(double x, double y)

      return (x * y) * 0.7;




      The business logic to apply



      public class clsBL

      public double costPrice get; set;
      public double qty get; set;
      IStrategy _strategy;

      public clsBL(IStrategy strategy)

      _strategy = strategy;


      public double GetfinalPrice(double cp, double qty)

      return _strategy.calculate(cp, qty);





      //Main method



      static void Main(string args)

      Console.WriteLine("Enter the discount Plan (Gold/Platinum)");
      string filter = Console.ReadLine().ToUpper();
      double result = 0;

      if (filter.Length > 0)

      switch (filter)

      case "GOLD":
      //Gold
      clsBL blgold = new clsBL(new clsGoldDiscountStrategy());
      blgold.costPrice = 5;
      blgold.qty = 10;

      result = blgold.GetfinalPrice(blgold.costPrice, blgold.qty);
      break;

      case "PLATINUM":
      //Platinum
      clsBL blplatinum = new clsBL(new clsPlatinumDiscountStrategy());
      blplatinum.costPrice = 10;
      blplatinum.qty = 8;

      result = blplatinum.GetfinalPrice(blplatinum.costPrice, blplatinum.qty);
      break;
      default:
      Console.WriteLine("Enter the discount value as either gold or platinum");
      break;


      Console.WriteLine("The result for " + filter + " is " + result);


      else

      Console.WriteLine("Enter the discount value");
      return;



      Console.ReadLine();











      share|improve this question















      I am implementing strategy pattern. I have defined a strategy as interfaces and concrete classes to implement the strategy. Based on user selection/configuration, the algorithm to apply the discount changes.



       public interface IStrategy

      double calculate(double x, double y);



      concrete classes implementing the gold strategy is listed below -



      public class clsGoldDiscountStrategy : IStrategy

      public double calculate(double x, double y)

      return (x * y) * 0.8;


      }


      concrete classes implementing the platinumstrategy is listed below -



      public class clsPlatinumDiscountStrategy : IStrategy

      public double calculate(double x, double y)

      return (x * y) * 0.7;




      The business logic to apply



      public class clsBL

      public double costPrice get; set;
      public double qty get; set;
      IStrategy _strategy;

      public clsBL(IStrategy strategy)

      _strategy = strategy;


      public double GetfinalPrice(double cp, double qty)

      return _strategy.calculate(cp, qty);





      //Main method



      static void Main(string args)

      Console.WriteLine("Enter the discount Plan (Gold/Platinum)");
      string filter = Console.ReadLine().ToUpper();
      double result = 0;

      if (filter.Length > 0)

      switch (filter)

      case "GOLD":
      //Gold
      clsBL blgold = new clsBL(new clsGoldDiscountStrategy());
      blgold.costPrice = 5;
      blgold.qty = 10;

      result = blgold.GetfinalPrice(blgold.costPrice, blgold.qty);
      break;

      case "PLATINUM":
      //Platinum
      clsBL blplatinum = new clsBL(new clsPlatinumDiscountStrategy());
      blplatinum.costPrice = 10;
      blplatinum.qty = 8;

      result = blplatinum.GetfinalPrice(blplatinum.costPrice, blplatinum.qty);
      break;
      default:
      Console.WriteLine("Enter the discount value as either gold or platinum");
      break;


      Console.WriteLine("The result for " + filter + " is " + result);


      else

      Console.WriteLine("Enter the discount value");
      return;



      Console.ReadLine();








      c# design-patterns






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 3 hours ago









      t3chb0t

      32.4k64299




      32.4k64299










      asked 7 hours ago









      krishna_v

      1161




      1161




      migrated from stackoverflow.com 3 hours ago


      This question came from our site for professional and enthusiast programmers.






      migrated from stackoverflow.com 3 hours ago


      This question came from our site for professional and enthusiast programmers.






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          2
          down vote













          The classes seem OK but the usage makes no sense:



           case "GOLD":
          //Gold
          clsBL blgold = new clsBL(new clsGoldDiscountStrategy());
          blgold.costPrice = 5;
          blgold.qty = 10;

          result = blgold.GetfinalPrice(blgold.costPrice, blgold.qty);
          break;


          This code (and the other switch case) does not use the polymorphism that the interface IStrategy enables. Rather, you can have simply written this code as:



           case "GOLD":
          double GetGoldPrice(double x, double y) => (x * y) * 0.8;
          result = GetGoldPrice(5, 10);
          break;


          Here, all classes and interfaces are deleted. There is just a static method.



          If you want to use the strategy pattern it must look something like:



          IStrategy strategy = GetStrategy();
          strategy.Calculate(...);


          Here, GetStrategy() can return any object compliant with that interface and further code does depend on any concrete type.




          Regarding naming, the classes do not have to be called "Strategy". I'd use the names IDiscountCalculator and GoldDicountCalculator. Or, instead of "Calculator" you could use "Model" or "Provider".






          share|improve this answer






















          • how do we pass the parameters in this?(for cost price and qty). you mean to say we do not add dependency injection to the clBL class. could you kindly detail me
            – krishna_v
            3 hours ago











          • I depends on the way you want the parameters to behave. Maybe you should give the parameters to the strategy constructor. Then, the parameters are fixed for the lifetime of the strategy object. If the parameters are dynamic, then they should be parameters to the Calculate method. They should not be fields of settable properties on IStrategy.
            – usr
            2 hours ago










          • Well, they could be settable if you want a strategy to be changeable. Nothing wrong with that in principle... But immutable objects usually make for a cleaner API.
            – usr
            2 hours ago

















          up vote
          0
          down vote













          x and y are really bad parameter names. I had to look at the client code to figure out that these were actually cost and quantity.





          share




















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f204676%2fapply-discount-changes-with-strategy-pattern%23new-answer', 'question_page');

            );

            Post as a guest






























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote













            The classes seem OK but the usage makes no sense:



             case "GOLD":
            //Gold
            clsBL blgold = new clsBL(new clsGoldDiscountStrategy());
            blgold.costPrice = 5;
            blgold.qty = 10;

            result = blgold.GetfinalPrice(blgold.costPrice, blgold.qty);
            break;


            This code (and the other switch case) does not use the polymorphism that the interface IStrategy enables. Rather, you can have simply written this code as:



             case "GOLD":
            double GetGoldPrice(double x, double y) => (x * y) * 0.8;
            result = GetGoldPrice(5, 10);
            break;


            Here, all classes and interfaces are deleted. There is just a static method.



            If you want to use the strategy pattern it must look something like:



            IStrategy strategy = GetStrategy();
            strategy.Calculate(...);


            Here, GetStrategy() can return any object compliant with that interface and further code does depend on any concrete type.




            Regarding naming, the classes do not have to be called "Strategy". I'd use the names IDiscountCalculator and GoldDicountCalculator. Or, instead of "Calculator" you could use "Model" or "Provider".






            share|improve this answer






















            • how do we pass the parameters in this?(for cost price and qty). you mean to say we do not add dependency injection to the clBL class. could you kindly detail me
              – krishna_v
              3 hours ago











            • I depends on the way you want the parameters to behave. Maybe you should give the parameters to the strategy constructor. Then, the parameters are fixed for the lifetime of the strategy object. If the parameters are dynamic, then they should be parameters to the Calculate method. They should not be fields of settable properties on IStrategy.
              – usr
              2 hours ago










            • Well, they could be settable if you want a strategy to be changeable. Nothing wrong with that in principle... But immutable objects usually make for a cleaner API.
              – usr
              2 hours ago














            up vote
            2
            down vote













            The classes seem OK but the usage makes no sense:



             case "GOLD":
            //Gold
            clsBL blgold = new clsBL(new clsGoldDiscountStrategy());
            blgold.costPrice = 5;
            blgold.qty = 10;

            result = blgold.GetfinalPrice(blgold.costPrice, blgold.qty);
            break;


            This code (and the other switch case) does not use the polymorphism that the interface IStrategy enables. Rather, you can have simply written this code as:



             case "GOLD":
            double GetGoldPrice(double x, double y) => (x * y) * 0.8;
            result = GetGoldPrice(5, 10);
            break;


            Here, all classes and interfaces are deleted. There is just a static method.



            If you want to use the strategy pattern it must look something like:



            IStrategy strategy = GetStrategy();
            strategy.Calculate(...);


            Here, GetStrategy() can return any object compliant with that interface and further code does depend on any concrete type.




            Regarding naming, the classes do not have to be called "Strategy". I'd use the names IDiscountCalculator and GoldDicountCalculator. Or, instead of "Calculator" you could use "Model" or "Provider".






            share|improve this answer






















            • how do we pass the parameters in this?(for cost price and qty). you mean to say we do not add dependency injection to the clBL class. could you kindly detail me
              – krishna_v
              3 hours ago











            • I depends on the way you want the parameters to behave. Maybe you should give the parameters to the strategy constructor. Then, the parameters are fixed for the lifetime of the strategy object. If the parameters are dynamic, then they should be parameters to the Calculate method. They should not be fields of settable properties on IStrategy.
              – usr
              2 hours ago










            • Well, they could be settable if you want a strategy to be changeable. Nothing wrong with that in principle... But immutable objects usually make for a cleaner API.
              – usr
              2 hours ago












            up vote
            2
            down vote










            up vote
            2
            down vote









            The classes seem OK but the usage makes no sense:



             case "GOLD":
            //Gold
            clsBL blgold = new clsBL(new clsGoldDiscountStrategy());
            blgold.costPrice = 5;
            blgold.qty = 10;

            result = blgold.GetfinalPrice(blgold.costPrice, blgold.qty);
            break;


            This code (and the other switch case) does not use the polymorphism that the interface IStrategy enables. Rather, you can have simply written this code as:



             case "GOLD":
            double GetGoldPrice(double x, double y) => (x * y) * 0.8;
            result = GetGoldPrice(5, 10);
            break;


            Here, all classes and interfaces are deleted. There is just a static method.



            If you want to use the strategy pattern it must look something like:



            IStrategy strategy = GetStrategy();
            strategy.Calculate(...);


            Here, GetStrategy() can return any object compliant with that interface and further code does depend on any concrete type.




            Regarding naming, the classes do not have to be called "Strategy". I'd use the names IDiscountCalculator and GoldDicountCalculator. Or, instead of "Calculator" you could use "Model" or "Provider".






            share|improve this answer














            The classes seem OK but the usage makes no sense:



             case "GOLD":
            //Gold
            clsBL blgold = new clsBL(new clsGoldDiscountStrategy());
            blgold.costPrice = 5;
            blgold.qty = 10;

            result = blgold.GetfinalPrice(blgold.costPrice, blgold.qty);
            break;


            This code (and the other switch case) does not use the polymorphism that the interface IStrategy enables. Rather, you can have simply written this code as:



             case "GOLD":
            double GetGoldPrice(double x, double y) => (x * y) * 0.8;
            result = GetGoldPrice(5, 10);
            break;


            Here, all classes and interfaces are deleted. There is just a static method.



            If you want to use the strategy pattern it must look something like:



            IStrategy strategy = GetStrategy();
            strategy.Calculate(...);


            Here, GetStrategy() can return any object compliant with that interface and further code does depend on any concrete type.




            Regarding naming, the classes do not have to be called "Strategy". I'd use the names IDiscountCalculator and GoldDicountCalculator. Or, instead of "Calculator" you could use "Model" or "Provider".







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 3 hours ago

























            answered 4 hours ago









            usr

            635310




            635310











            • how do we pass the parameters in this?(for cost price and qty). you mean to say we do not add dependency injection to the clBL class. could you kindly detail me
              – krishna_v
              3 hours ago











            • I depends on the way you want the parameters to behave. Maybe you should give the parameters to the strategy constructor. Then, the parameters are fixed for the lifetime of the strategy object. If the parameters are dynamic, then they should be parameters to the Calculate method. They should not be fields of settable properties on IStrategy.
              – usr
              2 hours ago










            • Well, they could be settable if you want a strategy to be changeable. Nothing wrong with that in principle... But immutable objects usually make for a cleaner API.
              – usr
              2 hours ago
















            • how do we pass the parameters in this?(for cost price and qty). you mean to say we do not add dependency injection to the clBL class. could you kindly detail me
              – krishna_v
              3 hours ago











            • I depends on the way you want the parameters to behave. Maybe you should give the parameters to the strategy constructor. Then, the parameters are fixed for the lifetime of the strategy object. If the parameters are dynamic, then they should be parameters to the Calculate method. They should not be fields of settable properties on IStrategy.
              – usr
              2 hours ago










            • Well, they could be settable if you want a strategy to be changeable. Nothing wrong with that in principle... But immutable objects usually make for a cleaner API.
              – usr
              2 hours ago















            how do we pass the parameters in this?(for cost price and qty). you mean to say we do not add dependency injection to the clBL class. could you kindly detail me
            – krishna_v
            3 hours ago





            how do we pass the parameters in this?(for cost price and qty). you mean to say we do not add dependency injection to the clBL class. could you kindly detail me
            – krishna_v
            3 hours ago













            I depends on the way you want the parameters to behave. Maybe you should give the parameters to the strategy constructor. Then, the parameters are fixed for the lifetime of the strategy object. If the parameters are dynamic, then they should be parameters to the Calculate method. They should not be fields of settable properties on IStrategy.
            – usr
            2 hours ago




            I depends on the way you want the parameters to behave. Maybe you should give the parameters to the strategy constructor. Then, the parameters are fixed for the lifetime of the strategy object. If the parameters are dynamic, then they should be parameters to the Calculate method. They should not be fields of settable properties on IStrategy.
            – usr
            2 hours ago












            Well, they could be settable if you want a strategy to be changeable. Nothing wrong with that in principle... But immutable objects usually make for a cleaner API.
            – usr
            2 hours ago




            Well, they could be settable if you want a strategy to be changeable. Nothing wrong with that in principle... But immutable objects usually make for a cleaner API.
            – usr
            2 hours ago












            up vote
            0
            down vote













            x and y are really bad parameter names. I had to look at the client code to figure out that these were actually cost and quantity.





            share
























              up vote
              0
              down vote













              x and y are really bad parameter names. I had to look at the client code to figure out that these were actually cost and quantity.





              share






















                up vote
                0
                down vote










                up vote
                0
                down vote









                x and y are really bad parameter names. I had to look at the client code to figure out that these were actually cost and quantity.





                share












                x and y are really bad parameter names. I had to look at the client code to figure out that these were actually cost and quantity.






                share











                share


                share










                answered 8 mins ago









                RubberDuck

                27k454155




                27k454155



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f204676%2fapply-discount-changes-with-strategy-pattern%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Comments

                    Popular posts from this blog

                    What does second last employer means? [closed]

                    List of Gilmore Girls characters

                    Confectionery