我是巴西的开发者,所以......对不起我的英语有限的英语。
嗯,实际上我的问题更多是一个常规问题,因为到目前为止我还没有使用Laravel的服务(到目前为止,我的应用程序非常简单)。
在提出这个问题之前,我已经读到了这个问题,但在这个具体情况下没有任何帮助。我会尝试以客观的方式描述。
之前,只是评论:我知道在这些例子中只使用控制器的错误。提问真的是关于那个错误。
嗯,实际结构是:
abstract class CRUDController extends Controller {
protected function __construct($data, $validatorData) {
// store the data in a attribute
// create with Validator facade the validation and store too
}
abstract protected function createRecord();
protected function create() {
try {
// do the validation and return an Response instance with error messages
// if the data is ok, store in the database with models
// (here's where the magic takes place) in that store!
// to do that, calls the method createRecord (which is abstract)
$this->createRecord();
// return a success message in an Response instance
}
catch(\Exception $e) {
// return an Response instance with error messages
}
}
}
class UserController extends CRUDController {
public function __construct($data) {
parent::__construct($data, [
'rules' => [
// specific user code here
],
'messages' => [
// specific user code here
],
'customAttributes' => [
// specific user code here
]
]);
}
protected function createRecord() {
$user = new UserModel();
// store values here...
$user->save();
return $user;
}
}
// here's the route to consider in that example
Route::post('/user', 'WebsiteController@register');
class WebsiteController extends Controller {
private $request;
public function __construct(Request $request) {
$this->request = $request;
}
public function register() {
$user = new UserController();
$user->create($this->request);
// here's the problem: controller working with another controller
}
}
class UserAPIController extends Controller {
// use here the UserController too
}
以及以同样的方式扩展CRUDController的许多其他类......
我想要什么
我想创建一个控制器(在这里称为CRUDController)来重用模式所说的方法(创建,读取,更新和删除)。 为了真正客观,我将使用create方法作为示例。 有了上面的代码,它的目的似乎很明确吗?我想是这样的...我的所有控制器都具有相同且可重用的验证代码。这就是事情。 除此之外,我希望我的网站路由调用另一个控制器(UserController)来存储新用户......但同样地,我将以相同的方式创建一个使用相同控制器的API(带有验证等) )。这就是CRUDController中响应的目的(我将在WebSiteController中读取它们以解决要做的事情,比如显示视图,另一方面使用API我会基本上返回响应
我的真正问题
公约和模式。这里打破了MVC模式。控制器调用另一个控制器是错误的,我知道。 我想知道我应该用什么东西!服务?是对的吗?我看到很多(真的)服务的例子,但没有那样,使用模型和重用代码等。我从不使用服务,但我知道如何使用,但我不知道它是否是对这些案件的权利。
我真的希望有人可以在这里提供帮助,并再次对与英语的错误表示遗憾。非常感谢。
答案 0 :(得分:1)
您将CRUD控制器称为控制器,但它不像MVC控制器那样。它充其量只是一个帮助类。你总是可以这样做:
abstract class CRUDManager {
//As you had the CRUDController
}
class UserManager extends CRUDManager {
//As you had the UserController
}
在AppServiceProvider中:
public function boot() {
$app->bind(UserManager::class, function ($app) {
return new UserManager(request()->all()); //I guess that's what you need.
});
}
无论何时需要使用它,您都可以:
public function register(UserManager $user) {
$user->create();
}
现在有一点需要指出。在构造函数中初始化请求不是一个好主意。您应该在控制器方法中使用依赖注入。我甚至不知道在构建控制器时请求是否可用(我知道会话不是)。我之所以这么说是因为中间件在构造控制器之后运行,因此在调用控制器方法时可以修改请求。
另一个注意事项:如果您因为需要使用某些控制器方法而执行原始解决方案,那么您可以使用相应的特征(因为控制器本身并没有真正的方法)。我猜测像ValidatesRequests这样的特质是use
所需要的。
答案 1 :(得分:0)
我会回答我自己的问题。我使用一种名为Repository Pattern的模式来解决问题(或者我尝试使用,因为它是第一次使用这种模式:也许我不会在每个步骤中以正确的方式使用它。)
文件结构
Controllers
UserController.php
Models
UserModel.php
Providers
UserRepositoryServiceProvider.php
Repositories
RepositoryInterface.php
Repository.php
User
UserRepositoryInterface.php
UserRepository.php
Traits
InternalResponse.php
通过这种结构,我在我的问题中做了我想做的事,而不需要只使用控制器。
我创建了一个名为InternalResponse的特征。该特性包含一些接收事务的方法,验证是否是这种情况然后返回响应(在我的逻辑中称为“内部”,因为控制器将读取并可能在最终返回之前更改响应)。
Repository类,它是抽象的(因为另一个类必须扩展它才有意义使用。在这种情况下,UserRepository类将扩展...),使用提到的Trait。
嗯,考虑到这一点,我们可以知道UserController使用UserRepositoryInterface,它提供了一个UserRepository对象:因为UserRepositoryServiceProvider在该接口上注册了它。
我认为没有必要在这里编写代码来解释,因为问题是关于一个模式,这些词很好地解释了问题(在问题中)和这个答案的解决方案。
我在这里写一个结论,我的意思是,文件结构带有注释来解释一下,结束答案。
结论:带注释的文件结构
Controllers
UserController.php
// the controller uses dependency injection and call methods of
// UserRepository, read and changes the Response receveid to finally
// create the final Response, like returning a view or the response
// itself (in the case it's an API controller)
Models
UserModel.php
// an normal model
Providers
UserRepositoryServiceProvider.php
// register the UserRepositoryInterface to
// return a UserRepository object
Repositories
RepositoryInterface.php
// the main interface for the Repository
Repository.php
// the main repository. It's an abstract class.
// All the others repositories must extend that class, because
// there's no reason to use a class Repository without an Model
// to access the database... That class share methods like create,
// read, update and delete, and the methods validate and transaction
// too because uses the trait InternalResponse.
User
UserRepositoryInterface.php
// the interface for UserRepository class
UserRepository.php
// that class extend Repository and uses the UserModel
Traits
InternalResponse.php
// trait with methods like validate and transaction. the method
// validate, read and validate the data receveid for the methods
// create and update. and all the CRUD methods uses the method
// transaction to perform the data to the database and return a
// response of that action.
这就是我之前所说的,就像我之前说过的那样,我不知道在参考存储库模式时它是否正确百分之百。
我希望这也可以帮助别人。 谢谢大家。