preface
Most of those who do java development may have read Alibaba's Java background development manual, which contains some contents about Java background development specifications, basically covering some general and universal specifications, but most of them are concise. This paper will mainly use more cases to explain some specifications and supplement them in combination with their own experience!
Other types of specifications
[Java background development specification] - not simple naming
[Java background development specification] - log output
Long function
I know that many companies have certain requirements for the number of lines of a method, such as no more than 50 lines or even 20 lines. I don't think such a hard requirement of no separation and integration is reasonable. We should find out what problems long functions will bring? Starting from the problem, check the number of lines of the method. Sometimes 10 lines may not be well written. Sometimes even 50 lines are OK. For example, there are many methods with more than 50 lines in the source code of spring and MyBatis.
In fact, most of the reasons for creating growth functions are insufficient encapsulation and design, resulting in poor maintainability of the code. There is no encapsulation of repetitive logic. Just like looking at the code of C language, it faces the process and completes the whole business logic in a straightforward manner.
A few lines of code do not necessarily mean no problem
public static void longMethod(String userId, BigDecimal price) { // Judge whether the user is a VIP User user = userDao.getUserByUserId(userId); int memberAttr = user.getUserMemberAttr(); double discountPrice; // 20% off for VIP users and 10% off for other users if (memberAttr == 1) { discountPrice;= price.multiply(new BigDecimal(8)).doubleValue(); } else { discountPrice = price.multiply(new BigDecimal(9)).doubleValue(); } }
Abstract general logic
// Get user member attributes according to user ID private static int getUserMemberAttr(String userId) { User user = userDao.getUserByUserId(userId); return user.getUserMemberAttr(); }
// Calculate discount price according to member attributes private static double getDiscountPrice(int memberAttr, BigDecimal price) { double discountPrice; if (memberAttr == 1) { discountPrice = price.multiply(new BigDecimal(8)).doubleValue(); } else { discountPrice = price.multiply(new BigDecimal(9)).doubleValue(); } return discountPrice; }
Finally, the specific business logic should be like this
public static void longMethod(String userId, BigDecimal price) { // Get user member properties int memberAttr = getUserMemberAttr(userId); // Get discount price according to member attributes double discountPrice = getDiscountPrice(memberAttr, price); }
The reason why many methods are longer is that they are not made by the same person, which means that the code written by predecessors do not understand logic and business, dare not move at will, and can only continue to stack functions.
American Boy Scouts a simple rule: make the camp cleaner than when you came.
Long parameter list
This specification is very similar to long functions, and it is generally stipulated in this way. For example, there can be no more than 5 parameters. The reason is the same. Too many parameters are not conducive to code maintenance and are prone to errors. It is not easy for others to understand when reading.
A very simple example
@Data @Builder class Order { private String orderId; private BigDecimal amount; private String orderChannel; } @Data @Builder class User { private String userName; private String userId; private String userAccount; private String phone; private String address; }
Long parameter list method
public static void longParam(String userName, String userId, String userAccount, String phone, String address) { User user = new User(); user.setUserName(userName); user.setUserId(userId); user.setUserAccount(userAccount); user.setPhone(phone); user.setAddress(address); // ... }
Can be encapsulated into objects for use
public static void longParam(User user) { // ... }
Long parameter list of mixed types
public static void longParam(String userAccount, String userName, String orderId, BigDecimal amount, String orderChannel) { }
Encapsulated into a mixed type object
@Data class RequestParam{ private String userAccount; private String userName; private String orderId; private BigDecimal amount; private String orderChannel; }
Take them out one by one during use
public static void longParam(RequestParam requestParam){ User user = new User(); user.setUserAccount(requestParam.getUserAccount()); user.setUserName(requestParam.getUserName()); Order order = new Order(); order.setOrderId(requestParam.getOrderId()); order.setOrderChannel(requestParam.getOrderChannel()); order.setAmount(requestParam.getAmount()); }
If you feel uncomfortable, of course, you can optimize it, such as the following:
Encapsulate RequestParam with a method to build Order and User objects respectively.
@Data class RequestParam { private String userAccount; private String userName; private String orderId; private BigDecimal amount; private String orderChannel; public Order newOrder() { return Order.builder() .amount(amount) .orderChannel(orderChannel) .orderId(orderId) .build(); } public User newUser() { return User.builder() .userAccount(userAccount) .userName(userName) .build(); } }
It can be used like this
public static void longParam(RequestParam requestParam){ User user = requestParam.newUser(); Order order = requestParam.newOrder(); }
Another very important reason for encapsulating multiple parameters into objects is that it can effectively improve the compatibility of methods. When a method is exposed as an interface, once a new parameter is added or deleted, if it is not encapsulated into an object, the caller must change it, but if it is encapsulated into an object, Then the old remote caller probably doesn't need to make any changes.