MVC(Laravel)在哪里添加逻辑 [英] MVC (Laravel) where to add logic

查看:129
本文介绍了MVC(Laravel)在哪里添加逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设每当我进行CRUD操作或者以特定的方式修改关系,我也想做别的事情。例如,每当有人发布一篇文章时,我也想保存一些表格进行分析。也许不是最好的例子,但总的来说有很多这样的分组功能。



通常我看到这种类型的逻辑放在控制器中。这一切都很好,直到你想在许多地方重现这个功能。当您开始进入部分版本时,创建API并生成虚拟内容,这将成为保持DRY的一个问题。



我看过的管理方式是事件,存储库,库和添加到模型。这是我对每个人的理解:



服务:这是大多数人可能会把这段代码的地方。我的主要服务问题是,有时很难在其中找到具体的功能,我觉得他们被人们关注何时使用雄辩的时候会被遗忘。我怎么知道我需要在库中调用方法 publishPost(),当我可以做 $ post-> is_published = 1



我看到这个工作正常的唯一条件是如果你只使用服务(最好让口才从控制器一起无法访问)。



如果您的请求一般遵循您的模型结构,最终似乎只会创建一大堆不必要的文件。



存储库:从我所了解的这个基本上就像一个服务,但是有一个界面,所以你可以在不需要的ORM之间切换。



事件:在某种意义上,我认为这是最优雅的系统,因为你知道你的模型事件总是被称为雄辩的方法,所以你可以像你一样编写你的控制器。我可以看到这些变得凌乱,如果有人有大型项目的例子,使用关键耦合的事件,我想看到它。



使事件成为no-no的最大的事情是,当关系被修改(至少不是很多对多)时,你不能调用它们更新:我相信我喜欢这个解决方案。将会发布。



模型:传统上,我会有执行CRUD的类,并处理关键耦合。这实际上使事情变得容易,因为你知道CRUD +中的所有功能,无论在哪里都要完成。



简单,但在MVC架构中,这通常不是我看到的。在某种意义上,虽然我喜欢这种服务,因为它更容易找到,并且有更少的文件来跟踪。可能会有点混乱。我想听到这种方法的垮台,为什么大多数人似乎没有这样做。



每种方法的优点/缺点是什么?我错过了什么吗?

解决方案

我认为你所呈现的所有模式/架构都非常有用,只要你遵循 SOLID 原则。



对于在哪里添加逻辑我认为参考单一责任原则很重要。此外,我的答案认为你正在从事一个中型/大型项目。如果是某个项目,请忘记这个答案,并将其全部添加到控制器或模型中。



简短的答案是:您(与服务)对您有意义



长的答案:



控制器:控制器有什么责任?当然,你可以将所有的逻辑放在控制器中,但是控制器的责任呢?我不这么认为



对于我来说,控制器必须收到请求并返回数据,这不是放置验证,调用db方法等的地方。



模型:这是添加逻辑的好地方,比如在用户注册或更新帖子的投票数时发送欢迎电子邮件?如果您需要从代码中的另一个地方发送相同的电子邮件怎么办?你创建一个静态方法吗?如果电子邮件需要另一个模型的信息呢?



我认为该模型应该代表一个实体。使用Laravel,我只使用模型类来添加诸如 fillable guarded table 和关系(这是因为我使用存储库模式,否则模型也会有保存 update find ,etc方法)。



存储库(存储库模式) / strong>:一开始我很困惑。而且,像你一样,我以为好吧,我使用MySQL这样做。



然而,我已经平衡了使用存储库模式的优势vs缺点,现在我用它。我认为现在 ,在这一刻,我只需要使用MySQL。但是,如果从现在开始三年,我需要转变为像MongoDB这样的大部分工作。所有这些都以一个额外的接口和一个 $ app-> bind(interface,存储库)为代价。



事件(观察者模式):事件对于任何给定时间可以抛出任何类的事物都是有用的。例如,想想向用户发送通知。
当您需要时,您可以触发事件,以便在您的应用程序的任何类别发送通知。然后,您可以使用类似 UserNotificationEvents 的类,用于处理所有已触发的用户通知事件。



服务:到目前为止,您可以选择向控制器或型号添加逻辑。 对于我来说,在服务中添加逻辑是非常有意义的。让我们来看看,服务是一个很有名气的课程。你可以拥有尽可能多的班级,因为你在这里应该是有意义的。举个例子:不久之前,我开发了一些类似Google表单的内容。



我开始使用 CustomFormService ,最后以 CustomFormService CustomFormRender CustomFieldService CustomFieldRender CustomAnswerService CustomAnswerRender 。为什么?因为这对我来说是有道理的。如果您与团队合作,您应该将您的逻辑放在团队合理的位置。



使用服务vs控制器/模型的优点是您不受单个控制器或单个模型的约束。您可以根据您的应用程序的设计和需要,根据需要创建尽可能多的服务。此外,您可以在任何类别的应用程序中调用服务的优点。



这很长,但我想向您展示如何构建我的应用程序: / p>

  app / 
controllers /
MyCompany /
作曲家/
异常/
模型/
观察者/
消毒剂/
ServiceProviders /
服务/
验证者/
视图
(...)

我为每个文件夹使用特定的功能。例如, Validators 目录包含一个负责处理验证的 BaseValidator 类,基于 $ rules $ messages 的特定验证器(通常每个型号一个)。我可以很容易地把这段代码放在一个服务中,但是对于我来说,即使在服务中使用这个代码也是一个特定的文件夹(对于现在)。



我建议您阅读以下文章,因为他们可能会更好地向您解释:



由Dayle Rees打破模具(CodeBright的作者):这是我把它放在一起的地方,即使我改变了一些东西来满足我的需要。



使用Laravel中的代码解耦存储库和服务 Chris Goosey:这篇文章解释了什么是服务和存储库模式以及它们如何组合在一起。



Laracasts还具有存储库简化单一责任,这是一个很好的资源与实际的例子(即使你必须支付)。


Let's say whenever I do a CRUD operation or modify a relationship in a specific way I also want to do something else. E.g., whenever someone publishes a post I also want to save something to a table for analytics. Maybe not the best example but in general there's a lot of this "grouped" functionality.

Normally I see this type of logic put into controllers. That's all fine an dandy until you want to reproduce this functionality in lots of places. When you start getting into partials, creating an API and generating dummy content it becomes an issue with keeping things DRY.

The ways I've seen to manage this are events, repositories, libraries, and adding to models. Here are my understandings of each:

Services: This is where most people would probably put this code. My main issue with services is that sometimes it's hard to find specific functionality in them and I feel like they get forgotten about when people are focused on using Eloquent. How would I know I need to call a method publishPost() in a library when I can just do $post->is_published = 1?

The only condition I see this working well in is if you ONLY use services (and ideally make Eloquent inaccessible somehow from controllers all together).

Ultimately it seems like this would just create a bunch of extra unnecessary files if your requests generally follow your model structure.

Repositories: From what I understand this is basically like a service but there's an interface so you can switch between ORMs, which I don't need.

Events: I see this as the most elegant system in a sense because you know your model events are always going to be called on Eloquent methods, so you can write your controllers like you normally would. I can see these getting messy though and if anyone has examples of large projects using events for critical coupling I'd like to see it.

The biggest thing that makes events a no-no is that you can't call them when relationships are modified (at least not many-to-many) UPDATE: I believe I fond a solution to this. Will post soon.

Models: Traditionally I'd have classes that performed CRUD and also handled critical coupling. This actually made things easy because you knew all functionality around CRUD + whatever had to be done with it was there.

Simple, but in MVC architecture this isn't normally what I see done. In a sense though I prefer this over services since it's a bit easier to find, and there are less files to keep track of. It can get a bit disorganized though. I'd like to hear downfalls to this method and why most people don't seem to do it.

What are the advantages / disadvantages of each method? Am I missing something?

解决方案

I think all patterns / architectures that you present are very useful as long as you follow the SOLID principles.

For the where to add logic I think that it's important to refer to the Single Responsibility Principle. Also, my answer considers that you are working on a medium / large project. If it's a throw-something-on-a-page project, forget this answer and add it all to controllers or models.

The short answer is: Where it makes sense to you (with services).

The long answer:

Controllers: What is the responsibility of Controllers? Sure, you can put all your logic in a controller, but is that the controller's responsibility? I don't think so.

For me, the controller must receive a request and return data and this is not the place to put validations, call db methods, etc..

Models: Is this a good place to add logic like sending an welcome email when a user registers or update the vote count of a post? What if you need to send the same email from another place in your code? Do you create a static method? What if that emails needs information from another model?

I think the model should represent an entity. With Laravel, I only use the model class to add things like fillable, guarded, table and the relations (this is because I use the Repository Pattern, otherwise the model would also have the save, update, find, etc methods).

Repositories (Repository Pattern): At the beginning I was very confused by this. And, like you, I thought "well, I use MySQL and thats that.".

However, I have balanced the pros vs cons of using the Repository Pattern and now I use it. I think that now, at this very moment, I will only need to use MySQL. But, if three years from now I need to change to something like MongoDB most of the work is done. All at the expense of one extra interface and a $app->bind(«interface», «repository»).

Events (Observer Pattern): Events are useful for things that can be thrown at any class any given time. Think, for instance, of sending notifications to a user. When you need, you fire the event to send a notification at any class of your application. Then, you can have a class like UserNotificationEvents that handles all of your fired events for user notifications.

Services: Until now, you have the choice to add logic to controllers or models. For me, it makes all sense to add the logic within Services. Let's face it, Services is a fancy name for classes. And you can have as many classes as it makes sense to you within your aplication.

Take this example: A short while ago, I developed something like the Google Forms. I started with a CustomFormService and ended up with CustomFormService, CustomFormRender, CustomFieldService, CustomFieldRender, CustomAnswerService and CustomAnswerRender. Why? Because it made sense to me. If you work with a team, you should put your logic where it makes sense to the team.

The advantage of using Services vs Controllers / Models is that you are not constrained by a single Controller or a single Model. You can create as many services as needed based on the design and needs of your application. Add to that the advantage of calling a Service within any class of your application.

This goes long, but I would like to show you how I have structured my application:

app/
    controllers/
    MyCompany/
        Composers/
        Exceptions/
        Models/
        Observers/
        Sanitizers/
        ServiceProviders/
        Services/
        Validators/
    views
    (...)

I use each folder for a specific function. For example the Validators directory contains a BaseValidator class responsible for processing the validation, based on the $rules and $messages of specific validators (usually one for each model). I could as easily put this code within a Service, but it makes sense to me to have a specific folder for this even if it is only used within the service (for now).

I recommend you to read the following articles, as they might explain things a little better to you:

Breaking the Mold by Dayle Rees (author of CodeBright): This is where I put it all together, even though I changed a few things to fit my needs.

Decoupling your code in Laravel using Repositories and Services by Chris Goosey: This post explains well what is a Service and the Repository Pattern and how they fit together.

Laracasts also have the Repositories Simplified and Single Responsibility which are good resources with practical examples (even though you have to pay).

这篇关于MVC(Laravel)在哪里添加逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆