• DDD Series 1: What is an Object-relational mapping ORM? Just plain not writing SQL?
  • DDD series ii: Re-understand object-oriented development, subvert traditional cognition, and break CURD dilemma
  • DDD Series 3: Transforming Procedural Code, Step by step (Step 1)
  • DDD series 3: Domain objects and value objects are confused
  • DDD Repository: DDD Repository and traditional Repository
  • DDD series 5: Polymerization root magic and egg pain
  • DDD series six: no matter how good the design can not afford to toss, software corruption step by step abyss
  • DDD series 7: Reconstructing the 16-character mind method
  • DDD Series 8: CodeReview for errands

DDD series 1: Re-understand object-oriented development, subvert traditional cognition, and break CURD dilemma

Learning from bottom to bottom: ask questions -> analyze problems -> solve problems -> summarize

Demand scenarios

The business requirements

1. Enter the mobile phone number to obtain the SMS verification code; Enter the verification code and click login. 1. Determine whether the mobile phone is registered. If it is not registered, it will be registered. 2. Registration process: Record login time, generate token, and generate nickname through mobile phone numberCopy the code

User table structure

CREATE TABLE `users` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'on the ID',
 `mobile` varchar(11) NOT NULL DEFAULT ' ' COMMENT 'User phone',
 `nickname` varchar(60) NOT NULL DEFAULT ' ' COMMENT 'nickname',
 `token` varchar(255) NOT NULL DEFAULT ' ' COMMENT 'token',
 `login_at` datetime DEFAULT NULL COMMENT 'landing Time'.PRIMARY KEY (`id`),
 UNIQUE KEY `mobile` (`mobile`),
 UNIQUE KEY `token` (`token`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4
Copy the code

Parameter validation is the first implementation

Note: in order to simplify the code, the code is not complete, only show the required code, annotations also go to a lot of complete code, please refer to the source code

public class UserController {
    public Response sendCaptcha(String mobile) {
        // Verify mobile phone number parameters
        isMobile(mobile);
        /** The sending verification code logic omits **/
        return success();
    }
    // Verify the phone number function
    private void isMobile(String mobile) {
        Pattern p = Pattern.compile("^ [1] [3,4,5,6,7,8,9] [0-9] {9} $");
        Matcher m = p.matcher(mobile);
        if(! m.matches()) {throw new Exception("Mobile phone number format is incorrect"); }}} POST request: HTTP:/ / 127.0.0.1 / user/sendCaptcha? mobile=13000000000-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the code analysis, parameter validation functions in the Controller layer; Controller layer responsibilities: Get information from HTTP requests, extract parameters, and distribute them to different processing services; The problem1The Controller layer is overloaded with validation functions because it violates the Controller layer's responsibility. The problem2: New user shipping address Requirements: The user has multiple shipping addresses, the user can add or modify the shipping address, including mobile phone number parameter verification; If implemented this way, AddressController needs to copy the isMobile function, causing code duplication;Copy the code

Duplicate code is a major source of software quality degradation!!

Duplicate code multiplies maintenance costs; Repetitive code that changes in one place and forgets to change in another is full of bugs (such as adding validation rules starting with 12 on your phone number), and it can make your code bloated.

Parameter validation is the second implementation

public class Utils {
    public static void isMobile(String mobile) {
        Pattern p = Pattern.compile("^ [1] [3,4,5,6,7,8,9] [0-9] {9} $");
        Matcher m = p.matcher(mobile);
        if(! m.matches()) {throw new Exception("Mobile phone number format is incorrect"); }}} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class UserController {
    public Response sendCaptcha(String mobile) {
        // Verify mobile phone number parameters
        Utils.isMobile(mobile);
        /** The sending verification code logic omits **/
        return success();
    }
}
POST请求:http:/ / 127.0.0.1 / user/sendCaptcha? mobile=13000000000-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the code analysis: to extract the validation logic, utility class Utils isMobile function realization: Extraction of validation logic into Utils utility class is also common in real development, but the code will appear in a large number of Utils. IsMobile, Utils. IsEmail, a large number of repetitive low quality codeCopy the code

Consider: From an object-oriented perspective, is isMobile an action or behavior of Utils objects?

Parameter validation is the third implementation

public class User {
    private Integer id;
    
    @notnull (message = "SMS verification code cannot be empty ")
    @size (min = 4, Max = 4, message = "SMS verification code can only be four digits ")
    private String captcha;

    @notblank (message = "Mobile phone number cannot be blank ")
    @notnull (message = "Mobile phone number cannot be empty ")
    ^ @ the Pattern (regexp = "[1] [3,4,5,6,7,8,9] [0-9] {9} $", message =" phone number format is not correct ")
    private String mobile;
    
    private String token;
    private String nickname;
    privateLocalDateTime loginAt; } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class UserController {
    public Response sendCaptcha(User user) {
    
       // Only mobile verification is required when sending the verification code. Captcha verification is not required
       The following two lines of code can independently verify the validation annotations for the mobile attribute of the User class
        Validator<User> validator = new Validator<>();
        validator.validateProperty(user, "mobile");
        
        /** The sending verification code logic omits **/
        return success();
    }
}
POST请求:http:/ / 127.0.0.1 / user/sendCaptcha? mobile=13000000000-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the code analysis: The use of annotations to achieve automatic calibration of parameters, is now a more popular way to achieve the user receiving Address requirements, new Address entity, annotation attributes for verificationpublic class Address {
    private Integer id;

    @notnull (message = "SMS verification code cannot be empty ")
    @size (min = 4, Max = 4, message = "SMS verification code can only be four digits ")
    private String captcha;

    @notblank (message = "Mobile phone number cannot be blank ")
    @notnull (message = "Mobile phone number cannot be empty ")
    ^ @ the Pattern (regexp = "[1] [3,4,5,6,7,8,9] [0-9] {9} $", message =" phone number format is not correct ")
    private String mobile;

    private String consignee;
    private String province;
    private String city;
    private String district;
    privateString detail; } Problem: Again, there is a lot of duplicate validation code in annotationsCopy the code

Consider: is the mobile phone number verification logic an action or behavior of the User object or Address object? Where would it fit?

Problem analysis

Object oriented is object centered development method, the object here is the object in the real world, not just build a few classes is object oriented development;

A mobile phone number in the real world is not just a string of numeric characters. It has the area code (86), the length limit (11 digits), the beginning of 1[3,4,5,6,7,8,9], the difference between 4G and 5G, and the difference between carriers. It is a real, living object with its own attributes and behaviors. Did you think about how it would feel to assign its properties and behavior to another object?

The SMS verification code also has its own attributes and behaviors in the real world. The verification code may contain four digits, expiration time, and SMS content. (#### is your login verification code. And so on.

SMS verification code properties: 1. Code value: value 2. Expire time: expire 3. Mobile phone number to be verified: Mobile 4. SMS text content: Content SMS verification code behavior: 1Copy the code

Object – oriented implementation of parameter validation

public class Mobile {

    @notblank (message = "Mobile phone number cannot be blank ")
    @notnull (message = "Mobile phone number cannot be empty ")
    ^ @ the Pattern (regexp = "[1] [3,4,5,6,7,8,9] [0-9] {9} $", message =" phone number format is not correct ")
    private String value;

    public void valid(a) {
        Validator<Mobile> validator = new Validator<>();
        validator.validate(this); }} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class Captcha {

    @notnull (message = "SMS verification code cannot be empty ")
    @size (min = 4, Max = 4, message = "SMS verification code can only be four digits ")
    private String value;

    @Valid
    private Mobile mobile;
    
    private static long expire = 60; // Expiration time
    private String content = "%s is your login verification code, if not myself, please ignore this message.";

    // Generate random four digits
    public void generateValue(a) {
        value = String.valueOf((int)(Math.random() * 9000 + 1000));
    }
    // Generate SMS content
    public void generateContent(a) { content = String.format(content, value); }} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class CaptchaController {
    public Response send(Captcha captcha) {
        // Only mobile verification is required when sending the verification code. Captcha verification is not required
        captcha.getMobile().valid();

        /** The sending verification code logic omits **/
        return success();
    }
}
POST请求:http:/ / 127.0.0.1 / captcha/send? mobile.value=13000000000-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the code analysis:1Create a Mobile entity. The value attribute is the value of the Mobile phone number, annotate the value verification rule, and the Mobile entity has its own self-verification function VALID2Create a Captcha entity. The Captcha entity contains Mobile entities to form nested objects.3, independent CaptchaController, using Captcha mapping request parameters, call the self-verification function VALID of the Mobile attribute in the Captcha instance to verify whether the parameters are correct4Note the POST request parameter: mobile. Value =13000000000
5, the user needs the delivery Address, create the Address entity, including the Mobile entity, form a nested object;public class Address {
    private Integer id;
    
    @Valid
    private Mobile mobile;

    private String consignee;
    private String province;
    private String city;
    private String district;
    private String detail;
}
Copy the code

Login function parameter verification code implementation

public class UserController {
    public Response login(@Valid Captcha captcha, User user) {

        user = /** The sending verification code logic omits **/;
        return success(user);
    }
}
POST请求:http:/ / 127.0.0.1 / user/login? value=1234&mobile.value=13000000000-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the code analysis:1, the use of@ValidNote Verify the SMS verification code and mobile phone number simultaneously2, notice the request parameter: value=1234&mobile.value=13000000000Value: SMS verification code Mobile. Value: mobile phone numberCopy the code

conclusion

First, the verification logic is encapsulated in their own entities. There are entities responsible for the verification logic, which will not be scattered around the project code. When the verification logic changes, it is enough to find the corresponding entity to modify, which is the high cohesion of the code.

Second, through the nested combination of different entities can achieve a variety of verification requirements, which greatly enhances the reusability of the code, which is the low coupling of the code

Send SMS verification code code implementation

public class CaptchaController {
    CaptchaService captchaService;
    public Response send(Captcha captcha) {
        captchaService.send(captcha);
        returnsuccess(); }} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class CaptchaService {
    // Object oriented
    public void send(Captcha captcha) {
        // Generate random four digits
        captcha.generateValue();
        // Generate SMS content
        captcha.generateContent();
        // Send SMS messages
        sendSMS(captcha);
        / / store
        save(captcha);
    }
    
    // Process oriented or function point oriented
    public void send(Captcha captcha) {
        // Generate random four digits
        String code = String.valueOf((int)(Math.random() * 9000 + 1000));
        // Generate SMS content
        content = String.format(captcha.getContent(), code);
        // Send SMS messages
        sms.send(captcha.getMobile().getValue(), content);
        / / storerepository.save(captcha); }} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class Captcha {
    private String value;
    private Mobile mobile;
    
    private static long expire = 60; // Expiration time
    private String content = "%s is your login verification code, if not myself, please ignore this message.";
    
    private void generateValue(a) {
        value = String.valueOf((int)(Math.random() * 9000 + 1000));
    }
    private void generateContent(a) { content = String.format(content, value); }} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the code analysis: please understand object-oriented and procedural code implementation differencesCopy the code

Before the popularity of object orientation, the dominant development approach was “function oriented”, specifically, to grasp the function of the target system as a whole, break it down into smaller parts by stage. When writing software using a feature-oriented development approach, when specifications change or features are added, the scope of the changes becomes extensive and the software is difficult to reuse.

Object oriented technology is to make the maintenance and reuse of software easier, its basic idea is to focus on each component, improve the independence of components, components together, to achieve the overall function of the system. By improving the independence of the component, it minimizes the scope of impact when changes occur and can be reused in other systems. From how Object Orientation Works

How to understand the above paragraph of text, feel said quite right, but read again is equal to white see, or to illustrate by example

New requirement: Added the description of validity period in SMS content, "%s is your login verification code, please fill in within %s minutes, if not operated by myself, please ignore this SMS."Copy the code

Analysis of the implementation process of new requirements: One, for the realization of the function point send function, it is a whole, if you want to modify the logic, the first step is to read through the entire send function code, clarify the context of business rules, and then dare to change the code, now only a few lines of code, if it is a complex function point, controlled lines of code, read again and clarify the rules, It takes a lot of effort, that is, the code is not readable, low maintainability;

The generateContent function of the Captcha component requires expire and Content attributes. This reduces the context of the business logic to be understood. The generateContent function of the Captcha component requires expire and Content attributes. Improved the implementation of new business code efficiency, that is, the code is readable, high maintainability;

Modify the code as follows:public class Captcha {
    private static long expire = 60;
    private String content = "%s is your login verification code, please fill in within %s minutes, if not by myself, please ignore this message.";
   
    private void generateContent(a) {
        long minute = expire / 60; content = String.format(content, value, minute); }}Copy the code

Code testability is also an important evaluation criterion of code quality

Analysis of test process: 1. The send function implemented for function points is an integral and indivisible function, which can only be tested for the whole function. At the same time, the function also relies on the SMS sending service of the third party and the storage service of the warehouse layer, which makes the unit test particularly difficult to write, and this is the poor testability of the code.

Second, object-oriented send function, it is easy to achieve Captcha generateValue, generateContent function unit test, this is the code testability;

Note: SMS sending service and warehouse storage service belong to the hardware layer, and the unit test mainly focuses on the test of business logic rulesCopy the code

User login function code implementation

public class Nickname {
    private String value;
    public void generate(String mobile) {
        StringBuilder sb = new StringBuilder(mobile);
        value = sb.replace(3.8."* * * * *").toString(); }} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class Token {
    private String value;
    public void generate(String val) { val += LocalDateTime.now().toString(); value = DigestUtils.md5DigestAsHex(val.getBytes()); }} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class User {
    private Integer id;
    private Mobile mobile = new Mobile();
    private Token token = new Token();
    private Nickname nickname = new Nickname();
    private LocalDateTime loginAt;

    public void reLogin(a) {
        // Update the login time
        loginAt = LocalDateTime.now();
        // Regenerate the token
        token.generate(mobile.getValue());
    }

    public void register(a) {
        // Update the login time
        loginAt = LocalDateTime.now();
        / / token is generated
        token.generate(mobile.getValue());
        // Generate a nicknamenickname.generate(mobile.getValue()); }} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class UserService {
    UserRepository repository;
    public User loginOrRegister(User user) {
        // Whether the mobile phone number is registered
        User u = repository.findByMobile(user.getMobile());
        if(u ! =null) {
            u.reLogin(); // Re-log in
            save(u);
            return u;
        }
        
        user.register(); // New user registration
        save(user);
        returnuser; } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --public class UserController {
    UserService userService;
    public Response login(@Valid Captcha captcha, User user) {
        user = userService.loginOrRegister(user);
        return success(user);
    }
}
POST请求:http:/ / 127.0.0.1 / user/login? value=1234&mobile.value=13000000000-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the code analysis:1, User nested Mobile, Nickname, and Token entities2, focusing on the realization method and process of User entity reLogin and RegisterCopy the code

conclusion

Attributes of the object changes are caused by the concrete behavior of the real world, users to log in to landing time and the change of the token, and encapsulate the behavior of the method of the object, through these object method, different behavioral requirements can be achieved in the real world, such as reLogin and register the implementation of the process; Be careful that methods are small enough that each method does only one thing. Only methods are small enough that they can be combined into more and more complex methods to implement diverse business requirements. This is also the meaning of single responsibility, which applies not only to classes, but also to class methods.

The essence of object orientation is divide and conquer, and the premise of realizing branch idea is that component shielding internal complexity, low coupling between components, if not based on low coupling, exposing the complex relationship between internal errors to the upper layer, it will cause the correlation between components, reduce the independence of components, resulting in components difficult to reuse.

Sometimes methods written in OOP are only a few or even one line long. Not all methods need to be this small, but in the case of OOP, the upper limit for a method should be 20 or 30 lines. From how Object Orientation Works

Afterword.

Entity methods are pure memory operations that return no value and are stateless

GenerateValue, Captcha. GenerateContent, User.relogin, and User.register entity functions do not return values. Object methods operate on the properties of the object according to the business logic. If there is a return value, you need to consider whether the function is applicable to the correct scenario;

Note: Stateful refers to problems with dependencies, data storage, etc. Stateless is the opposite

Consider whether each attribute should be implemented as an entity, such as adding the User name attribute name, nested in the User entity name entity;

There are some examples of this in real development, such as the id attribute is a separate ID entity, which is too cumbersome and too academic; Reference standard: Mobile, Token, and Nickname entities

Myth: Object-oriented features are “encapsulation”, “polymorphism” and “inheritance”

How Object Orientation Works explicitly defines classes, polymorphism, and inheritance as programming constructs: Classes, polymorphism, and inheritance should be explicitly defined as constructs that improve software maintainability and reusability. Classes are used to aggregate variables and subroutines to create highly independent artifacts; Polymorphism and inheritance are used to eliminate duplicate code and create general-purpose artifacts.

Distinguish between business processes and business rules: Business rules have if/else, business processes do not!

If there is a branch statement that indicates that there is a logical judgment based on the business rule, the logical judgment should be written in the corresponding object method.

Note: Business processes are not absolutely if/else free, as explained below.

Service responsibilities:1, business process2, creation and destruction of entity objects (live and die)public class CaptchaService {
    public void send(Captcha captcha) {

        // Generate captcha information (step 1 of the business process)
        captcha.generate();
        // Send SMS (step 2 of the business process)
        sendSMS(captcha);
        // Destruction of entity objectssave(captcha); }}public class UserService extends BaseService<User> {
    UserRepository repository;
    public User loginOrRegister(User user) {

        // Whether the mobile phone number is registered
        User u = repository.findByMobile(user.getMobile()); // Create an entity object

        // If is a precondition of the business process.
        // The logical processing of reLogin and register services is not affected.
        if(u ! =null) {
            // Re-log in
            u.reLogin();

            // Destruction of entity objects
            save(u); 
            return u;
        }
        // New user registration
        user.register();
        // Destruction of entity objects
        save(user); 

        returnuser; }} Controller is responsible for service choreography:public class UserController extends BaseController {

    UserService userService;
    CaptchaService captchaService;

    public Response login(@Valid Captcha captcha, User user) {
        // Controller usage: Get the information from the HTTP request, extract the parameters, and distribute them to different processing services
        // Check whether the verification code is correct (call CaptchaService)
        captchaService.check(captcha);
        // User login or registration (calling UserService)
        user = userService.loginOrRegister(user);

        returnsuccess(user); }}Copy the code

Entity method is the operation of the concrete logic of entity attributes, which is commonly known as adding, deleting and modifying

Queries are different representations of data that are not included in entity methods and are implemented directly in the Service layer by invoking the Dao layer

Blood loss, anemia, hyperemia and distension

In the anaemic model, entities contain atomic domain logic that does not depend on persistence, while composition logic is in the Service layer. In the congestion model, most of the business logic should be placed in the entity, including the persistence logic, while the Service layer is a very thin layer, which only encapsulates transactions and a small amount of logic, and does not deal with the DAO layer.

Note: The code in this article is anaemic model

Automatically generate models for each language version

Parameter problems: 1, each language version of the model automatically concatenated to generate URL parameter string, such as PHP http_build_query 2, model directly converted to JSON, JSON as a parameter, server JSON mapping to model

The topic outside