Home  >  Article  >  Backend Development  >  PHP design pattern strategy pattern

PHP design pattern strategy pattern

高洛峰
高洛峰Original
2016-11-22 10:09:091387browse

Introduction

The strategy pattern defines a family of algorithms and encapsulates them separately so that they can be replaced with each other. This model allows the algorithm to change independently of the customers using it.

Composed of

Abstract strategy role: Strategy class, usually implemented by an interface or abstract class.

Specific strategy role: packaging related algorithms and behaviors.

Environment role: holds a reference to a strategy class, which is ultimately called by the client.

Application scenarios

Multiple classes are only distinguished by different behaviors. You can use the strategy mode to dynamically select the specific behavior to be executed at runtime.

Different strategies (algorithms) need to be used in different situations, or the strategy may be implemented in other ways in the future.

The implementation details of specific strategies (algorithms) are hidden from customers and are completely independent of each other.

Implementation

Steps

Define the abstract role class (define the common abstract method of each implementation)

Define the specific strategy class (concretely implement the common method of the parent class)

Define the environment role class (receive the saved instance and execute it uniformly Strategy class interface method)

Code

<?php
header(&#39;Content-Type:text/html;charset=utf-8&#39;);
/**
 * 策略模式演示代码
 *
 * 为了更好地突出“策略”,我们这里以出行为例演示,日常出行大概分为以下几种工具:自驾车,公交车,地铁,火车,飞机,轮船
 *
 * 下面一起看代码,领会何为策略模式
 */

/**
 * Interface Travel 抽象策略角色
 * 约定具体方法
 */
interface Travel
{
    public function go();
}

/**
 * Class selfDriving 具体策略角色
 * 自驾车
 */
class bySelfDriving implements Travel
{
    public function go()
    {
        echo &#39;我自己开着车出去玩<br>&#39;;
    }
}

/**
 * Class byBus具体策略角色
 * 乘公交
 */
class byBus implements Travel {
    public function go()
    {
        echo &#39;我乘公交出去玩<br>&#39;;
    }
}

/**
 * Class byMetro 具体策略角色
 * 乘地铁
 */
class byMetro implements Travel
{
    public function go()
    {
        echo &#39;我乘地铁出去玩<br>&#39;;
    }
}

/**
 * Class byTrain 具体策略角色
 * 乘火车
 */
class byTrain implements Travel
{
    public function go()
    {
        echo &#39;我乘火车出去玩<br>&#39;;
    }
}

/**
 * Class byAirplane 具体策略角色
 * 乘飞机
 */
class byAirplane implements Travel
{
    public function go()
    {
        echo &#39;我乘飞机出去玩<br>&#39;;
    }
}

/**
 * Class bySteamship 具体策略角色
 * 乘轮船
 */
class bySteamship implements Travel
{
    public function go()
    {
        echo &#39;我乘轮船出去玩<br>&#39;;
    }
}

/**
 * Class Mine 环境角色
 */
class Mine{
    private $_strategy;
    private $_isChange = false;

    /**
     * 构造方法
     * 此处使用到了依赖注入和类型约束的概念,详情请参考
     * 1.聊一聊PHP的依赖注入(DI) 和 控制反转(IoC)
     * @link https://segmentfault.com/a/1190000007209266
     * 2.浅谈PHP的类型约束
     * @link https://segmentfault.com/a/1190000007226476
     *
     * @param Travel $travel
     */
    public function __construct(Travel $travel)
    {
        $this->_strategy = $travel;
    }

    /**
     * 改变出行方式
     *
     * @param Travel $travel
     */
    public function change(Travel $travel)
    {
        $this->_strategy = $travel;
        $this->_isChange = true;
    }

    public function goTravel()
    {
        if ($this->_isChange) {
            echo &#39;现在改变主意,&#39;;
            $this->_strategy->go();
        } else {
            $this->_strategy->go();
        }

    }
}

/**
 * 客户端使用
 */
$strategy = new Mine(new byBus());
// 乘公交
$strategy->goTravel();
// 乘地铁
$strategy->change(new byMetro());
$strategy->goTravel();
// 自驾车
$strategy->change(new bySelfDriving());
$strategy->goTravel();

// 其他根据具体应用选择实现

Running results

I took the bus to go out to play
Now I changed my mind, I took the subway to go out to play
Now I changed my mind, I drove out to play by myself

Advantages and disadvantages

Advantages

The strategy pattern provides a way to manage related algorithm families. A hierarchy of policy classes defines a family of algorithms or behaviors. Proper use of inheritance can transfer common code to the parent class, thereby avoiding duplication of code.

The strategy pattern provides a way to replace the inheritance relationship. Inheritance can handle multiple algorithms or behaviors. If you are not using the strategy pattern, then the environment class that uses the algorithm or behavior may have some subclasses, each subclass providing a different algorithm or behavior. However, in this way the users of the algorithm or behavior are conflated with the algorithm or behavior itself. The logic that determines which algorithm to use or which behavior to take becomes mixed with the logic of the algorithm or behavior, making it impossible for it to evolve independently. Inheritance makes it impossible to dynamically change algorithms or behavior.

Using strategy pattern can avoid using multiple conditional transfer statements. Multiple transfer statements are not easy to maintain. It mixes the logic of which algorithm or behavior to adopt with the logic of the algorithm or behavior, and lists them all in one multiple transfer statement. It is more primitive and backward than the inheritance method. .

Disadvantages

The client must know all the policy classes and decide which one to use. This means that the client must understand the differences between these algorithms in order to select the appropriate algorithm class at the right time. In other words, the strategy pattern is only suitable if the client knows all the algorithms or behaviors.

The strategy pattern creates many strategy classes, and each specific strategy class will generate a new class. Sometimes it is possible to design a policy class to be shareable by saving environment-dependent state to the client, so that policy class instances can be used by different clients. In other words, you can use the flyweight pattern to reduce the number of objects.


Statement:
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