Encoding Specification | Java function elegant way (under)

Background above

This article summarizes a set of Java-related function of encoding rules, designed to give the majority of Java programmers some coding suggestions to help you write more elegant, more quality, more efficient code.

Try to use the internal function argument type based

Case I: Try to use internal arguments underlying type

Symptom:

// 调用代码
double price = 5.1D;
int number = 9;
double total = calculate(price, number);

// 计算金额函数
private double calculate(Double price, Integer number) {
    return price * number;
}
复制代码

Proposal:

// 调用代码
double price = 5.1D;
int number = 9;
double total = calculate(price, number);

// 计算金额函数
private double calculate(double price, int number) {
    return price * number;
}
复制代码

Case II: internal function return value to make use of the base type

Symptom:

// 获取订单总额函数
public double getOrderAmount(List<Product> productList) {
    double amount = 0.0D;
    for (Product product : productList) {
        if (Objects.isNull(product) || Objects.isNull(product.getPrice())
            || Objects.isNull(product.getNumber())) {
            continue;
        }
        amount += calculate(product.getPrice(), product.getNumber());
    }
    return amount;
}

// 计算金额函数
private Double calculate(double price, double number) {
    return price * number;
}
复制代码

Proposal:

// 获取订单总额函数
public double getOrderAmount(List<Product> productList) {
    double amount = 0.0D;
    for (Product product : productList) {
        if (Objects.isNull(product) || Objects.isNull(product.getPrice())
            || Objects.isNull(product.getNumber())) {
            continue;
        }
        amount += calculate(product.getPrice(), product.getNumber());
    }
    return amount;
}

// 计算金额函数
private double calculate(double price, double number) {
    return price * number;
}
复制代码

Herein are illustrative of this phenomenon, the better way is to use the programming stream (Stream).

Key Benefits

  • Internal functions make use of the base type, to avoid the implicit type of packing and unpacking the package;
  • Internal function argument type base, using syntax avoid internal parameter functions determined null pointer;
  • Internal function returns the type of base used, with the syntax to avoid the called function returns a null pointer value determination.
  • Try to avoid the return of the array and the list is null

Case a: Avoid returned array is null, the null pointer is determined unnecessary

Symptom:

// 调用代码
UserVO[] users = queryUser();
if (Objects.nonNull(users)) {
    for (UserVO user : users) {
        // 处理用户信息
    }
}

// 查询用户函数
private UserVO[] queryUser() {
    // 查询用户列表
    List<UserDO> userList = userDAO.queryAll();
    if (CollectionUtils.isEmpty(userList)) {
        return null;
    }

    // 转化用户数组
    UserVO[] users = new UserVO[userList.size()];
    for (int i = 0; i < userList.size(); i++) {
        UserDO user = userList.get(i);
        users[i] = new UserVO();
        users[i].setId(user.getId());
        users[i].setName(user.getName());
    }

    // 返回用户数组
    return users;
}
复制代码

Proposal:

// 调用代码
UserVO[] users = queryUser();
for (UserVO user : users) {
    // 处理用户信息
}

// 查询用户函数
private UserVO[] queryUser() {
    // 查询用户列表
    List<UserDO> userList = userDAO.queryAll();
    if (CollectionUtils.isEmpty(userList)) {
        return new UserVO[0];
    }

    // 转化用户数组
    UserVO[] users = new UserVO[userList.size()];
    for (int i = 0; i < userList.size(); i++) {
        UserDO user = userList.get(i);
        users[i] = new UserVO();
        users[i].setId(user.getId());
        users[i].setName(user.getName());
    }

    // 返回用户数组
    return users;
}
复制代码

Case II: to avoid the returned list is null, the null pointer is determined unnecessary

Symptom:

// 调用代码
List<UserVO> userList = queryUser();
if (Objects.nonNull(userList)) {
    for (UserVO user : userList) {
        // 处理用户信息
    }
}

// 查询用户函数
private List<UserVO> queryUser(){
    // 查询用户列表
    List<UserDO> userList = userDAO.queryAll();
    if(CollectionUtils.isEmpty(userList)) {
        return null;
    }

    // 转化用户列表
    List<UserVO> userVoList = new ArrayList<>(userList.size());
    for(UserDO user : userList) {
        UserVO userVo = new UserVO();
        userVo.setId(user.getId());
        userVo.setName(user.getName());
        userVoList.add(userVo);
    }

    // 返回用户列表
    return userVoList;
}
复制代码

Proposal:

// 调用代码
List<UserVO> userList = queryUser();
for (UserVO user : userList) {
   // 处理用户信息
 }

// 查询用户函数
private List<UserVO> queryUser(){
    // 查询用户列表
    List<UserDO> userList = userDAO.queryAll();
    if(CollectionUtils.isEmpty(userList)) {
        return Collections.emptyList();
    }

    // 转化用户列表
    List<UserVO> userVoList = new ArrayList<>(userList.size());
    for(UserDO user : userList) {
        UserVO userVo = new UserVO();
        userVo.setId(user.getId());
        userVo.setName(user.getName());
        userVoList.add(userVo);
    }

    // 返回用户列表
    return userVoList;
}
复制代码

Key Benefits

  • And to ensure that the returned array list is not null, the null pointer is determined to avoid the calling function.

Function arguments passed package

Case I: When an incoming parameters too, should be packaged as a parameter class

Java specification does not allow too many arguments, not easy to maintain is not easy to expand.

Symptom:

// 修改用户函数
public void modifyUser(Long id, String name, String phone, Integer age, 
    Integer sex, String address, String description) {
    // 具体实现逻辑
}
复制代码

Proposal:

// 修改用户函数
public void modifyUser(User user) {
    // 具体实现内容
}

// 用户类
@Getter
@Setter
@ToString
private class User{
    private Long id;
    private String name;
    private String phone;
    private Integer age;
    private Integer sex;
    private String address;
    private String description;
}
复制代码

When an incoming group parameters should be packaged as a parameter class

Since the group parameter occurs, it is necessary to describe a class packaging phenomenon.

Symptom:

// 获取距离函数
public double getDistance(double x1, double y1, double x2, double y2) {
    // 具体实现逻辑
}
复制代码

Proposal:

// 获取距离函数
public double getDistance(Point point1, Point point2) {
    // 具体实现逻辑
}

// 点类
@Getter
@Setter
@ToString
private class Point{
    private double x;
    private double y;
}
复制代码

Key Benefits

  • Excessive packaging function parameters for a class, a function to make easier maintenance and expansion;
  • Function parameter set encapsulated into a class, business concepts make clearer sharper.

Possible alternative implementations of a function anonymous inner classes

Advantages and disadvantages of Java anonymous inner classes: anonymous inner classes (including Lambda expressions) can be directly accessed outside of the class members, including members of the class variable, the function of internal variables. Because free to access external variables, it will lead to code boundary is not clear.

First recommendation to simplify the anonymous inner class with Lambda expressions, followed by the recommended alternative implementation of complex Lambda expressions as functions.

Case I: a possible alternative functions anonymous inner classes (including Lambda expression) is achieved

Symptom:

// 发送结算数据
sendWorkerSettleData(WorkerPushDataType.CHECKER, () -> {
    Date beginDate = DateUtils.addDays(currDate, -aheadDays);
    Date endDate = DateUtils.addDays(currDate, 1);
    return auditTaskDAO.statCheckerSettleData(beginDate, endDate);
});
复制代码

Proposal:

// 发送结算数据
sendWorkerSettleData(WorkerPushDataType.CHECKER, () -> statCheckerSettleData(currDate, aheadDays));

// 统计验收员结算数据函数
private List<WorkerSettleData> statCheckerSettleData(Date currDate, int aheadDays) {
    Date beginDate = DateUtils.addDays(currDate, -aheadDays);
    Date endDate = DateUtils.addDays(currDate, 1);
    return auditTaskDAO.statCheckerSettleData(beginDate, endDate);
}
复制代码

In fact, there is a simpler way. Calculation start date before calling the function sendWorkerSettleData (sending operator billing data), the end date, you can replace the anonymous inner class directly function auditTaskDAO.statCheckerSettleData (beginDate, endDate) implementation.

Case II: split complex anonymous inner class that implements the interface class interface for multiple functions

If the interface between a number of functions implemented anonymous inner classes little relevance, this interface can be split into several interface functions, ease of use Lambda expressions.

Symptom:

// 清除过期数据
cleanExpiredData("用户日志表", new CleanExpiredDataOperator() {
    @Override
    public List<Date> queryExpiredDate(Integer remainDays) {
        return userDAO.queryExpiredDate(remainDays);
    }
    @Override
    public void cleanExpiredData(Date expiredDate) {
        userDAO.cleanExpiredData(expiredDate);
    }
});

// 清除过期数据函数
private void cleanExpiredData(String tableName, CleanExpiredDataOperator ,
cleanExpiredDataOperator) {
    // 功能实现代码
}

// 清除过期操作接口
interface CleanExpiredDataOperator {
    // 查询过期日期
    public List<Date> queryExpiredDate(Integer remainDays);
    // 清除过期数据
    public void cleanExpiredData(Date expiredDate);
}
复制代码

Proposal:

// 清除过期数据
cleanExpiredData("用户日志表", userDAO::queryExpiredDate,userDAO::cleanExpiredData);

// 清除过期数据函数
private void cleanExpiredData(String tableName, QueryExpiredDateOperator queryExpiredDateOperator, CleanExpiredDataOperator cleanExpiredDataOperator) {
    // 功能实现代码
}

// 查询过期日期接口
interface QueryExpiredDateOperator {
    // 查询过期日期
    public List<Date> queryExpiredDate(Integer remainDays);
}

// 清除过期操作接口
interface CleanExpiredDataOperator {
    // 清除过期数据
    public void cleanExpiredData(Date expiredDate);
}
复制代码

Key Benefits

  • Defined functions and parameters are specified, the code clearly defines the boundaries of anonymous inner classes;
  • Lambda expressions to simplify the use of anonymous inner class, make the code more concise.

Return to streamline the use of unnecessary code

Case I: Remove unnecessary if

Symptom:

// 是否通过函数
public boolean isPassed(Double passRate) {
    if (Objects.nonNull(passRate) && passRate.compareTo(PASS_THRESHOLD) >= 0) {
        return true;
    }
    return false;
}
复制代码

Proposal:

// 是否通过函数
public boolean isPassed(Double passRate) {
    return Objects.nonNull(passRate) && passRate.compareTo(PASS_THRESHOLD) >= 0;
}
复制代码

Case two: Remove unnecessary else

Symptom:

// 结算工资函数
public double settleSalary(Long workId, int workDays) {
    // 根据是否合格处理
    if (isQualified(workId)) {
        return settleQualifiedSalary(workDays);
    } else {
        return settleUnqualifiedSalary(workDays);
    }
}
复制代码

Proposal:

// 结算工资函数
public double settleSalary(Long workId, int workDays) {
    // 根据是否合格处理
    if (isQualified(workId)) {
        return settleQualifiedSalary(workDays);
    }
    return settleUnqualifiedSalary(workDays);
}
复制代码

Case 3: Remove unnecessary variables

Symptom:

// 查询用户函数
public List<UserDO> queryUser(Long id, String name) {
    UserQuery userQuery = new UserQuery();
    userQuery.setId(id);
    userQuery.setName(name);
    List<UserDO> userList = userDAO.query(userQuery);
    return userList;
}
复制代码

Proposal:

// 查询用户函数
public List<UserDO> queryUser(Long id, String name) {
    UserQuery userQuery = new UserQuery();
    userQuery.setId(id);
    userQuery.setName(name);
    return userDAO.query(userQuery);
}
复制代码

Key Benefits

  • Streamline unnecessary code, make the code look more refreshing

The use of temporary variables to optimize the code

In some code, often we see a.getB (). GetC () ... getN () the wording, tentatively called "cascade function is called" code readability and robustness bad. Suggestion: put an end to the cascade called function, using the temporary variable split, and make the object null pointer check.

Case I: the use of temporary variables to clarify the logic

Symptom:

// 是否土豪用户函数
private boolean isRichUser(User user) {
    return Objects.nonNull(user.getAccount())
        && Objects.nonNull(user.getAccount().getBalance())
        && user.getAccount().getBalance().compareTo(RICH_THRESHOLD) >= 0;
}
复制代码

This is the code to streamline the control of the favorites, but readability is really bad.

Proposal:

// 是否土豪用户函数
private boolean isRichUser(User user) {
    // 获取用户账户
    UserAccount account = user.getAccount();
    if (Objects.isNull(account)) {
        return false;
    }

    // 获取用户余额
    Double balance = account.getBalance();
    if (Objects.isNull(balance)) {
        return false;
    }

    // 比较用户余额
    return balance.compareTo(RICH_THRESHOLD) >= 0;
}
复制代码

The program, increasing the number of lines of code, but logic clearer. Sometimes, when streamlining and readability of the code conflict, individuals prefer to retain the readability of the code.

Case II: the use of temporary variables to streamline the code

Symptom:

// 构建用户函数
public UserVO buildUser(UserDO user) {
    UserVO vo = new UserVO();
    vo.setId(user.getId());
    vo.setName(user.getName());
    if (Objects.nonNull(user.getAccount())) {
        vo.setBalance(user.getAccount().getBalance());
        vo.setDebt(user.getAccount().getDebt());
    }
    return vo;
}
复制代码

So write about is a temporary variable in order to save it.

Proposal:

// 构建用户函数
public UserVO buildUser1(UserDO user) {
    UserVO vo = new UserVO();
    vo.setId(user.getId());
    vo.setName(user.getName());
    UserAccount account = user.getAccount();
    if (Objects.nonNull(account)) {
        vo.setBalance(account.getBalance());
        vo.setDebt(account.getDebt());
    }
    return vo;
}
复制代码

Key Benefits

  • The use of temporary variables to clarify the logic, business logic seemed clearer;
  • The use of temporary variables to streamline the code to see the variable name and know what justice and less dead code;
  • If you get the function is more complex time-consuming, the use of temporary variables can improve operational efficiency;
  • The use of temporary variables to avoid cascading calling function, which can effectively prevent null pointer exception.

Retaining only the parameters required for the function

In some code, often we see a.getB (). GetC () ... getN () the wording, tentatively called "cascade function is called" code readability and robustness bad. Suggestion: put an end to the cascade called function, using the temporary variable split, and make the object null pointer check.

Case one: Remove the extra parameters

Symptom:

// 修改用户状态函数
private void modifyUserStatus(Long userId, Integer status, String unused) {
    userCache.modifyStatus(userId, status);
    userDAO.modifyStatus(userId, status);
}
复制代码

Which, unused parameters are useless argument.

Proposal:

// 修改用户状态函数
private void modifyUserStatus(Long userId, Integer status) {
    userCache.modifyStatus(userId, status);
    userDAO.modifyStatus(userId, status);
}
复制代码

Case II: The property to replace objects

Symptom:


// 删除用户函数
private void deleteUser(User user) {
    userCache.delete(user.getId());
    userDAO.delete(user.getId());
}
复制代码

Proposal:

// 删除用户函数
private void deleteUser(Long userId) {
    userCache.delete(userId);
    userDAO.delete(userId);
}
复制代码

Proposal:

When calling a function, parameter object does not need to be specially constructed, its properties and function uses more than three, may not necessarily use the rule.

Key Benefits

  • Retaining only parameters required function, defined the parameters to be assigned in the call to avoid the call to go construction Shihai some useless arguments.

postscript

"The more the merrier". If there is more and better view, or will have better code case, welcome to a supplementary explanation. I hope that this article initiate, if eventually form a complete set of Java coding standard, itself a remarkable achievement.

Germany focus on high technology, professional content to find more technical field trips

Guess you like

Origin juejin.im/post/5d511b8af265da03af19c5b5