gpt4 book ai didi

php - 如何在保持服务层抽象的同时使用 Yii 组件?

转载 作者:搜寻专家 更新时间:2023-10-31 21:38:18 24 4
gpt4 key购买 nike

我喜欢并使用 Yii 框架,尤其是它的“组件”,它们是延迟实例化的,您可以在配置文件中换入或换出它们。有点像依赖注入(inject)精简版。

我尽量使我的代码的业务逻辑完全独立于框架,以防我想重新调整该代码的用途,甚至更改框架。

假设我的服务层中有一个名为 AccountService 的类,它实现了 IAccountService 并具有一个单参数构造函数。

interface IAccountService
{
function getUserById($id);
}

class AccountService implements IAccountService
{
private $_userRepository;

public function __construct(IUserRepository $userRepository) {
$this->_userRepository = $userRepository;
}

public function getUserById($id) {
return $this->_userRepository->getById($id);
}
}

太棒了。到目前为止,它是完全无框架的。现在我想将它公开为一个 Yii 组件,这样它就可以延迟实例化,并且可以很容易地被 Yii Controller 和其他 Yii 组件使用。

但是 Yii 组件(实现 IApplicationComponent)必须有零个构造函数参数,而我的类需要一个!

有什么想法吗?

这是我得到的。我对他们中的任何一个都不满意;它们看起来都设计过度了,我从它们身上闻到了明显的气味。

选项 1 - 组合:我创建了一个名为“AccountServiceComponent”的类,它实现了 Yii 的 IApplicationComponent。由于构造函数的原因,它无法扩展我的 AccountService 类,但它可以将一个类实例化为私有(private)成员并包装其所有方法,如下所示:

class AccountServiceComponent implements IApplicationComponent, IAccountservice
{
private $_accountService;

public __construct() {
$this->_accountService = new AccountService(new UserRepository());
}

public getUserById($id) {
return $this->_accountService->getUserById($id);
}
}

缺点:我必须像那样包装每个 方法,这很乏味并且可能导致“果仁蜜饼代码”。特别是考虑到会有多个服务类,每个服务类都有多种方法。

选项 2 - 混入:(或者行为或特质或现在所谓的任何东西。)

Yii(在 PHP 5.4 之前编写)以实现 IBehavior 的类的形式提供“行为”。我可以创建一个扩展我的服务的行为类,并将其附加到一个组件:

class AccountServicesBehavior extends AccountService implements IBehavior
{
// Implement the few required methods here
}

class AccountServiceComponent implements IApplicationComponent
{
public function __construct() {
$accountService = new AccountService(new UserRepository());
$this->attachBehavior($accountService);
}

缺点:我的组件不再正式实现 IAccountService。分层似乎也变得过多。

选项 3 - 可选的构造函数参数:

我可以让我的服务类的构造函数参数是可选的,然后将它扩展到一个组件中:

class AccountService implements IAccountService
{
public $userRepository;

public function __construct(IUserRepository $userRepository = null) {
$this->userRepository = $userRepository;
}

public function getUserById($id) {
return $this->_userRepository->getById($id);
}
}

class AccountServiceComponent extends AccountService implements IApplicationComponent
{
}

缺点:可选的构造函数参数意味着这个类现在可以在不提供它需要的一切的情况下被实例化。

...那么,我还缺少其他选项吗?还是我只能选择对我影响最小的那个?

最佳答案

选项 3,但将对象作为可选参数听起来最好:

public function __construct(IUserRepository $userRepository = new UserRepository()) {
$this->userRepository = $userRepository;
}

关于php - 如何在保持服务层抽象的同时使用 Yii 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13960486/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com