dersonsena/yii2-tactician

该包已被弃用,不再维护。作者建议使用astrotechlabs/yii2-tactician包。

Yii 2 命令总线模式实现

1.2.5 2022-01-26 20:27 UTC

This package is auto-updated.

Last update: 2023-12-24 15:46:31 UTC


README

Packagist PHP Version Support GitHub stars GitHub forks GitHub repo size GitHub license

这是一个针对Tactician 命令总线库的 Yii Framework 2 包装器/适配器。它提供了一个简单的方式来在基于 Yii2 的应用程序中使用命令总线模式。

我应该何时使用命令总线?

如果您的应用程序有一个服务层,Tactician 是一个很好的选择。如果您不确定服务层是什么,Martin Fowler 的 PoEAA 是一个很好的起点。Tactician 的作者还就此主题做了一次演讲。

命令可以帮助捕获用户的意图。当涉及到表单或期望 getter/setter 对象的序列化库时,它们也是模型的良好替代品。

命令总线本身很容易添加额外的行为,如锁定或数据库事务,因此很容易通过插件进行扩展。

by: tactician.thephpleague.com

我应该何时不使用它?

如果您有一个非常小的应用程序,不需要服务层,那么 Tactician 对您来说可能不会提供太多。

如果您已经使用了一个提供命令总线的工具(如 Broadway),那么您可能也做得很好。

by: tactician.thephpleague.com

安装

$ composer require astrotechlabs/yii2-tactician

设置

首先,您必须配置您的 Yii 依赖注入容器,以便在其中使用命令和处理类。

您应该在 config/web.php 中有类似以下内容

$config = [
    'id' => 'your-app-id',
    //...
    'container' => [
        'definitions' => [
            MyClassCommand::class => MyClassHandler::class 
        ]
    ],
    'components' => [
        //...
    ]
];

重要:您必须遵循以下约定

  • 您的 命令 类必须以 Command 结尾;
  • 您的 处理 类必须是: 相同的命令类名称 + 不带命令后缀 + Handler

最后一个是注册 Yii2TacticianCommandBus 组件到您的 config/web.php 文件中,如下所示

$config = [
    'id' => 'your-app-id',
    //...
    'container' => [
        'definitions' => [
            MyClassCommand::class => MyClassHandler::class 
        ]
    ],
    'components' => [
        'commandBus' => [
            'class' => AstrotechLabs\Yii2Tactician\Yii2TacticianCommandBus::class
        ],
        // other components...
    ]
];

如何使用

映射命令和处理类

在您的应用程序的某个地方定义一个 Command 类,例如

class MyClassCommand
{
    public $someParam;
    public $someOtherParam;

    public function __construct($someParam, $someOtherParam = 'defaultValue')
    {
    	$this->someParam = $someParam;
        $this->someOtherParam = $someOtherParam;
    }
}

定义您的 Handler 类应该是这样的

class MyClassHandler
{
    public function handle(MyClassCommand $command)
    {
    	// do command stuff here!
        // we can use $command->someParam and $this->someOtherParam
    }
}

现在我们可以在控制器或其他任何地方使用这个命令

public function actionDoSomething()
{
    $queryParam = Yii::$app->getRequest()->get('some_param');
    
    // Here the magic happens! =)
    $result = Yii::$app->commandBus->handle(new MyClassCommand($queryParam));

    if ($result === true) {
    	return $this->redirect(['go/to/some/place']);
    }

    return $this->render('some-awesome-view');
}

使用字符串路径

您可以使用命令类作为 字符串路径 而不是具体对象。为此,只需这样做

$config = [
    'id' => 'your-app-id',
    //...
    'container' => [
        'definitions' => [
            // you can use any string here.
            'awesome.alias.to.be.called.anywhere' => MyClassHandler::class 
        ]
    ],
    'components' => [
        //...
    ]
];

您的 处理类 应该如下所示

class MyClassHandler implements AstrotechLabs\Yii2Tactician\Handler
{
    public function handle(MyClassCommand $command)
    {
    	// do command stuff here!
        // we can use $command->someParam and $this->someOtherParam
    }
    
    public function commandClassName(): string
    {
        return MyClassCommand::class;
    }
}

重要:使用这种方式,您的处理类必须实现AstrotechLabs\Yii2Tactician\Handler接口,而您的命令类必须实现AstrotechLabs\Yii2Tactician\Command

您的控制器操作或任何其他地方

public function actionDoSomething()
{
    $result = Yii::$app->commandBus->handle('awesome.alias.to.be.called.anywhere', [
        'someParam' => 'abc',
        'someOtherParam' => 'def'
    ]);
    
    // .. other logics
}

在内部,命令总线系统会调用

MyClassHandler::handle($command);

其中$command参数是在这里创建的

MyClassCommand::create([someParam' => 'abc', 'someOtherParam' => 'def']);

享受吧 =).

作者

有关参与此项目的贡献者列表,请参阅贡献者

贡献

欢迎提出拉取请求。对于重大更改,请先提出问题以讨论您想要进行的更改。

请确保适当更新测试。

许可

此软件包在MIT许可下发布。有关详细信息,请参阅捆绑的LICENSE

参考文献