Opinion: Strategy Pattern + Factory Pattern will be the most-used design pattern in your career
Note: Usage of specific design patterns may depend on the programming language, the type of application, and the preferences of the team/developer. This post is solely based on my experience of building enterprise software in C#.
Take a look at some of the use cases below...
Perform a specific behavior that depends on a set of data or variables that can change at runtime.
Select an algorithm or behavior from a set of alternatives at runtime.
Decouple a class from the algorithms or behaviors it uses.
Change the behavior of a class without changing its code.
Add new behaviors to a system without changing existing code.
Use different algorithms or behaviors in different contexts.
Isolate a class from the details of its algorithms or behaviors.
Use the same algorithm or behavior in multiple classes.
Extend a class with new behaviors without modifying its code.
Reuse the same algorithm or behavior in different parts of a system
Avoid creating a large class with many conditional statements to handle different behaviors.
At the risk of generalizing all software development use cases, I opine that the majority of the business use cases you will encounter will be a variant of the above scenarios.
In my opinion, a combination of Strategy + Factory can be used for all the scenarios.
Of course, there are 'better-suited' design patterns than Strategy/Factory for the scenarios above - but this will get you off the blocks in the first iteration.
Below is a simple example of how Strategy and Factory patterns are used to solve a use case.
Imagine that we are designing a taxi service application that allows users to book rides with different types of vehicles, such as a standard car, a luxury car, or a minivan.
In this scenario, we can use the Strategy Design pattern to define the different algorithms for calculating the fare for each type of vehicle. This allows us to easily add or remove vehicle types without having to make major changes to the rest of the application.
// The base Strategy interface
public interface IFareStrategy
{
double CalculateFare(int distance);
}
// Concrete Strategies
public class StandardCarFare : IFareStrategy
{
public double CalculateFare(int distance)
{
return distance * 0.5;
}
}
public class LuxuryCarFare : IFareStrategy
{
public double CalculateFare(int distance)
{
return distance * 0.7;
}
}
public class MinivanFare: IFareStrategy
{
public double CalculateFare(int distance)
{
return distance * 0.9;
}
}
public class TaxiFareMethodFactory
{
public static IFareStrategy CreateFareMethod(string type)
{
if (type == "StandardCar")
{
return new StandardCarFare();
}
else if (type == "LuxuryCar")
{
return new LuxuryCarFare();
}
else if (type == "Minivan")
{
return new MinivanFare();
}
else
{
throw new ArgumentException("Invalid fare method type");
}
}
}
// The Context
public class FareCalculator
{
private IFareStrategy _fareStrategy;
public FareCalculator(string fareType)
{
_fareStrategy = TaxiFareMethodFactory.CreateFareMethod(fareType);
}
public double CalculateFare(int distance)
{
return _fareStrategy.CalculateFare(distance);
}
}
// Usage
var fare = new FareCalculator("StandardCar");
fare.CalculateFare(100);
// Output: 50
fare = new FareCalculator("LuxuryCar");
fare.CalculateFare(100);
// Output: 70
fare = new FareCalculator("Minivan");
fare.CalculateFare(100);
// Output: 90
As you can see the pattern implementation is very easy.
Together, the Strategy and Factory patterns can help you create more flexible and maintainable software by allowing you to change the behavior of your algorithms and the objects that are created at runtime. They are essential tools for any software developer to have in their toolkit.
Liked my content? Do kindly like and share to help other students in your network. And don't forget to subscribe to the newsletter to NEVER miss an article. I also tweet here.