PHP设计模式——命令模式

PHP设计模式——命令模式

声明

本系列博客参考资料《大话设计模式》,作者程杰。

命令模式

在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式。

类图

www.zeeklog.com  - PHP设计模式——命令模式

角色分析

抽象命令

定义命令的接口,声明执行的方法。

具体命令

命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。

命令接收者

接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。

控制者

要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。

核心代码

<?php
/**
 * Created by PhpStorm.
 * User: LYL
 * Date: 2015/6/4
 * Time: 20:21
 */

/**
 * 电视机是请求的接收者,
*遥控器上有一些按钮,不同的按钮对应电视机的不同操作。
*抽象命令角色由一个命令接口来扮演,有三个具体的命令类实现该接口:开机命令、关机命令和频道切换命令。
*/

// 命令接收者
class Tv {
    public function on() {
        echo "TV is on.<br>";
    }

    public function off() {
        echo "TV is off.<br>";
    }

    public function changeChannel($channel) {
        echo "TV channel changed to $channel.<br>";
    }
}

// 抽象命令
interface Command {
    public function execute();
}

// 具体命令:开机命令
class CommandOn implements Command {
    private $tv;

    public function __construct(Tv $tv) {
        $this->tv = $tv;
    }

    public function execute() {
        $this->tv->on();
    }
}

// 具体命令:关机命令
class CommandOff implements Command {
    private $tv;

    public function __construct(Tv $tv) {
        $this->tv = $tv;
    }

    public function execute() {
        $this->tv->off();
    }
}

// 具体命令:频道切换命令
class CommandChannel implements Command {
    private $tv;
    private $channel;

    public function __construct(Tv $tv, $channel) {
        $this->tv = $tv;
        $this->channel = $channel;
    }

    public function execute() {
        $this->tv->changeChannel($this->channel);
    }
}

// 命令控制对象
class Control {
    private $_onCommand;
    private $_offCommand;
    private $_changeChannel;

    public function __construct(Command $on, Command $off, Command $channel) {
        $this->_onCommand = $on;
        $this->_offCommand = $off;
        $this->_changeChannel = $channel;
    }

    public function turnOn() {
        $this->_onCommand->execute();
    }

    public function turnOff() {
        $this->_offCommand->execute();
    }

    public function changeChannel() {
        $this->_changeChannel->execute();
    }
}

调用客户端代码

header("Content-Type:text/html;charset=utf-8");
//----------------------命令模式--------------------
require_once "./Command/Command.php";
//测试代码
// 命令接收者  
$myTv = new Tv();
// 开机命令  
$on = new CommandOn($myTv);
// 关机命令  
$off = new CommandOff($myTv);

// 频道切换命令  
$channel = new CommandChannel($myTv, 2);
// 命令控制对象 
$control = new Control($on, $off, $channel);
// 开机  
$control->turnOn();
// 切换频道  
$control->changeChannel();
// 关机  
$control->turnOff();

适用场景

  1. 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
  2. 系统需要在不同的时间指定请求、将请求排队和执行请求。
  3. 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
  4. 系统需要将一组操作组合在一起,即支持宏命令。

优点

  1. 降低对象之间的耦合度。
  2. 新的操作可以很容易地加入到系统中。
  3. 可以比较容易地设计一个组合命令。
  4. 调用同一方法实现不同的功能

Read more

超快速,使用ChatGPT编写回归和分类算法

超快速,使用ChatGPT编写回归和分类算法

本文将使用一些 ChatGPT 提示,这些提示对于数据科学家在工作时非常重要。 微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩 以下是一些示例ChatGPT 提示的列表以及数据科学家的响应。 ChatGPT 提示 为决策树回归算法生成 python 代码。 下面是使用scikit-learn在 Python 中进行决策树回归的示例代码: import numpy as np import matplotlib.pyplot as plt from sklearn.tree import DecisionTreeRegressor # Generate random data rng = np.random.default_rng() x = 5 * rng.random(100) y = np.sin(x) + 0.

By Ne0inhk
力扣每日一题:993.二叉树的堂兄弟节点 深度优先算法

力扣每日一题:993.二叉树的堂兄弟节点 深度优先算法

993.二叉树的堂兄弟节点 难度:简单 题目: 在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。 如果二叉树的两个节点深度相同,但 父节点不同 ,则它们是一对堂兄弟节点。 我们给出了具有唯一值的二叉树的根节点 root ,以及树中两个不同节点的值 x 和 y 。 只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true 。否则,返回 false。 示例: 示例 1: 输入:root = [1,2,3,4], x = 4, y = 3 输出:false

By Ne0inhk
1239.串联字符串的最大长度 关于字符串的回溯算法!

1239.串联字符串的最大长度 关于字符串的回溯算法!

题目: 给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串, 如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解。 请返回所有可行解 s 中最长长度。 提示: 1 <= arr.length <= 16 1 <= arr[i].length <= 26 arr[i] 中只含有小写英文字母 示例: 示例 1: 输入:arr = ["un","iq","ue"] 输出:4 解释:所有可能的串联组合是

By Ne0inhk