Back to: Design Patterns in C# With Real-Time Examples
Strategy Design Pattern Real-Time Example in C# – Travel and Payment
In this article, I will discuss the Travel and Payment Real-Time Examples using the Strategy Design Pattern in C#. Please read our previous article discussing the basic concepts of the Strategy Design Pattern with Examples. The Strategy Design Pattern belongs to the category of Behavioral Design Patterns, i.e., it deals with the communication or interaction between Classes and objects.
Strategy Design Pattern Real-Time Example in C#- Travel
Let us understand the Strategy Design Pattern in C# using a Real-Time Example of Travel. Please have a look at the following image. On the left-hand side, you can see a house, and John is staying in the house. You can see the Airport on the right-hand side, and the distance from John’s house to the Airport is approximately 100 KM. Suppose John wants to go to the Airport. Then what are all the different kinds of transport modes John can use? John can use an Auto, Train, Taxi, or Bus to go to the Airport. So, John has four options, and he can choose any option to go to the Airport.
As per the Strategy Design Pattern, multiple solutions will exist for the particular Task (or Problem or Algorithm). The client will choose one solution from the available solutions only at runtime. So, in our example, Traveling is the Task, and John has four options to go to the Airport. And John will choose only one option based on the cost, convenience, and time.
Implementing the Travel Real-Time Example in C# using Strategy Design Pattern:
Let us implement the above Travel Real-Time Example step by step in C# using the Strategy Design Pattern. This is one of the best real-time examples of the Strategy Design Pattern.
Step 1: Creating Strategy Interface
This is going to be an Interface, and this Interface declares methods that are common to all supported versions of the algorithm. So, create an interface with ITravelStrategy.cs and copy and paste the code below. The Context object will use this interface to call the algorithm defined by ConcreteStrategy classes.
namespace StrategyPatternRealTimeExample { // Strategy Interface // The ITravelStrategy Interface declares the method GotoAirport that is common to all supported versions of the algorithm. // The Context is going to use this Strategy Interface to call the algorithm defined by Concrete Strategies. public interface ITravelStrategy { void GotoAirport(); } }
Step 2: Creating Concrete Strategies
The Concrete Strategies will be the classes that implement the ITravelStrategy interface. Each Concrete Strategy will provide one option to go to the AirPort by implementing the method GotoAirport of the ITravelStrategy interface. Let’s create four Concrete Strategy classes as per our business requirement.
AutoTravelStrategy
Create a class file named AutoTravelStrategy.cs, then copy and paste the following code. The following AutoTravelStrategy Concrete Strategy class implements the ITravelStrategy Interface and Implement the GotoAirport Method. This strategy provides the option to go to the AirPort by Auto.
using System; namespace StrategyPatternRealTimeExample { // Concrete Strategy A // The following AutoTravelStrategy Concrete Strategy implement the ITravelStrategy Interface and // Implement the GotoAirport Method. public class AutoTravelStrategy : ITravelStrategy { public void GotoAirport() { Console.WriteLine("Traveler is going to Airport by Auto and will be charged Rs 600"); } } }
TrainTravelStrategy
Create a class file named TrainTravelStrategy.cs and copy and paste the following code into it. The following TrainTravelStrategy Concrete Strategy class implements the ITravelStrategy Interface and Implement the GotoAirport Method. This strategy provides the option to go to the AirPort by Train.
using System; namespace StrategyPatternRealTimeExample { // Concrete Strategy B // The following TrainTravelStrategy Concrete Strategy implement the ITravelStrategy Interface and // Implement the GotoAirport Method. public class TrainTravelStrategy : ITravelStrategy { public void GotoAirport() { Console.WriteLine("Traveler is going to Airport by Train and will be charged Rs 200"); } } }
TaxiTravelStrategy
Create a class file named TaxiTravelStrategy.cs, then copy and paste the following code. The following TaxiTravelStrategy Concrete Strategy class implements the ITravelStrategy Interface and Implement the GotoAirport Method. This strategy provides the option to go to the AirPort by Taxi.
using System; namespace StrategyPatternRealTimeExample { // Concrete Strategy C // The following TaxiTravelStrategy Concrete Strategy implement the ITravelStrategy Interface and // Implement the GotoAirport Method. public class TaxiTravelStrategy : ITravelStrategy { public void GotoAirport() { Console.WriteLine("Traveler is going to Airport by Taxi and will be charged Rs 1000"); } } }
BusTravelStrategy
Create a class file named BusTravelStrategy.cs and copy and paste the following code. The following BusTravelStrategy Concrete Strategy class implements the ITravelStrategy Interface and Implement the GotoAirport Method. This strategy provides the option to go to the AirPort by Bus.
using System; namespace StrategyPatternRealTimeExample { // Concrete Strategy D // The following BusTravelStrategy Concrete Strategy implement the ITravelStrategy Interface and // Implement the GotoAirport Method. public class BusTravelStrategy : ITravelStrategy { public void GotoAirport() { Console.WriteLine("Traveler is going to Airport by bus and will be charged Rs 300"); } } }
Step 3: Creating context
Create a class file named TravelContext.cs and copy and paste the following code. This TravelContext class contains a property that holds the reference of a Strategy object. The client will set this property at run-time according to the required algorithm. The following class code is self-explained, so please go through the comment lines for a better understanding.
namespace StrategyPatternRealTimeExample { // The Context Provides the interface which is going to be used by the Client. public class TravelContext { // The Context has a reference to one of the Strategy objects. // The Context does not know the concrete class of a strategy. // It should work with all strategies via the Strategy interface. private ITravelStrategy travelStrategy; // The Client will set what TravelStrategy to use by calling this method at runtime public void SetTravelStrategy(ITravelStrategy strategy) { travelStrategy = strategy; } // The Context delegates the work to the Strategy object instead of // implementing multiple versions of the algorithm on its own. public void GotoAirport() { travelStrategy.GotoAirport(); } } }
Step 4: Client code
The Main method of the Program class is going to be the client. So, modify the Main method of the Program class as shown below. The following Client Code is self-explained, so please go through the comment lines for a better understanding.
using System; namespace StrategyPatternRealTimeExample { class Program { static void Main(string[] args) { //Ask the user to Select the Travel Type Console.WriteLine("Please Enter Travel Type : \n1 for Auto \n2 for Bus \n3 for Train \n4 for Taxi"); int travelType = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("You Select Travel type : " + travelType); //Create an Instance of the TravelContext class TravelContext ctx = new TravelContext(); //Based on the Travel Type Selected by user at Runtime, //Create the Appropriate Travel Instance and call the SetTravelStrategy method if (travelType == (int)TravelType.Bus) { ctx.SetTravelStrategy(new BusTravelStrategy()); } else if (travelType == (int)TravelType.Train) { ctx.SetTravelStrategy(new TrainTravelStrategy()); } else if (travelType == (int)TravelType.Taxi) { ctx.SetTravelStrategy(new TaxiTravelStrategy()); } else if (travelType == (int)TravelType.Auto) { ctx.SetTravelStrategy(new AutoTravelStrategy()); } else { Console.WriteLine("You Select an Invalid Option"); } //Finally, call the GotoAirport Method ctx.GotoAirport(); Console.Read(); } } public enum TravelType { Auto = 1, // 1 for Auto Bus = 2, // 2 for Bus Train = 3, // 3 for Train Taxi = 4 // 4 for Taxi } }
Output:
UML or Class Diagram of Strategy Design Pattern:
Let us understand the Class Diagram or UML Diagram of the above example by comparing it with the Strategy Design Pattern and understanding the different components involved. Please have a look at the following image.
As shown in the above UML or Class Diagram, three participants are involved in the Strategy Design Pattern in C#. Their role and responsibilities are as follows:
- Strategy: The Strategy declares an interface that all supported algorithms will implement. In our example, it is the GotoAirport method of the ITravelStrategy interface.
- ConcreteStrategy: These will be concrete classes, and they must implement the Strategy (ITravelStrategy) interface and provide implementations for the algorithm. In our example, it is the AutoTravelStrategy, TrainTravelStrategy, TaxiTravelStrategy, and BusTravelStrategy classes.
- Context: This is going to be a class that maintains a reference to a Strategy object and then uses that reference to call the algorithm defined by a particular ConcreteStrategy (i.e., one of the instances of AutoTravelStrategy, TrainTravelStrategy, TaxiTravelStrategy, and BusTravelStrategy classes.). In our example, it is the TravelContext class.
Strategy Design Pattern Real-Time Example in C# – Payment
Let us understand the Real-time example of the Strategy Design Pattern using C#. Please have a look at the following image. As shown in the following image, Steve goes to a shopping mall and purchases one LED TV and washing machine for around 90000 rupees. After purchasing the LED TV and Washing Machines, Steve goes to the bill counter and wants to pay the money. There are three different options to pay the money. The options are Credit card, Debit Card, and Cash. So, he has to choose one option from these three options and pay the money at the bill counter.
So, per the Strategy Design Pattern, multiple solutions will exist for a particular Task (Problem). From the solutions, the user has to choose only one solution at runtime. So, in this example, paying money is the task, and Steve has three options (Credit, Debit, and Cash) to pay the money. And Steve will choose only one option at the time of billing.
Implementing the Payment Example using the Strategy Design Pattern in C#:
Let us implement the above example step by step in C# using the Strategy Design Pattern. This is one of the best real-time examples of the Strategy Pattern.
Step 1: Creating Strategy Interface
This is going to be an Interface, and this Interface declares methods that are common to all supported versions of the algorithm. So, create an interface with IPaymentStrategy.cs and copy and paste the code below. The Context will use this interface to call the algorithm defined by ConcreteStrategy classes.
namespace StrategyPatternRealTimeExample { // Strategy Interface // The IPaymentStrategy Interface declares the method Pay that is common to all supported versions of the algorithm. // The Context is going to use this IPaymentStrategy Interface to call the algorithm defined by Concrete Strategies. public interface IPaymentStrategy { void Pay(double amount); } }
Step 2: Creating Concrete Strategies
These are going to be the classes that implement the IPaymentStrategy interface. Each Concrete Strategy will provide one option to make the Payment at the billing counter by implementing the Pay method of the IPaymentStrategy interface. Let’s create three Concrete Strategy classes as per our business requirement.
CreditCardPaymentStrategy
Create a class file named CreditCardPaymentStrategy.cs, then copy and paste the following code. The following CreditCardPaymentStrategy Concrete Strategy class implements the IPaymentStrategy Interface and provides implementations for the Pay Method. This strategy provides the option to make the payment via the Credit Card.
using System; namespace StrategyPatternRealTimeExample { // Concrete Strategy A // The following CreditCardPaymentStrategy Class implements the IPaymentStrategy Interface and // Implement the Pay Method. public class CreditCardPaymentStrategy : IPaymentStrategy { public void Pay(double amount) { Console.WriteLine("Customer pays Rs " + amount + " using Credit Card"); } } }
DebitCardPaymentStrategy
Create a class file named DebitCardPaymentStrategy.cs, and then copy and paste the following code. The following DebitCardPaymentStrategy Concrete Strategy class implements the IPaymentStrategy Interface and provides implementations for the Pay Method. This strategy provides the option to make the payment via the Debit Card.
using System; namespace StrategyPatternRealTimeExample { // Concrete Strategy B // The following DebitCardPaymentStrategy class implements the IPaymentStrategy Interface and // Implement the Pay Method. public class DebitCardPaymentStrategy : IPaymentStrategy { public void Pay(double amount) { Console.WriteLine("Customer pays Rs " + amount + " using Debit Card"); } } }
CashPaymentStrategy
Create a class file named CashPaymentStrategy.cs and copy and paste the following code. The following CashPaymentStrategy Concrete Strategy class implements the IPaymentStrategy Interface and provides implementations for the Pay Method. This strategy provides the option to make the payment via Cash.
using System; namespace StrategyPatternRealTimeExample { // Concrete Strategy C // The following CashPaymentStrategy class implement the IPaymentStrategy Interface and // Implement the Pay Method. public class CashPaymentStrategy : IPaymentStrategy { public void Pay(double amount) { Console.WriteLine("Customer pays Rs " + amount + " By Cash"); } } }
Step 3: Creating Context
Create a class file called PaymentContext.cs and copy and paste the following code. This PaymentContext class contains a property that holds the reference of a Strategy object. The client will set this property at run-time according to the payment option the client selected. The following class code is self-explained, so please go through the comment lines for a better understanding.
namespace StrategyPatternRealTimeExample { // The Context Provides the interface which is going to be used by the Client. public class PaymentContext { // The Context has a reference to the Strategy object. // The Context does not know the concrete class of a strategy. // It should work with all strategies via the Strategy interface. private IPaymentStrategy PaymentStrategy; // The Client will set what PaymentStrategy to use by calling this method at runtime public void SetPaymentStrategy(IPaymentStrategy strategy) { PaymentStrategy = strategy; } // The Context delegates the work to the Strategy object instead of // implementing multiple versions of the algorithm on its own. public void Pay(double amount) { PaymentStrategy.Pay(amount); } } }
Step 4: Client code
The Main method of the Program class is going to be the client. So, modify the Main method of the Program class as shown below. The following Client Code is self-explained, so please go through the comment lines for a better understanding.
using System; namespace StrategyPatternRealTimeExample { class Program { static void Main(string[] args) { //Ask the user to Select the Payment Type Console.WriteLine("Please Select Payment Type : \n1 For CreditCard \n2 For DebitCard \n3 For Cash"); int SelectedPaymentType = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Payment type is : " + SelectedPaymentType); Console.WriteLine("\nPlease enter Amount to Pay : "); double Amount = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("Amount is : " + Amount); //Create an Instance of the PaymentContext class PaymentContext context = new PaymentContext(); //Based on the Payment Type Selected by user at Runtime, //Create the Appropriate Payment Strategy Instance and call the SetPaymentStrategy method if (SelectedPaymentType == (int)PaymentType.CreditCard) { context.SetPaymentStrategy(new CreditCardPaymentStrategy()); } else if (SelectedPaymentType == (int)PaymentType.DebitCard) { context.SetPaymentStrategy(new DebitCardPaymentStrategy()); } else if (SelectedPaymentType == (int)PaymentType.Cash) { context.SetPaymentStrategy(new CashPaymentStrategy()); } else { Console.WriteLine("You Select an Invalid Option"); } //Finally, call the Pay Method context.Pay(Amount); Console.ReadKey(); } } public enum PaymentType { CreditCard = 1, // 1 for CreditCard DebitCard = 2, // 2 for DebitCard Cash = 3, // 3 for Cash } }
Output:
Understanding the UML or Class Diagram of Strategy Design Pattern:
Let us understand the Class Diagram or UML Diagram of the above example by comparing it with the Strategy Design Pattern and understanding the different components involved. Please have a look at the following image.
As shown in the above UML or Class Diagram, three participants are involved in the Strategy Design Pattern. Their role and responsibilities are as follows:
- Strategy: The Strategy declares an interface that all supported algorithms will implement. In our example, it is the payment method of the IPaymentStrategy interface.
- ConcreteStrategy: These will be concrete classes, and they must implement the Strategy (IPaymentStrategy) interface and provide implementations for the algorithm. Our example includes the CreditCardPaymentStrategy, DebitCardPaymentStrategy, and CashPaymentStrategy classes.
- Context: This is going to be a class that maintains a reference to a Strategy object and then uses that reference to call the algorithm defined by a particular ConcreteStrategy (i.e., one of the instances of CreditCardPaymentStrategy, DebitCardPaymentStrategy, and CashPaymentStrategy classes.). In our example, it is the PaymentContext class.
In the next article, I will discuss the Real-Time Examples of the Strategy Design Pattern in C#. Here, in this article, I try to explain the Travel and Payment Real-Time Examples using the Strategy Design Pattern in C#. I hope you enjoy these Real-Time Examples of the Strategy Design Pattern in the C# article.
About the Author: Pranaya Rout
Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.