Table of Contents
question
interface
in conclusion
Home Backend Development PHP Tutorial Strategy pattern: one of the design patterns

Strategy pattern: one of the design patterns

Aug 28, 2023 pm 05:53 PM
Design Patterns strategy pattern Key words

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.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

// 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);

}

Copy after login

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.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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";

    }

 

}

Copy after login

Next we will create our main class, which can use different strategies than the ones we have implemented so far.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

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);

         

    }

}

Copy after login

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.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

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

Copy after login

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.

1

2

3

4

5

6

7

8

9

class payByMB implements payStrategy {

 

    private $mbEmail = '';

     

    public function pay($amount = 0) {

        echo "Paying ". $amount. " using Money Booker";

    }

 

}

Copy after login

We now have our new strategy class ready, all we need to change is the main payAmount method. Need to be modified as follows:

1

2

3

4

5

6

7

8

9

10

11

12

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);

}

Copy after login

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!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

The difference between design patterns and architectural patterns in Java framework The difference between design patterns and architectural patterns in Java framework Jun 02, 2024 pm 12:59 PM

In the Java framework, the difference between design patterns and architectural patterns is that design patterns define abstract solutions to common problems in software design, focusing on the interaction between classes and objects, such as factory patterns. Architectural patterns define the relationship between system structures and modules, focusing on the organization and interaction of system components, such as layered architecture.

What are the practical application cases of strategy pattern in java framework? What are the practical application cases of strategy pattern in java framework? Jun 05, 2024 pm 08:44 PM

The strategy pattern in the Java framework is used to dynamically change class behavior. Specific applications include: Spring framework: data validation and cache management JakartaEE framework: transaction management and dependency injection JSF framework: converters and validators, response life cycle management

Analysis of the Decorator Pattern in Java Design Patterns Analysis of the Decorator Pattern in Java Design Patterns May 09, 2024 pm 03:12 PM

The decorator pattern is a structural design pattern that allows dynamic addition of object functionality without modifying the original class. It is implemented through the collaboration of abstract components, concrete components, abstract decorators and concrete decorators, and can flexibly expand class functions to meet changing needs. In this example, milk and mocha decorators are added to Espresso for a total price of $2.29, demonstrating the power of the decorator pattern in dynamically modifying the behavior of objects.

PHP design pattern practical case analysis PHP design pattern practical case analysis May 08, 2024 am 08:09 AM

1. Factory pattern: Separate object creation and business logic, and create objects of specified types through factory classes. 2. Observer pattern: allows subject objects to notify observer objects of their state changes, achieving loose coupling and observer pattern.

How design patterns deal with code maintenance challenges How design patterns deal with code maintenance challenges May 09, 2024 pm 12:45 PM

Design patterns solve code maintenance challenges by providing reusable and extensible solutions: Observer Pattern: Allows objects to subscribe to events and receive notifications when they occur. Factory Pattern: Provides a centralized way to create objects without relying on concrete classes. Singleton pattern: ensures that a class has only one instance, which is used to create globally accessible objects.

The wonderful use of the adapter pattern in Java design patterns The wonderful use of the adapter pattern in Java design patterns May 09, 2024 pm 12:54 PM

The Adapter pattern is a structural design pattern that allows incompatible objects to work together. It converts one interface into another so that the objects can interact smoothly. The object adapter implements the adapter pattern by creating an adapter object containing the adapted object and implementing the target interface. In a practical case, through the adapter mode, the client (such as MediaPlayer) can play advanced format media (such as VLC), although it itself only supports ordinary media formats (such as MP3).

PHP Design Patterns: Test Driven Development in Practice PHP Design Patterns: Test Driven Development in Practice Jun 03, 2024 pm 02:14 PM

TDD is used to write high-quality PHP code. The steps include: writing test cases, describing the expected functionality and making them fail. Write code so that only the test cases pass without excessive optimization or detailed design. After the test cases pass, optimize and refactor the code to improve readability, maintainability, and scalability.

Application of design patterns in Guice framework Application of design patterns in Guice framework Jun 02, 2024 pm 10:49 PM

The Guice framework applies a number of design patterns, including: Singleton pattern: ensuring that a class has only one instance through the @Singleton annotation. Factory method pattern: Create a factory method through the @Provides annotation and obtain the object instance during dependency injection. Strategy mode: Encapsulate the algorithm into different strategy classes and specify the specific strategy through the @Named annotation.

See all articles