我试图在Laravel应用程序中应用Bob叔叔的Clean Architecture。
我所关注的是:正如鲍勃叔叔所描述的那样,控制器应该属于第三个圈子:接口适配器(从里到外)。这意味着Controller仅依赖于Use Case Circle(2nd),并且不应该对第4圈中的框架有任何了解。
但是某些框架中的控制器必须扩展基类(例如,一个AbstractController类),它还需要接收一个Request对象,有时还会返回一个Response对象,所以这种打破了依赖规则强大的清洁架构,因为它了解外圈的框架。
我误解了吗?如果没有,是否有任何解决方案不打破依赖规则?
我的控制器看起来像这样:
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,
];
}
}
答案 0 :(得分:1)
AbstractController
属于第三个圈。所以你不要打破任何依赖。如果您在用例圈中有数据传输对象(DTO),以便将数据传输到第三个圈,那么您就不会破坏任何依赖。
为了实现这一目标,您应该为所有请求和响应创建DTO,将您的实体映射到DTO并共享DTO而不是实体。
例如:您有一个User
实体,其字符串变量名为Name
。您有一个控制器将从use-cases
圈中获取用户。
解决方案:使用字符串变量创建名为UserDto
的DTO(您可以将其称为Name
)。 Controller知道UserDto
但不知道User entity
答案 1 :(得分: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,
];
}
}
这样你就不会违反纪律。