如何将使用 runnable 的 java 命令模式迁移到 PHP 7.4?
How to migrate a java command pattern using runnable to PHP 7.4?
出于学习目的,我正在尝试将此 Java 命令模式示例迁移到 PHP:
https://codereview.stackexchange.com/questions/52110/command-pattern-implementation
As @simon commented,使用方法引用运算符,将使代码现代化很多:
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 Class 的最佳方法是什么?
这里有一些关于PHP的设计模式的参考:
https://designpatternsphp.readthedocs.io/en/latest/README.html
https://phptherightway.com/#design_patterns
在 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');
我不确定使用方法引用的方法是否在所有情况下都更好。
根据经验,您应该始终根据每个用例考虑何时使用方法引用或匿名函数是命令模式。
正如 Evgeniy 已经提到的,您可以使用 call_user_func()。
由于有很多方法可以解决这个问题,我已经将我的解决方案添加到您的问题中。您还可以通过在 class 中添加 __invoke 方法来创建一个对象 callable
。也可以 return 一个 callable
函数。我总共添加了 3 个示例。
这是我在 java 中的 MyCommand
class 版本,用于所有 3 个示例。
class MyCommand implements Order
{
private $action;
public function __construct(callable $action)
{
$this->action = $action;
}
public function execute()
{
// Option 1) use call_user_function
call_user_func($this->action);
// Option 2) define it as a variable and call it by adding `()`
//$action = $this->action;
//$action();
}
}
示例 1) 可调用函数 (https://3v4l.org/FVTEK)
class Stock
{
public function buy(): callable
{
return function () {
echo "You want to buy stocks via callable function" . PHP_EOL;
};
}
public function sell(): callable
{
return function () {
echo "You want to sell stocks via callable function" . PHP_EOL;
};
}
}
$stock = new Stock();
$bsc = new MyCommand($stock->buy());
$ssc = new MyCommand($stock->sell());
$bsc->execute();
$ssc->execute();
示例 2) 可调用的 class (https://3v4l.org/BrKjv)
class StockBuy
{
public function __invoke()
{
echo "You want to buy stocks via __invoke()" . PHP_EOL;
}
}
class StockSell
{
public function __invoke()
{
echo "You want to sell stocks __invoke()" . PHP_EOL;
}
}
$bsc = new MyCommand(new StockBuy());
$ssc = new MyCommand(new StockSell());
$bsc->execute();
$ssc->execute();
示例 3) return 可调用的静态成员函数。只是一个更接近 java (https://3v4l.org/PKk4B)
的例子
class Stock
{
static public function buy(): callable
{
return function () {
echo "You want to buy stocks via callable function" . PHP_EOL;
};
// or as callable object
// return new StockBuy();
}
static public function sell(): callable
{
return function () {
echo "You want to sell stocks via callable function" . PHP_EOL;
};
// or as callable object
// return new StockSell();
}
}
$bsc = new MyCommand(Stock::buy());
$ssc = new MyCommand(Stock::sell());
$bsc->execute();
$ssc->execute();
如果您还有其他问题,请告诉我。
出于学习目的,我正在尝试将此 Java 命令模式示例迁移到 PHP:
https://codereview.stackexchange.com/questions/52110/command-pattern-implementation
As @simon commented,使用方法引用运算符,将使代码现代化很多:
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 Class 的最佳方法是什么?
这里有一些关于PHP的设计模式的参考:
https://designpatternsphp.readthedocs.io/en/latest/README.html https://phptherightway.com/#design_patterns
在 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');
我不确定使用方法引用的方法是否在所有情况下都更好。 根据经验,您应该始终根据每个用例考虑何时使用方法引用或匿名函数是命令模式。
正如 Evgeniy 已经提到的,您可以使用 call_user_func()。
由于有很多方法可以解决这个问题,我已经将我的解决方案添加到您的问题中。您还可以通过在 class 中添加 __invoke 方法来创建一个对象 callable
。也可以 return 一个 callable
函数。我总共添加了 3 个示例。
这是我在 java 中的 MyCommand
class 版本,用于所有 3 个示例。
class MyCommand implements Order
{
private $action;
public function __construct(callable $action)
{
$this->action = $action;
}
public function execute()
{
// Option 1) use call_user_function
call_user_func($this->action);
// Option 2) define it as a variable and call it by adding `()`
//$action = $this->action;
//$action();
}
}
示例 1) 可调用函数 (https://3v4l.org/FVTEK)
class Stock
{
public function buy(): callable
{
return function () {
echo "You want to buy stocks via callable function" . PHP_EOL;
};
}
public function sell(): callable
{
return function () {
echo "You want to sell stocks via callable function" . PHP_EOL;
};
}
}
$stock = new Stock();
$bsc = new MyCommand($stock->buy());
$ssc = new MyCommand($stock->sell());
$bsc->execute();
$ssc->execute();
示例 2) 可调用的 class (https://3v4l.org/BrKjv)
class StockBuy
{
public function __invoke()
{
echo "You want to buy stocks via __invoke()" . PHP_EOL;
}
}
class StockSell
{
public function __invoke()
{
echo "You want to sell stocks __invoke()" . PHP_EOL;
}
}
$bsc = new MyCommand(new StockBuy());
$ssc = new MyCommand(new StockSell());
$bsc->execute();
$ssc->execute();
示例 3) return 可调用的静态成员函数。只是一个更接近 java (https://3v4l.org/PKk4B)
的例子class Stock
{
static public function buy(): callable
{
return function () {
echo "You want to buy stocks via callable function" . PHP_EOL;
};
// or as callable object
// return new StockBuy();
}
static public function sell(): callable
{
return function () {
echo "You want to sell stocks via callable function" . PHP_EOL;
};
// or as callable object
// return new StockSell();
}
}
$bsc = new MyCommand(Stock::buy());
$ssc = new MyCommand(Stock::sell());
$bsc->execute();
$ssc->execute();
如果您还有其他问题,请告诉我。