In this post, I will explain how to implement the Strategy Design Pattern in Node.js.
To illustrate this concept, I’ll use the example of integrating multiple payment methods which can be used in the e-commerse and other applications to accept payment from customers. Whether it’s PayPal, bank transfers, or credit card.
Strategy Pattern
The Strategy Design Pattern is a behavioral design pattern in software engineering that enables the dynamic selection of algorithms at runtime, allowing for greater flexibility and adaptability in the application’s behavior.
This pattern is highly useful for developers in creating flexible, maintainable, and clean code, especially when multiple algorithms are needed to solve a problem.
This pattern promotes the Open/Closed Principle, which states that software entities should be open for extension but closed for modification, as per the SOLID principles.
Benefits of Using the Strategy Pattern
Flexibility and Reusability:
Instead of large blocks of if-else statements, the logic is separated into different strategy classes, making the code more flexible, easier to extend, and more readable.
Separation of Concerns:
Each algorithm has its own dedicated strategy class. All tests and logic can be written for a specific strategy class. Logic change in one strategy will not impact the other strategy.
Ease of Testing:
Each strategy class or algorithm can be tested separately, allowing unit tests to be written for each strategy class without affecting the existing functionality of the other strategies.
Open for Extension
Newer strategy can be easily added without affecting the existing functionality of the other strategies.
Although this design pattern has many benefits, it also comes with some drawbacks. For instance, your application may end up with numerous classes, which could lead to confusion and complexity. It’s important to have proper documentation to manage this effectively.
Strategy Pattern in Node.js
Let’s assume you already have installed Node in your machine.
Initialize a Node.js project
Let me create a project folder nodejs-strategy-pattern
. You can follow below setps to initate the node.js app.
Install dependencies
npm init -y
command needs to be run inside the project folder to create the package.json
file.
Next step is to install the express
package in our project. Here, we are installing express
as a node module and saving in the package.json
.
|
|
Also add
"start": "node app.js",
in scripts
After installing the express
package your package.json
file will be like below.
|
|
Create the necessary files:
Create necessary strategy class and fiels that are required. We have the following structure:
|
|
Creating Payment Strategies
We define three classes (PayPalStrategy
, BankTransferStrategy
, and CreditCardStrategy
) that encapsulate the logic for processing payments through their respective providers.
BankTransferStrategy class
Create a BankTransferStrategy class that simulates processing a payment through Bank Transfer.
PayPalStrategy class
Next, create a PayPalStrategy class that simulates processing a payment through PayPal.
CreditCardStrategy class
Finally, create a CreditCardStrategy class that simulates processing a payment through Credit Card.
Implementing the Payment Handling Logic in app.js
Now that we have our strategies in place, let’s move on to the main application file (app.js
), where we will use the Strategy Pattern to select the correct payment provider based on user input.
|
|
Now, it’s time to test the application we built. You can run
node app.js
or npm start
to start the app on port 3000.
Since our app is running on localhost at port 3000, we can submit JSON payload specifying the payment provider and amount to the API endpoint http://localhost:3000/pay
. Based on the provider, the application dynamically chooses the corresponding strategy to process the payment.
Here is the example of provider using payPal
Sample Payload:
Sample Resposne:
Here is the full screenshot of the request and response:
Instead of payPal
, you can easily switch the payment provider to bankTransfer
or creditCard
, and it will automatically use the correct PaymentStrategy
class.
You can even add a new payment provider, such as bitcoin
. To do this, simply create a new strategy class to handle Bitcoin payments and add context.
Components of Strategy Design Pattern
There are four componensts of the strategy desing pattern
- Context : The Context is the main class that uses a strategy to perform tasks. It allows switching algorithms without modifying the existing code. In our case below piece of code is the context.
Strategy Interface : Defines common methods that all strategies must implement. In JavaScript, interfaces cannot be defined directly, but in TypeScript, they can be used to achieve this.
Concrete Strategy : Actual implementation of the algorithm. In our case
./BankTransferStrategy.js
;PayPalStrategy.js
andCreditCardStrategy.js
are the Concrete Strategy.Client : Interacts with the Context and triggers the use of a strategy. In our case clint would be API end point
http://localhost:3000/pay
Conclusion
In conclusion, the Strategy Pattern is a powerful design approach that enhances flexibility, maintainability, and adherence to SOLID principles. By decoupling algorithms into distinct strategy classes, it allows for easy extension of functionality without altering existing code. This makes it particularly well-suited for scenarios like dynamic payment processing, where seamless integration of multiple options is required.
In this post, we also explored a practical implementation of the Strategy Pattern by integrating payment providers into a Node.js application.
Github Reposatory : https://github.com/dev-scripts/nodejs-strategy-pattern