Strategy pattern falls under the behavioral design patterns.
It’s very useful when you have an object which has some behaviors that could be changed during the run-time.
It’s common practice to separate what varies from what stay the same; separate those behaviors from the class of that object, treat each one of the behaviors as a separate class that implements an interface.
In Design Principles, we’ve mentioned in “Protected Variations” principle that interfaces are a solution for minimizing the impact of the parts of the system that are more likely to change. This pattern uses this principle to solve a common problem.
Example: Customer Payment
Let’s say that you have an application that tries to initiate a payment of a customer, but the problem is, the customer may choose to pay with paypal, or with credit card, where each of them has a different implementation.
We might say “Ok, why not to have a method for paypal and another one for credit card?”. This sounds reasonable for now, but what if you want to extend the methods of payment?. We will end up having many methods in one class, which is not a good case practice.
A composition relationship between the customer and the payment interface, where each payment method inherits setPayment method. The composition relationship implies the idea of HAS-A relationship.
Command pattern falls under the behavioral design patterns.
It’s solution to a problem when an object has to perform some commands during the run-time; we don’t know which commands needs to be executed.
You start separating those commands in encapsulated classes. Each class is implementing an interface that has a method called execute.
It’s the same principle as in the stratgey pattern; separate what varies from what stays the same.
Example: Read, Update, Delete Commands
We have the invoker object represents the admin, where the admin of the system can perform different commands. We have the command interface, where all commands are inheriting from it.
And we have the receiver object, which will be used by the inheriting command sub classes to perform the requested command.
A composition relationship between the admin and the command Interface, where each command method implements execute method.
State pattern is a behavioral software design patter.
It’s used for the system that has different states to navigate between them based on some interactions during the running time. States are in form of objects, where each state object handles a specific kind of user interaction.
The interactions maybe external interactions from the users, or internally from the system itself.
Again, the same principle also applies here; separate what varies from what stays the same. So, we need to encapsulate these states as they will be changed during the run time.
In our example, imagine that you have a microwave, that has an initial state called waiting, and whenever the user press on start button, it moves to working state, and at this point the user can either pause or stop the microwave.
In case of pause it will move to a third state called paused, and in case of stop, it will revert back to waiting state.
We start creating a class for each state, each of these states will inherit from an interface called State.
It has a list of methods; “start”, “pause” & “stop”. Notice that each state class will handle these methods, these are the interactions the user can make.
The user doesn’t need to know anything about the states, the user just perform some interactions; “start”,”pause, and “stop”.
So, what if the user clicks on pause while the system in waiting state. Inside the class of the waiting state, it should handles if the user wants to navigate to a wrong state, maybe you can display an error.
A composition relationship between the microwave and the state interface.
The microwave class handles the interactions of the user, by asking the current state object to handle this interaction, which in turn navigate from one state to another (if needed). So, we only care about creating an instance from the microwave class.
This decreases the dependency, and the user will only care about the Microwave rather than each state.