5

我正在尝试在 Laravel 应用程序中应用 Bob 叔叔的Clean Architecture

我关心的是:正如鲍勃叔叔所描述的,控制器应该属于第三个圈子:接口适配器(从内到外)。这意味着控制器仅依赖于用例圈(第 2 圈),并且不应该对第 4 圈中的框架一无所知。

但是有些框架中的控制器必须扩展一个基类(例如,一个 AbstractController 类),它还需要接收一个 Request 对象,有时还需要返回一个 Response 对象,所以这有点打破了Clean Architecture 的依赖规则,因为它知道外圈的框架。

我误解了吗?如果没有,是否有任何解决方案可以不破坏依赖规则

我的控制器看起来像这样:

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use User\UseCase\FetchUsers;
use User\UseCase\FetchUsersRequest;

class UserController extends Controller
{
    public function index(Request $request, FetchUsers $fetchUsersUseCase)
    {
        $useCaseRequest = new FetchUsersRequest(
            // extract data from Request
        );

        $useCaseResponse = $fetchUsersUseCase->handle($useCaseRequest);

        return [
            'users' => $useCaseResponse->users,
        ];
    }
}
4

2 回答 2

1

AbstractController属于第三圈。所以你不会破坏任何依赖。如果您在用例圈中有数据传输对象 (DTO)用于将数据传输到第三个圈,则不会破坏任何依赖关系。

为了实现这一点,您应该为所有请求和响应创建 DTO,将您的实体映射到 DTO 并共享 DTO 而不是实体。

例如:您有一个User实体,其中包含一个名为 的字符串变量Name。您有一个控制器将从use-cases圈子中获取用户。

解决方案:创建一个以UserDto字符串变量命名的 DTO(您可以调用它Name)。控制器知道UserDto但不知道User entity

于 2016-11-30T10:29:01.907 回答
0

有点太晚了,但是您可以在用例圈中创建一个特定控制器的接口(这将被称为干净架构中的输入端口)。

然后您可以在第三个圆圈中实现接口,例如

// In the use-cases circle
interface UserControllerInterface(){

    public function index(Request $request, FetchUsers $fetchUsersUseCase);

}

// In the third circle
class UserController extends Controller implements UserControllerInterface{

    public function index(Request $request, FetchUsers $fetchUsersUseCase){
        $useCaseRequest = new FetchUsersRequest(
            // extract data from Request
        );

        $useCaseResponse = $fetchUsersUseCase->handle($useCaseRequest);

        return [
            'users' => $useCaseResponse->users,
        ];
    }
}

这样你就不会违反纪律。

于 2017-03-01T15:50:18.637 回答