The use of action classes in Laravel program architecture design

Source: Internet
Author: User
This article mainly introduces to you about the Laravel program architecture design ideas of the use of the relevant data, the text through the sample code introduced in very detailed, to everyone's study or work has a certain reference learning value, the need for friends below with the small series to learn together

Objective

When we talk about the architecture of the application, we often ask a classic question: "Where should this code be better?" Because Laravel is a fairly flexible framework, it's not that easy to answer this question. Should I write my business logic on the Model layer, the Controller layer, or somewhere else?

When your application has only one access point, it is possible to write the business logic on the Controller layer. But the more common scenario now is that there are many access points to call the same function modules.

For example, too many applications have the ability to register a user, and the process is to call a controller and then return a successful or failed view of the registration. If the application has a mobile side, it is likely to provide a set of APIs for mobile user registration because it needs to return the data format JSON. It is also common to use Laravel's artisan commands to create users, especially in the early stages of the project.

The above two pieces of code may look fine, but as the business logic increases, the code becomes redundant. For example, if you need a new user after the registration, to increase the ability to send email notifications to users, you have to add the above two controllers to send the message code. But if you want to keep the code simple and elegant, we can write these business logic somewhere else.

For the "Where to write business logic code" question, you go to any forum to get a universal answer, that is, "use a service layer, and then invoke the class at the controller layer." Yes, yes, the question is, how should we design the service class? is to create a UserService class to implement all the business logic related to the user's user, and then inject this class into the Controller layer that needs to be used? Or are there other options?

Avoid the Pit of God

First, you can try to create a single class for a particular model that contains all the code. For example:

It looks perfect: we can declare or use the Create/delete method in any controller and get the results we want. But what is the problem with this implementation? That is, we often use a single model rarely in the process of solving problems.

For example, when we create an account for a user, we also need to create a separate blog for the user. If we implement this process in the current way, we must create a Blogservice class and then inject its dependencies into the UserService class.

Obviously, as the business of the application grows, there will be dozens of to hundreds of service classes, some of which need to rely on 5 to 6 other service classes, and the end result is that the code is redundant and chaotic, and this situation is something we want to avoid at all costs.

Introduction to Single Action class

So, if we don't add a few methods to a single service class, we decide to divide it into several classes? Here are my recent projects have adopted the method, the results are very good, recommend to everyone.

First, let's discard overly vague and vague service terms to see our new action classes and define what they are and what they can do.

    • An action class, there should be a name that can explain its function, such as: Createorder, Confirmcheckout, Deleteproduct, Addproducttocart and so on.

    • It should have and have only one public method, as an API. Ideally, it should be the same method name, like handle () or execute (). This is handy if you need to implement some kind of adapter pattern for our action class.

    • It must be agnostic about requests and responses. It does not process the request, nor does it send a response. Such duties should be borne by the Controller.

    • It can depend on other action classes.

    • If anything prevents it from executing and/or returning the desired value, it must enforce the relevant business logic by throwing a Exception, and let the caller (or Laravel's Exceptionhandler) assume responsibility for rendering/responding to the exception.

Create our CreateUser action class

Now, let's take a look at the previous example and refactor it with a single action class, and we'll name it CreateUser.

You might want to know why the method throws an exception when the email address is already occupied. Is this not a request for verification to guarantee? Of course. However, isn't it better to execute business logic inside an action class? This makes logic easier to understand and debug.

Let's look at the controller code after using our action class, as follows:


Now, no matter what modifications we make, the user registration process is handled by the API and Web version, elegantly and neatly.

Nesting of Action classes

If we need an action class to import 1000 users into our app. We can write an action class and continue to use the CreateUser class above:


Very neat, isn't it? We can reuse the CreateUser code by embedding it in the Collection::map () method, and then return the collection of all new users. When the message is occupied, we can either return the Null Object or record it in the log file, which you should have thought of.

Decoration of the Action class

Now, let's say we want to record each new registered user in the log. We can write the code inside the action class, or we can use decorator mode.

We can then use the Laravel IoC container to bind the Logcreateuser class to the CreateUser class, all of which are injected whenever we need an instance of the latter:

appserviceprovider.php

This makes it easier to use configuration or environment variables to control the activation or deactivation of logging features:


appserviceprovider.php

Summarize

Using this method seems to require a lot of classes. Of course, user registration is just a simple example, designed to keep the code short and clear. Once the complexity of the project begins to grow, the real value of the action class becomes more apparent as you clearly know where the code is and what it is defining.

Benefits of using the single action class:

    • A small, single logical domain prevents code duplication and increases the reusability of code and remains stable.

    • Easy independent testing for a variety of scenarios.

    • Meaningful naming is easier to read in large projects.

    • Easy to decorate.

    • Consistency throughout the project: Prevent code distribution in Controllers, Models, etc.

Of course, this approach is based on some of my experience with Laravel over the past few years and my practice in some projects. It's really useful for me, and I'm even using it in some small and medium-sized projects.

If you have a different approach, I am very much looking forward to reading it.

The above is the whole content of this article, I hope that everyone's learning has helped, more relevant content please pay attention to topic.alibabacloud.com!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.