例如,C中的表单数据在做完验证后,如何传递给M层?
目前采用的是在Action中就把数据组装成对应的领域对象,然后通过传参的方式给制定的model~
但是这样做的话无疑把复杂的组装过程交给了action的开发人员,这样做会使得分层之间的职责划分不够合理,c和m层的人员都需要去了解领域对象的相关接口。
另外,model做完业务后的反馈数据如何回传给action,尤其是多条数据返回,简单的返回一个数组总觉得不够优雅,导致两层之间的依赖过强,不利于开发~
有没有好的解决方案?
例如,C中的表单数据在做完验证后,如何传递给M层?
目前采用的是在Action中就把数据组装成对应的领域对象,然后通过传参的方式给制定的model~
但是这样做的话无疑把复杂的组装过程交给了action的开发人员,这样做会使得分层之间的职责划分不够合理,c和m层的人员都需要去了解领域对象的相关接口。
另外,model做完业务后的反馈数据如何回传给action,尤其是多条数据返回,简单的返回一个数组总觉得不够优雅,导致两层之间的依赖过强,不利于开发~
有没有好的解决方案?
关于数据结构,我的建议是,PHP代码,拒绝数据对象。PHP最牛的,或者说最具有优势的数据结构就是数组,所以传递数组不是不优雅,这就是PHP的最佳实践。
关于MVC之间的传递,我的建议是各层只把自己了解的数据以数组形式传递给其它层,接收数据的时候,做一次可用性验证,拼装成自己需要的数据结构(最好也是数组)。
你的问题我也纠结过,目前我的解决办法是这样的:
<code>/** * 创建新主题 * @return string */ public function actionNew() { if (Yii::$app->user->isGuest) { Yii::$app->user->loginRequired(); } $form = new TopicForm(); $form->author_id = Yii::$app->user->getId(); $form->ip_address = Yii::$app->request->getUserIP(); if ($form->load($_POST) && $form->validate()) { Services::getTopics()->create($form->getAttributes(), $form->content); $this->redirect(['/forum']); } return $this->render('new', [ 'model' => $form ]); } </code>
这段代码是基于Yii2的,作用是在社区发一个新贴。
我的做法是用model(实际上我写的名字是form,因为Yii2的form其实就是model)来收集提交上来的表单数据,然后进行验证
<code>$form = new TopicForm(); $form->author_id = Yii::$app->user->getId(); $form->ip_address = Yii::$app->request->getUserIP(); </code>
验证通过后会使用相应的服务将数据写入数据
<code>Services::getTopics()->create($form->getAttributes(), $form->content); </code>
已知这样做的好处是form基本可以重用,因为他不涉及其他东西,只是验证数据合法性,所以不管是web、api,我都能直接使用他。
Services同理,不管别的,拿到数据就往数据库写(当然复杂的还要在内部处理,这里不说),同样也能复用。
不过这种做法有个问题,就是你需要同时了解 Form 跟 Services 的功能,而Yii2默认的做法是你不需要了解他们,一个典型的Yii2从表单到数据库的代码是这样的:
<code>public function actionCreate() { $model = new User(); if ($model->load($_POST) && $model->save()) { $this->redirect(['index']); } return $this->render('create', ['model' => $model]); } </code>
看出来了吗?人家压根就不分层,你根本不用关心其他的,把数据load进去就好了,至于怎么验证,怎么存储,都是黑箱在操作,开发速度大大提升,但是代码耦合略高,比如web注册用户跟app上注册用户的情景可能是不同的(当然,Yii2提供了scenario机制,一定程度上可以避免这个问题)