preface

As one of the new features of Java8, the functional interface, like Stream, can make Java code more concise and elegant. This article will take the code of the project as an example to explain how to use the functional interface to rewrite the new and modified verification code about role management, post management, parameter management, etc. This article provides an idea of how to use functional programming to optimize code in daily life. If there are any mistakes, please discuss them together.

Logical combing

Before the formal transformation, we first sort out the verification logic in the new and modified. Taking parameter management as an example, the key name of the parameter will be verified when the new or modified:

The verification logic is relatively simple. You only need to query the database based on the parameter key name. If the query result is found, the system displays a message indicating that the parameter key name already exists and cannot be added.

If you need to modify an existing parameter record, the verification logic of the key name becomes the need to exclude the current modified parameter record in the query, and then query whether the parameter name exists in the rest of the record, if the use of pure SQL statement query, you need to use! =, and if according to the project is not directly used! =, but directly according to the parameters of the key names in the database query a record can be modified (not to the records, you may be sure), and then the parameters of the query to the record of code level id and modify the parameters of the current record the id of the comparison, if the same, is the key parameter of records using only the current parameters, can be modified. If they are different, it indicates that the current key name has been used by another parameter record, and cannot be changed. Avoid the use of large amount of data! The efficiency of =.

While in if in accordance with the project, further to add and modify the parameters in the key name check simplified consolidation, with a variable stores the current new or modified record id, if it is due to the new id does not exist, the assignment of 1 (normal record id not to 1), so you can ensure that the new and modified the uniqueness of judgment. If no record is found based on the key name, the key name can be used. If the record is found and the change logic is the same as above, -1 indicates that the parameter key name has been used because the id of the record must be different from that of the queried record. In this way, the uniqueness check of the new and modified parameters can be used in a unified way.

Attached is the verification code of parameter key name of the project as follows:

public String checkConfigKeyUnique(SysConfig config) {
    // Get the id of the current new or modified record. The id of the new record is always -1 because there is an ID when the new record is transferred
    Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId();
    // Query parameter records by key name
    SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey());
    // If a record is queried and its ID is the same as that of the newly added or modified record, the execution parameter key is unavailable
    if(StringUtils.isNotNull(info) && info.getConfigId().longValue() ! = configId.longValue()) {return UserConstants.NOT_UNIQUE;
    }
    // If there is no record of the specified parameter key name, it can be used
    return UserConstants.UNIQUE;
}
Copy the code

Business extract

Just like the parameter key name in parameter management, the uniqueness check of a certain field also exists in role management and post management. These uniqueness checks are unified logic except that the parameters passed during the check are different from the SQL table of the underlying query:

  1. Of the current added or modified recordid.
  2. Query records based on field conditions.
  3. Check whether the query result is null andidDoes the uniqueness check and returns the result.

Use functional interfaces for transformation

We will first show the method extracted according to the business. For ease of understanding, the overall code logic still refers to the code logic of the code:

public static <E> String checkFieldUnique(E entity, Function
       
         getIdFun, UnaryOperator
        
          checkFieldUniqueFun)
        
       ,> {
    Long id = StringUtils.isNull(getIdFun.apply(entity)) ? -1L : getIdFun.apply(entity);
    E e = checkFieldUniqueFun.apply(entity);
    if(StringUtils.isNotNull(e) && getIdFun.apply(e).longValue() ! = id.longValue()) {return UserConstants.NOT_UNIQUE;
    }
    return UserConstants.UNIQUE;
}
Copy the code

Here are three more arguments to this method:

  1. E entity

    This is easier to understand because by using generics, you can easily handle different entity types.

  2. Function<E, Long> getIdFun

    SysConfig::getConfigId (Long); SysConfig::getConfigId (Long); This can be thought of as passing a reference to the getConfigId method of the SysConfig class to checkFieldUnique, so that the method can be called as needed within the method content. This can be thought of as passing one function as an argument to another function, like the following:

    // A deliberate example is used here, just to make it easier to understand method references in Java
    const getNumArr = () = > [1.2.3.4.5.6.7]
    const getStrArr = () = > ['A'.'B'.'C'.'D']
    ​
    const printArr = getArrFun= > {
        const arr = getArrFun()
        for (let item of arr) {
            process.stdout.write(`${item} `)}console.log()
    }
    ​
    printArr(getNumArr)  // 1 2 3 4 5 6 7
    printArr(getStrArr)  // A B C D
    Copy the code

    Can also be thought of as a c function pointer:

    #include <stdio.h>int sum(int a, int b) 
    {
        printf("%d + %d = %d", a, b, a + b);
    }
    ​
    void demo(int(*fun)(int.int), int a, int b) {
        fun(a, b);
    }
    ​
    int main(a)
    {
       
       demo(sum, 1.2);  // 1 + 2 = 3
       
       return 0;
    }
    Copy the code
  3. UnaryOperator<E> checkFieldUniqueFun

    UnaryOperator

    is a function that takes E(the entity type) and returns E(the entity type). Can see the calibration field and uniqueness of only one function parameters of type String fields, but there is need to pass the whole entity class, the reason for this transformation, is to facilitate some cases may need to be performed according to the multiple fields of entity the uniqueness of field calibration, for example, if in accordance with the department of management is need to pass two fields:

    /** * Verify that the department name is unique **@paramDeptName Department name *@paramParentId ID of the parent department *@returnResults the * /
    public SysDept checkDeptNameUnique(@Param("deptName") String deptName, @Param("parentId") Long parentId);
    Copy the code

The actual transformation

The following is to transform the department management code to show the final effect. First, transform the unique parameter of the verification field to the entity type:

/** * Verify that the department name is unique **@paramDept Department *@returnResults the * /
public SysDept checkDeptNameUnique(SysDept dept);
Copy the code

Then modify the internal code of the method that validates the department name, where the checkFieldUnique method is the functional interface method extracted above:

public String checkDeptNameUnique(SysDept dept) {
    return checkFieldUnique(dept, SysDept::getDeptId, deptMapper::checkDeptNameUnique);
}
Copy the code

Then test it:

You can see that the code works so that when you add or modify an entity and need a unique check on a field of the entity, you simply call checkFieldUnique instead of having to write the same check logic over and over again.

conclusion

In this paper, a simple modification if calibration code explained according to the uniqueness of functional programming in practical application in actual open, in fact, a lot of times, we can find there are many same overall logic in the code, but the sector method calls a different code, then can consider to use functional interface methods for extraction, simplify the code.