悠然乱弹:从几个方法的重构讲开去--注解相关的处理

简介:

有时候它们的处理没有关联性,有些时候,它们的处理又是有关联性的。

我们用伪代码来示意一下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (includeAnnotation(testClass,Abc. class )){
   doSomething...
}
 
if (includeAnnotation(testClass,Abc. class )){
   for (Field field:testClass.getFields){
     if (includeAnnotation(testField,AbcField. class )){
      dosomething...
    }
   }
   for (Method method:testClass.getMethods){
     if (includeAnnotation(testMethod,AbcMethod. class )){
      dosomething...
    }
   }
}
你会发现所有的注解过程处理都是上面几种情况。

有的时候,我们可能在类名的处理上还有一些规则,比如:....Service,.....Action,.....View等等,我们的某些注解只可以加在某种类名规则之下,这个时候,判定就又会增加。我们的程序员就不停的在写这些重复,但是却不可缺少的内容。有没有办法让开发人员只写doSomething的内容就好呢??

只要问题可以提得出来,办法总是有的:

可以定义下面的三个类,开发人员只要编写process函数体中的内容就好了。

?
1
2
3
4
5
6
7
8
9
public interface AnnotationClassAction {
     <T> void process(Class<T> clazz, Annotation annotation);
}
public interface AnnotationMethodAction {
     <T> void process(Class<T> clazz, Method method, Annotation annotation);
}
public interface AnnotationPropertyAction{
     <T> void process(Class<T> clazz, Field field, Annotation annotation);
}

这对于开发人员来说当然是再熟悉不过的了。

但是总要让上面的逻辑有所体现才是,否则不是就执行错位置了??

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
< annotation-class-matchers >
     < annotation-class-matcher class-name = ".*\.annotation\.Annotation.*"
         annotation-type = ".*Test" >
         < processor-beans >
             < processor-bean enable = "true" name = "classAction" >
             </ processor-bean >
         </ processor-beans >
         < annotation-method-matchers >
             < annotation-method-matcher method-name = "method.*"
                 annotation-type = ".*Test" >
                 < processor-beans >
                     < processor-bean enable = "true" name = "methodAction" >
                     </ processor-bean >
                 </ processor-beans >
             </ annotation-method-matcher >
         </ annotation-method-matchers >
         < annotation-property-matchers >
             < annotation-property-matcher
                 property-name = "field.*" annotation-type = ".*Test" >
                 < processor-beans >
                     < processor-bean enable = "true" name = "propertyAction" >
                     </ processor-bean >
                 </ processor-beans >
             </ annotation-property-matcher >
         </ annotation-property-matchers >
     </ annotation-class-matcher >
</ annotation-class-matchers >

上面的演示了一个 示例,看起来比较复杂,其实是因为配置的内容为了充分说明,所以看起来有点复杂,实际应用情况不一定要全配的。我给翻译一下:

?
1
2
3
4
5
首先进行注解类的匹配,匹配的类名是*.annotation.Annotation.*,上面加的注解名是*Test,如果匹配呢,就执行classAction处理器。
 
如果类名匹配,则再进行方法匹配,方法名必须是method*格式的,上面加的注解是*Test类型的注解,匹配成功呢就执行methodAction处理器。
 
如果类名匹配,再进行属性匹配,属性名必须为field*格式,上面的注解格式是*Test类型,如果匹配呢就执行propertyAction处理器。

这样是不是简单了,把所有的匹配工作都通过配置的方式进行实现,开发人员只需要做逻辑处理的部分。

比如下面这样子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class AnnotationClassActionDemo implements AnnotationClassAction {
     public <T> void process(Class<T> clazz, Annotation annotation) {
         System.out.println( "className:" + clazz.getName() + " annotation类型:"
                 + annotation.annotationType().getName());
     }
}
 
public class AnnotationMethodActionDemo implements AnnotationMethodAction {
     public <T> void process(Class<T> clazz, Method method,
             Annotation annotation) {
         System.out.println( "className:" +clazz.getName()+ " annotation类型:" +annotation.annotationType().getName()+ " method名称:" +method.getName());     
     }
}
 
public class AnnotationPropertyActionDemo implements
         AnnotationPropertyAction {
 
     public <T> void process(Class<T> clazz, Field field, Annotation annotation) {
         System.out.println( "className:" + clazz.getName() + " annotation类型:"
                 + annotation.annotationType().getName() + " field名称:"
                 + field.getName());
     }
}
针对下面的类:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Test (id= 0 ,description= "class" )
@XStreamAlias ( "sd" )
public class AnnotationDemo1 {
     @Test (id= 1 ,description= "field1" )
     private String field1;
     @Test (id= 2 ,description= "field2" )
     private String field2;
     @Test (id= 3 ,description= "method1" )
     public void method1(){
         System.out.println( "method1" );
     }
     @Test (id= 4 ,description= "method2" )
     public void method2(){
         System.out.println( "method2" );
     }
     public String getField1() {
         return field1;
     }
     public void setField1(String field1) {
         this .field1 = field1;
     }
     public String getField2() {
         return field2;
     }
     public void setField2(String field2) {
         this .field2 = field2;
     }
}

进行处理,可以看到正确的处理结果。

?
1
2
3
4
5
className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test
className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test field名称:field1
className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test field名称:field2
className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test method名称:method1
className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test method名称:method2

通过上面的的重构,我们可以看到,把开发人员从重复的劳动中解脱出来,而且由于其只处理逻辑部分的内容即可,也避免了一些不必要的逻辑错误引入。

当然,采用配置还是编码的方式配置匹配规则,这个是公说公有理,婆说婆有理,其实两者都支持不就可以了??

总之,通过上面的重构,对编程人员开发注解方面有更大的便捷。

通过文件处理及注解处理的重构,我们看到代码编写及实现确实是优雅了,

解决了代码重复、圈复杂度大、扩展方面的问题,但是性能方面的问题其实是还没有解决的。

相关文章
|
5月前
|
IDE Java 编译器
JAVA注解,你的代码需要的一次“心灵按摩”!
【6月更文挑战第29天】Java注解是提升代码可维护性的关键,它们是编译器和IDE理解代码意图的特殊标记,不同于仅作解释的注释。注解可用于编译时检查(如@Override、@NotNull)、自动生成代码(Lombok的@Getter、@Setter)、框架集成(Spring的@Autowired、MyBatis的@Mapper)。通过注解,代码变得更简洁、功能更强大,为项目带来效率提升。尝试使用注解,赋予代码新生命!
40 12
|
6月前
|
存储 算法 程序员
代码之韵:编程中的诗意与逻辑
在数字的世界里,每一行代码都如同诗句般细腻而富有节奏感。本文将探讨编程不仅仅是一门科学或技术,更是一种艺术形式,它融合了逻辑思维的严谨和创造力的灵动。我们将通过分析编程的核心概念,如变量、控制结构、函数等,来揭示它们背后的美学原则和哲学思考。同时,我们还将讨论如何在日常的编程实践中寻找和创造美感,以及这种美感如何影响我们的工作效率和产品的用户体验。
|
6月前
|
设计模式 Java 开发者
避免重复代码的灾难:Java设计模式的救赎之路
【4月更文挑战第7天】设计模式是解决编程问题的模板,提供整洁、可扩展的代码结构。如单例模式确保唯一实例,工厂方法模式实现对象创建的标准化。其他模式如抽象工厂、建造者、原型、适配器、观察者等,分别用于生成相关对象、复杂对象构建、接口兼容、消息传递等场景。掌握设计模式能提升代码质量,使开发更高效,是Java开发者必备技能。
36 0
|
设计模式 SQL Java
有点狠有点猛,我用责任链模式重构了业务代码
文章开篇,抛出一个老生常谈的问题,学习设计模式有什么作用? 设计模式主要是为了应对代码的复杂性,让其满足开闭原则,提高代码的扩展性 另外,学习的设计模式 一定要在业务代码中落实,只有理论没有真正实施,是无法真正掌握并且灵活运用设计模式的 这篇文章主要说 责任链设计模式,认识此模式是在读 Mybatis 源码时, Interceptor 拦截器主要使用的就是责任链,当时读过后就留下了很深的印象(内心 OS:还能这样玩)
MyBatis这样用,同事直呼哇塞,堪称最佳实践
MyBatis是一款非常流行的ORM框架,相信很多小伙伴都在使用。我们经常会把它和MyBatis-Plus或者MBG一起使用,用多了之后对于其一些常规操作就不太熟悉了。最近总结了下MyBatis的实用用法和技巧,希望对大家有所帮助!
|
Python
一日一技:你的代码是如何被炫技毁掉的
一日一技:你的代码是如何被炫技毁掉的
105 0
|
设计模式 移动开发 安全
与其硬啃“屎山”代码,不如用这六步有条不紊实现代码重构 李慧文
对大规模系统进行重构,如果一个人对着又臭又长的代码硬刚,即使花了大量的时间进行手工验证,最后仍然会有很多问题,特别是一些深路径及特殊场景下的问题。其实,大规模的系统级别重构时是有方法的。我们采访了 Thoughtworks 数字化转型与运营 资深咨询师黄俊彬(QCon+案例研习社讲师),请他来分享 MV*模式重构演进的方法和经验。
571 0
与其硬啃“屎山”代码,不如用这六步有条不紊实现代码重构 李慧文
|
设计模式 缓存 NoSQL
专治不会看源码的毛病--spring源码解析AOP篇
总结一下要形成的习惯:   1>有空时隔一段时间要做几道算法题,C语言和JAVA都可以,主要是训练思维。 2>定期阅读spring的源码。因为spring是框架,重设计,能够培养大局观。   3>阅读底层的书籍,如linux方面,虚拟机方面,这是内功。越高级的语言只是招式。   4>不要忘记做了一半的东西,如搜索引擎方面,redis方面,可以过一段时间再做,因为到时候自己的境界有提升,深入程度也会有所增加。      下面是今天的正题。我也很菜,看源码也很费力,所以都会从最容易的入手。先了解其原理,再去看源码。看源码看熟了,以后再遇到问题,就可以通过源码去了解原理了。
专治不会看源码的毛病--spring源码解析AOP篇
|
设计模式 Java
最全工厂设计模式案例详解,不服来辩!(二)
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,今天我们一起来彻底解析一下它。
最全工厂设计模式案例详解,不服来辩!(二)
|
设计模式 Java
最全工厂设计模式案例详解,不服来辩!
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,今天我们一起来彻底解析一下它。
最全工厂设计模式案例详解,不服来辩!
下一篇
无影云桌面