如何在 CakePHP 中重构更好的模型函数?
我正在阅读编程最佳实践,据说在创建函数时我们应该让它只执行一项特定任务。
我得到了检索数据及其相关数据的模型函数。示例:
$this->Student->StudentAssignments();
目前,此函数检索学生的作业以及每个作业的问题和有关学生的数据。我都用它们。我的困境是,如果我尝试创建单独的函数来检索相关数据(学生和问题数据),那么这会很费力,因为我要对数据库进行更多调用。
你们有什么建议?
I'm reading programming best practices and it is said that when creating a function we should make it do a only single specific task.
I got model functions that retrieves data and it's related data. Example:
$this->Student->StudentAssignments();
Currently this function retrieves the student's assignments plus the question for each assignment and data about the student. I use them all. My dilemma is if I try to make separate functions that retrieves the related data (student and question datas) it's taxing since I'm producing more calls to the DB.
What would you guys suggest?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在进行这种重构时要记住一些事情......
我的模型中通常会有一个 Model->getSomethingAndSomethingElse 函数。
这些函数是公共的,旨在替代从控制器执行复杂(或任何)查找调用。
我通常会做的是在模型中构建一小部分私有函数。
在你的情况下,我可能有一些类似的东西...
Student->getStudentAssigmentsWithQuestions
然后调用一些私有函数,即
Student->getStudent 可能会调用 Student->joinStudentAssignment ,而后者可能会调用Assignment->joinAssignmentQuestion 等双
下划线前缀已被删除,因为 markdown 想要将它们加粗。如果您使用 php5,只要您使用“private”或“proteced”关键字,下划线就并不重要。
基本上,我使用公共方法作为模型中一组非常具体的查询构建或关联构建私有函数的容器。这使我能够拥有一个返回复杂数据的 api,但我可以从小块构建查询或结果集(取决于数据类型、涉及的关系或查询复杂性)——理想情况下,这些小块可以用于多种目的和用途一个公共函数调用。
Something to keep in mind when doing this sort of refactoring...
I typically will have a Model->getSomethingAndSomethingElse functions in my models.
These functions are public and meant to be called as a substitute for doing complicated (or any) find calls from the Controller.
What I will usually do is then build up a small collection of private functions in the model.
In your case I might have something along the lines of...
Student->getStudentAssigmentsWithQuestions
that then calls some private functions i.e.
Student->getStudent which might call Student->joinStudentAssignment which in turn might call Assignment->joinAssignmentQuestion etc.
The double underscore prefixes have been removed since markdown wants to bold things because of them. If you are using php5 the underscores aren't really important anyways as long as you use the "private" or "proteced" keywords.
Basically I use the public method as a container for a group of very specific query building or association building private functions within the models. This allows me to have an api that has complex data returned, but I build the query or the result set (depending on the type of data, relationships involved or query complexity) from small pieces - that can ideally be purposed and used in more than one public function call.
我认为你做得很好。但您应该重新考虑将您的函数重命名为
Or 任何您认为合适的名称。我认为应该尝试尽可能少地调用数据库(我假设您正在其中的某个位置执行联接),而不是通过特定方法获取每组元素。这可能导致您将获得更多方法(因此必须编写更多测试),但我认为这是正确的方法。
为了捍卫设计论点:
您的方法只执行一项任务;它获取学生的作业以及每个作业的问题。
I think you're doing fine. But you should reconsider renaming your function to
Or whatever you think fit. I think one should try to do as few calls to the database as possible (I assume you're performing a join somewhere in there), instead of fetching each set of elements by specific methods. This can lead to the fact that you'll get more methods (and therefore have to write some more tests), but I think this is the right way to do it.
To defend the design argument:
Your method does just one single task; it fetches student's assignments with each assignment's questions.
不,如果您严格关注代码重构,您应该将该 blob 分解为更简单的函数,按照您所说的执行单个任务。是的,您会访问更多的数据库,但考虑到在 cakephp 中使用缓存是多么容易,性能不应该成为问题。如果是,那么您此时不必担心代码重构。
No, if you're strictly concerned about code refactoring you should break down that blob into simpler functions that perform a single task as you said. Yes, you will hit more your database but considering how easy is to work with caching in cakephp, performance should not be an issue. And if it is, then you shouldn't worry about code refactoring at this point.