background
Suppose we want to develop a function of creating super club members. The conditions for creation are:
- The id requirements of members are [1-10]
- The phone number should start with 185
- The registration date cannot be less than May 15
Usually we would write this:
copypublic void creatSupperClubMember(Member member) { //1. Verify member id //2. Check the phone number //3. Verify the registration date //4. Create super club members }
In the above method, we found that in addition to the creation of super members, more than half of our code is checking parameters. The problem is that the code we really need is 4. To some extent, 1, 2 and 3 are redundant code.
If our verification is very complex, this method will be difficult to read. Through analysis, we find that this method actually does two things
- Calibration parameters
- Create super member
Therefore, we refactor the code as follows:
copypublic void creatSupperClubMember(Member member) { //1. Parameter verification validatorBeforeCreate() //2. Create super club members } public void validatorBeforeCreate() { //1. Verify member id //2. Check the phone number //3. Verify the registration date }
This will make our code clearer. In fact, when writing methods, we need to consider the principle of single responsibility. The parameter verification of business belongs to non business code to some extent. The above functions can be abstracted as follows:

check
Yes, business logic and non business logic. Is there any way to decouple business logic from non business logic.
We can use annotation verification.
In fact, in our usual development, we use annotation verification in many places:

I believe everyone has written the above code. We don't need to write parameter verification in the method. We use annotation on the field to realize the required verification and range verification of parameters.
However, the existing annotations can not meet our requirements, and the actual parameter verification is more complex. So I decided to write a parameter verification annotation myself.
Annotation model
What I want is
copy@ValidatorHandler(validators = XXXXValidator.class) public int createXXX(XXX xxx) { }
We add a @ ValidatorHandler annotation to the business code we write. The XXXXValidator class in the annotation is the class that really writes the verification function, and the business parameters will be transferred to this verification class.
copypublic class XXXValidator extends AbstractValidator { @Override public void check(Object o) { //Get parameters XXXx xxx = (XXX)o; //Related business verification } }
The verification class model is shown above.

annotation
We separate the business code from the verification code through annotations.
Write verification notes
First, let's define the annotation:
copy@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ValidatorHandler { /** * Checked class */ Class<?> validators(); }
In terms of the function and method of this annotation, the parameter validators is the class of the verification class.
Then write and implement the function of verifying annotations

In order to show the code clearly, I use pictures.
The above code realizes several functions:
"Instantiate the validation class corresponding to validators" Get the business parameters and pass them to the parameters of the check method in the check class Execute the check method in the check class Execute business code "
In order to standardize the writing of verification classes, we need to define an interface
copypublic interface AbstractValidator { void check(Object o); }
All validation classes must implement AbstractValidator and implement the check method.
In the annotation implementation function here, I only get the first parameter in the business function, that is, the first parameter of our business method will be verified. You can think about this: if there are multiple parameters of the business function, how to write the function class of the annotation?
Code test
After the above comments have been developed, we begin to test the following functions:
First, we write a verification class:

As shown in the figure above, in the verification class, we have implemented the three verification functions required at the beginning of the article.
Then we write business code and create super club members
copy@ValidatorHandler(validators = MemberValidator.class) public void creatSupperClubMember(Member member) { System.out.println("member Start adding"); //Here is our business code System.out.println("member End of addition"); }
Let's write another method to simulate the incoming data from the front end:

The test method is as follows:
copy@Test public void testCreateMember() { Member member = initData(); testMemberService.creatSupperClubMember(member); System.out.println("End of creation"); }
Verification id
copyprivate Member initData() { Member member = new Member(); member.setId("11"); member.setMobile("17790990033"); member.setCreateBy("Miss Li"); member.setCreateDate(new Date()); member.setIsActive("Y"); return member; }
Execute the test method and find that the console prints as follows. We find that id = 11 does not meet the requirements and the verification is successful.

We modify id = 5, and the verification of ID passes.
copymember.setId("5");
Verify phone number moblie
Then we execute it again and find that the mobile phone number does not start with 185, and the verification here is also successful.

If the mobile phone number is changed to 185, the verification is passed.
copymember.setMobile("18590990033");
Verification registration date
Among the parameters of member, the registration date is 2021-05-15, which is less than 2021-05-20, which does not meet the requirements.
copyprivate Member initData() { String registerDateStr = "2021-05-15"; Date registerDate = DateUtil.parse(registerDateStr); Member member = new Member(); member.setId("5"); member.setMobile("18590990033"); member.setCreateBy("Miss Li"); member.setCreateDate(registerDate); member.setIsActive("Y"); return member; }
The following errors will appear on the console, and the verification is successful.

Check all pass
copyprivate Member initData() { Member member = new Member(); member.setId("5"); member.setMobile("18590990033"); member.setCreateBy("Miss Li"); member.setCreateDate(new Date()); member.setIsActive("Y"); return member; }
When all our parameters meet the business verification requirements, our verification passes, and a super club member will be created.

The above is the whole content of this article. When our business logic verification is very complex, we can use the verification annotation above to separate the verification logic from the business logic, which is conducive to the decoupling of business and non business, and also meets the single responsibility principle of the design principle. In addition to being easy to read, another advantage is that when we don't need verification, we can comment out the verification annotation on the business method, so we don't have to modify it in the business code, so as to reduce the risk of bug s caused by modifying the business code.
If the article is useful to you, you are welcome to like it and forward it 😀.