Strategy pattern: one of the design patterns
So far, we have covered three design patterns in this series. We define four different categories of design patterns. In this article, I will explain the Strategic Design Pattern, which falls under the Behavioral Design Patterns.
You may have a question: When should you use this design pattern? I would say when we have multiple methods (algorithms) to perform the same operation and we want the application to choose a specific method based on the parameters you have. This mode is also called strategy mode.
A very simple example for this article is the sorting function. For example, we have multiple algorithms for sorting arrays, but depending on the number of array elements, we should choose which algorithm to use to get the best performance.
This mode is also called strategy mode.
question
I will give an example of an e-commerce website that integrates multiple payment gateways. Although the website has multiple payment gateways, upon request, they are not all displayed on the front-end. Instead, the appropriate payment gateway needs to be selected on the fly based on the cart amount.
As a simple example, if the cart value is less than $500, the payment should be processed using PayPal standards, but if the amount is $500 or more, it should be processed using the stored credit card details (assuming the details have been storage).
Without the correct strategy implemented, our code would look like this:
First we will provide the main classes for payment via Paypal and payment via credit card, which will be added below.
// Class to pay using Credit Card class payByCC { private $ccNum = ''; private $ccType = ''; private $cvvNum = ''; private $ccExpMonth = ''; private $ccExpYear = ''; public function pay($amount = 0) { echo "Paying ". $amount. " using Credit Card"; } } // Class to pay using PayPal class payByPayPal { private $payPalEmail = ''; public function pay($amount = 0) { echo "Paying ". $amount. " using PayPal"; } } // This code needs to be repeated every place where ever needed. $amount = 5000; if($amount >= 500) { $pay = new payByCC(); $pay->pay($amount); } else { $pay = new payByPayPal(); $pay->pay($amount); }
Here, you might say that we need to put conditional statements to make our code work properly. Imagine how many changes you need to make when we need to make new changes to this logic or you find a bug in this logic. We have to add patches to all places where this code is used.
solution
We will implement the same requirement, but using the Strategy pattern, which allows us to make our code clearer, easier to understand and extensible.
interface
First, we will implement the interfaces that all the different payment gateway classes will use. Ultimately, these are our strategies.
interface payStrategy { public function pay($amount); } class payByCC implements payStrategy { private $ccNum = ''; private $ccType = ''; private $cvvNum = ''; private $ccExpMonth = ''; private $ccExpYear = ''; public function pay($amount = 0) { echo "Paying ". $amount. " using Credit Card"; } } class payByPayPal implements payStrategy { private $payPalEmail = ''; public function pay($amount = 0) { echo "Paying ". $amount. " using PayPal"; } }
Next we will create our main class, which can use different strategies than the ones we have implemented so far.
class shoppingCart { public $amount = 0; public function __construct($amount = 0) { $this->amount = $amount; } public function getAmount() { return $this->amount; } public function setAmount($amount = 0) { $this->amount = $amount; } public function payAmount() { if($this->amount >= 500) { $payment = new payByCC(); } else { $payment = new payByPayPal(); } $payment->pay($this->amount); } }
Here we can see that the conditional loading of our payment method is done in the payAmount
method. Let's wrap everything together and see how to use it further.
interface payStrategy { public function pay($amount); } class payByCC implements payStrategy { private $ccNum = ''; private $ccType = ''; private $cvvNum = ''; private $ccExpMonth = ''; private $ccExpYear = ''; public function pay($amount = 0) { echo "Paying ". $amount. " using Credit Card"; } } class payByPayPal implements payStrategy { private $payPalEmail = ''; public function pay($amount = 0) { echo "Paying ". $amount. " using PayPal"; } } class shoppingCart { public $amount = 0; public function __construct($amount = 0) { $this->amount = $amount; } public function getAmount() { return $this->amount; } public function setAmount($amount = 0) { $this->amount = $amount; } public function payAmount() { if($this->amount >= 500) { $payment = new payByCC(); } else { $payment = new payByPayPal(); } $payment->pay($this->amount); } } $cart = new shoppingCart(499); $cart->payAmount(); // Output Paying 499 using PayPal $cart = new shoppingCart(501); $cart->payAmount(); //Output Paying 501 using Credit Card
We can see that the payment gateway rollover is not transparent to the application. Depending on the parameters, it has the appropriate payment gateway available to process the transaction.
Add new strategy
If at a later stage the user needs to add a new strategy with different logic (here a new payment gateway), it will be very simple in this case. Let’s say we want to add a new payment gateway, Moneybooker, and want to process funds when the cart amount exceeds $500 but falls below $1,000.
All we need to do is create a new strategy class that implements our interface and we are good to go.
class payByMB implements payStrategy { private $mbEmail = ''; public function pay($amount = 0) { echo "Paying ". $amount. " using Money Booker"; } }
We now have our new strategy class ready, all we need to change is the main payAmount
method. Need to be modified as follows:
public function payAmount() { if($this->amount > 500 && $this->amount < 1000) { $payment = new payByMB(); } else if($this->amount >= 500) { $payment = new payByCC(); } else { $payment = new payByPayPal(); } $payment->pay($this->amount); }
Here you can see that we only made the change in the payAmount
method, not in the client code that calls the method.
in conclusion
So to conclude, when we have multiple ways to perform the same task (in software languages, when we have multiple algorithms to perform the same operation), we should consider implementing the Strategy pattern.
By using this mode, we can add/remove algorithms freely since the switching of these algorithms is not transparent to the application.
I've tried my best to provide a basic but useful example to demonstrate the Strategy Design Pattern, but if you have additional comments or questions, please feel free to add them to the feed below.
The above is the detailed content of Strategy pattern: one of the design patterns. For more information, please follow other related articles on the PHP Chinese website!

PHPsessionstrackuserdataacrossmultiplepagerequestsusingauniqueIDstoredinacookie.Here'showtomanagethemeffectively:1)Startasessionwithsession_start()andstoredatain$_SESSION.2)RegeneratethesessionIDafterloginwithsession_regenerate_id(true)topreventsessi

In PHP, iterating through session data can be achieved through the following steps: 1. Start the session using session_start(). 2. Iterate through foreach loop through all key-value pairs in the $_SESSION array. 3. When processing complex data structures, use is_array() or is_object() functions and use print_r() to output detailed information. 4. When optimizing traversal, paging can be used to avoid processing large amounts of data at one time. This will help you manage and use PHP session data more efficiently in your actual project.

The session realizes user authentication through the server-side state management mechanism. 1) Session creation and generation of unique IDs, 2) IDs are passed through cookies, 3) Server stores and accesses session data through IDs, 4) User authentication and status management are realized, improving application security and user experience.

Tostoreauser'snameinaPHPsession,startthesessionwithsession_start(),thenassignthenameto$_SESSION['username'].1)Usesession_start()toinitializethesession.2)Assigntheuser'snameto$_SESSION['username'].Thisallowsyoutoaccessthenameacrossmultiplepages,enhanc

Reasons for PHPSession failure include configuration errors, cookie issues, and session expiration. 1. Configuration error: Check and set the correct session.save_path. 2.Cookie problem: Make sure the cookie is set correctly. 3.Session expires: Adjust session.gc_maxlifetime value to extend session time.

Methods to debug session problems in PHP include: 1. Check whether the session is started correctly; 2. Verify the delivery of the session ID; 3. Check the storage and reading of session data; 4. Check the server configuration. By outputting session ID and data, viewing session file content, etc., you can effectively diagnose and solve session-related problems.

Multiple calls to session_start() will result in warning messages and possible data overwrites. 1) PHP will issue a warning, prompting that the session has been started. 2) It may cause unexpected overwriting of session data. 3) Use session_status() to check the session status to avoid repeated calls.

Configuring the session lifecycle in PHP can be achieved by setting session.gc_maxlifetime and session.cookie_lifetime. 1) session.gc_maxlifetime controls the survival time of server-side session data, 2) session.cookie_lifetime controls the life cycle of client cookies. When set to 0, the cookie expires when the browser is closed.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

WebStorm Mac version
Useful JavaScript development tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SublimeText3 English version
Recommended: Win version, supports code prompts!
