Monday 26 December 2016

Strategy Pattern In MVC4

08:57 Posted by Nikesh No comments



 Creating a form which on post do calculation based on different shipping types.We will learn how these calculations occurs in Strategy Pattern


We are creating very simple form in which we can enter price and based on shipping service we can do calculation.


<form action="/home/myform" method="post">


    <input type="text" value="" name="Address1" />
    <input type="text" value="" name="Address2" />
    <input type="text" value="" name="price" />

    <select name="shipingservice">
        <option value="Fedex">Fedex</option>
        <option value="UPS">UPS</option>
        <option value="Shenker">Shrinker</option>
    </select>

    <input type="submit" />
</form>



Creating Action result. Create your action and add Post codes on your Action Post.

        public ActionResult myform()
        {
          
            return View();
        }


         [HttpPost, ValidateInput(false)]
        public ActionResult myform(   Address a)
        {
          

        //////////Accepting Values from Forms///////////////
          
            Int64 price  =  Convert.ToInt64(Request.Params["price"].ToString());
            String Address1 = a.Address1 = Request.Params["Address1"].ToString();
            String Address2 = a.Address2 = Request.Params["Address2"].ToString();
            String shipingservice = Request.Params["shipingservice"].ToString();


       ///////////////A call to shipcostcalculation class which passes our data based on strategy for calculations.////


            Shipcostcalculator sc  =  new Shipcostcalculator();
                      
            sc.pricefiller = price;   //// // Passing price to class by Setting price to shipcalculatior getter setter

           //////////// //checking shipping type and based on form values//////////////////////.


            switch (shipingservice)
            {

                case "Fedex":
                    

          /////////////A call to strategy/////////////

                    sc.strategy = new FedexShippingStrategy();

                    break;

                case "UPS":

                    sc.strategy = new UPSshippingStrategy();

                    break;

                case "Shenker":

                    sc.strategy = new ShrenkShippingStrategy();

                    break;

             

                default:

                    throw new ArgumentException("Unexpected value in drop down");

            }
            
            ///// //In last call to custom strategies fucntion to start calculation///////////
          
            Int64 result = 0;
            result = sc.CalulateCost();

           
////////Saving data to database after calculation done////////////////

            Int64 id = Address.AddProductData(a, result);

            return View();
        }



We have noticed little annoying codes in Myform action post but soon you will recover what is happening.

To use strategy we need interface.
Create an interface by right clicking on Model -->> Add -->> Interface. Name it Strategy. 





Strategy Interface

namespace strategypattern.Models
{
    public interface Strategy
    {
        Int64 Calculate(Int64 price);
    }
}




Add Class Adress.cs  by right click on model. In side that add string fields which later we can use to validate and enum which will say about our shipping. one thing i have not bounded relation with enum in that example because i am trying to make it easy as much it can.

Add class Adress.cs


namespace strategypattern.Models
{
    public class Address
    {
        public string Name { get; set; }
        public string Address1 { get; set; }
        public string Address2 { get; set; }

        static public int AddProductData(Address a, Int64 ad)
        {        
                return 2;
        }
    }
    public enum shipOtions
    {
        UPS,
        Fedex,
        Shenker
    }
   }



Add Three classes FedexShippingStrategy.cs,ShrenkShippingStrategy.cs,UPSshippingStrategy.cs

which will work based on our strategy of calculations we have.We will parse our price inputted in strategy Calculate function which is implemented by interface.


FedexShippingStrategy.cs

namespace strategypattern.Models
{
    public class FedexShippingStrategy : Strategy
    {
             public  Int64 Calculate(Int64 price)
        {
          Int64 prices = price;
          Int64 calculation = prices - 4;

          return calculation;    ////We always have to give return type same that interface has.
        }
    }
}



ShrenkShippingStrategy.cs

namespace strategypattern.Models
{
    public class ShrenkShippingStrategy : Strategy
    {
       public Int64 Calculate(Int64 price)
        {
            return (price -  6);
        }
    }
}



UPSshippingStrategy.cs


namespace strategypattern.Models
{
    public class UPSshippingStrategy : Strategy
    {
       public Int64 Calculate(Int64 price)
        {
            return (price -  2);
        }
    }
}


 Now this is our main calculation service which directs which strategy have to use and pass parameters to that strategy.

Add a class Shipcostcalculator for calculation service

Shipcostcalculator.cs


namespace strategypattern.Models
{
    public class Shipcostcalculator
    {
        //Defining Strategy Interface as variable( Note we have not make this variable readonly because we have to pass parameters)//
     
        private  Strategy _mystratigies;


       /// // A mandatory constructor which is calling fedexstrategy default//////
        public Shipcostcalculator()
        {
            _mystratigies = new FedexShippingStrategy();
        }

        //variable which will retrieve value from our controls for calculations
        private Int64 price;

        ////////////Setter Getter through which we can pass our parameters to this class.////////

        public Int64 pricefiller
        {
            get { return price; }
            set { price = value; }
        }

       ////////// //Defining a getter setter for strategy which will pass from home controller.////////

        public Strategy strategy
        {
            get { return _mystratigies; }
            set { _mystratigies = value; }

       ///////////////By this we can get strategy name in _mystratigies variable.////////////////
        }

 /////////////A function which will call to our custom strategies with parameters.////////////////////
        public Int64  CalulateCost()
        {
            return _mystratigies.Calculate(price);  ////We can pass multiple parameters from here.
        }
    }
}

0 comments:

Post a Comment