1. Formal parameters of encapsulation method
When there are too many method parameters, it is necessary to encapsulate an object
2. Encapsulate business logic
A method can write thousands of lines of code, and there are no rules at all... Often the person in charge will say that this business is too complicated and there is no way to improve it. In fact, this is an excuse for being lazy. No matter how complex the business is, we can use reasonable design and packaging to improve code readability.
3. The correct way to judge whether the collection type is not empty
CollectionUtils.isEmpty(list)
4. Do not return null for collection type return value
Collections.emptyList();
5. Try not to use basic types for the properties of the mapping database
For example, mybatis returns a null value, and the default value of the packaging type is null
6. Encapsulation Judgment Conditions
if (a || b || c) multi-judgment conditions are packaged into a judgment method and commented
7. Use @ConfigurationProperties instead of @Value
8. Do not call BMapper in AService
9. Write as few tools as possible
Why do you say that you need to write less tool classes, because most of the tool classes you write are included in the jar package that is invisible, such as String, Assert assertion, IO upload file, copy stream, Bigdecimal and so on. It is easy to make mistakes and load redundant classes by yourself.
10. Do not wrap the return value of the OpenFeign interface
An exception is thrown directly at the service provider, and such a packaged HTTP request is always 200, so retrying and monitoring cannot be done. The interface response status should follow the HTTP real status
11. It is not recommended to make the OpenFeign interface into a jar
I have seen many interfaces that use OpenFeign are used in this way. The OpenFeign interface is written on the service provider and packaged into a jar. For example, when service A calls B, a separate module is opened in project B to write the interface definition, and a jar package is created to let A import dependencies.
Let's feel the steps to call a Feign interface implementation:
- Write Controller implementation in B service
- Define the OpenFeign interface definition in the B service
- Modify the jar version +1 in the B service, and print a jar package to the local warehouse
- Modify the dependent jar version in A service, refresh maven/gradle
At first glance, it doesn't seem troublesome, does it? But we must know that we often lose parameters and lack response attributes in our development. Once there are any small problems, we have to go through the above process again. . . .
It is recommended to define the OpenFeign interface on consumer A, and B only needs to provide an interface implementation. The bad thing is that the XxxRequest and XxxResponse classes are redundant, but there is no problem, because for Feign, the request and response BO classes do not need to have exactly the same fields, and its decoder will intelligently parse them Response and wrap it into your XxxResponse receiving class.
This class XxxRequest, XxxResponse, etc., is just a mapping data structure locally customized by service A to map the request result. This mapping data structure has nothing to do with service B. So of course it should be placed here in A.
The essence of high cohesion and low coupling is to package all the code related to a service (component, application, package, etc.) together, and don’t get involved with the outside world. If you are involved, it will cause dependency when modifying hell.
12. Write meaningful method comments
13. Naming of DTO objects that interact with the front end
What VO, BO, DTO, PO I really don’t think it’s necessary to divide it into such details, at least when we interact with the front-end, the class name should be appropriate, and don’t directly use the class that maps the database to return to the front-end, which will return a lot Unnecessary information, if there is sensitive information, it needs to be handled specially.
The recommended method is to define the class that accepts the front-end request as XxxRequest, and the definition of the response as XxxResponse. Take orders as an example: the entity class that accepts, saves and updates order information can be defined as OrderRequest, the order query response is defined as OrderResponse, and the order query condition request is defined as OrderQueryRequest.
14. Don’t cycle through databases across services
When querying across services, if there is a batch data query scenario, directly write a batch Feign query interface instead of the following
list.foreach(id -> {
UserResponse user = userClient.findById(id);
});
Because every OpenFeign request is an Http request, a database IO operation, and it has to go through various interceptors, decoders, etc. in the framework, all of which are losses.
Directly define a batch query interface
@PostMapping(\"/user/batch-info\")
List<UserResponse> batchInfo(@RequestBody List<Long> userIds);
Is this the end? No, if the number of such userIds is very large, more than 2000, then the implementation side cannot directly use in() to query in the database. The useIds should be split on the implementation side. In the case of an index, in() below 1000 elements is not a big problem.
public List<XxxResponse> list(List<Long> userIds) {
List<List<Long>> partition = Lists.partition(userIds, 500);
List<XxxResponse> list = new ArrayList<>();
partition.forEach(item -> list.addAll(xxxMapper.list(item)));
return list;
}
15. Try not to let IDEA call the police
A warning in the IDEA code window means that the code can still be optimized, or there is a problem.