首页 > 解决方案 > 如何使用 runnable 将 java 命令模式迁移到 PHP 7.4?

问题描述

出于学习目的,我正在尝试将此 Java 命令模式示例迁移到 PHP:

https://codereview.stackexchange.com/questions/52110/command-pattern-implementation

UML 图

正如@simon 评论的那样,使用方法引用运算符会使代码现代化很多:

class MyCommand implements Order {
    private final Runnable action;

    public MyCommand(Runnable action) {
         this.action = action;
    }

    @Override
    public void execute() {
         action.run();
    }
}

然后你可以创建这样的命令:

MyCommand bsc = new MyCommand(stock::buy);
MyCommand ssc = new MyCommand(stock::sell);

我当前的 PHP 实现在这里:https ://3v4l.org/iIHn9

那么在 PHP 中实现 MyCommand 类的最佳方法是什么?

标签: javaphprunnableportingcommand-pattern

解决方案


在 PHP 中,您可以使用call_user_func类似于 Java 中的方法引用来实现相同的目的。

<?php

namespace StockCommandNS;

//Command interface
interface Order {
    public function execute();
}

//Receiver class
class StockTrade {

    public function buy() {
        print("You want to buy stocks\n");
    }

    public function sell() {
        print("You want to sell stocks\n");
    }
}

//Invoker class
class Agent {

    public function placeOrder(Order $order) {
        $order->execute($order);
    }
}

//ConcreteCommand Class
class GenericOrder implements Order {

    private $action;

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

    public function execute() {
        call_user_func($this->action);
    }
}

$stock = new StockTrade();
$bsc = new GenericOrder([$stock, 'buy']);
$ssc = new GenericOrder([$stock, 'sell']);
$agent = new Agent();
$agent->placeOrder($bsc); // Buy Shares
$agent->placeOrder($ssc); // Sell Shares

7.2.0 - 7.4.3 的输出

You want to buy stocks
You want to sell stocks

运行 PHP 代码:https ://3v4l.org/fWo20

另一个不太干净的选择是使用变量函数。

class GenericOrder implements Order {

    private $stock;
    private $action;

    public function __construct($stock, $action) {
        $this->stock = $stock;
        $this->action = $action;
    }

    public function execute() {
        $method = $this->action;
        $this->stock->$method();
    }
}

$bsc = new GenericOrder($stock, 'buy');
$ssc = new GenericOrder($stock, 'sell');

我不确定在所有情况下使用方法引用的方法都更好。根据经验,您应该始终根据每个用例考虑何时使用方法引用或匿名函数是命令模式。


推荐阅读