`

Toggle Annotation实现

 
阅读更多
在上一篇博客中介绍了一个从实际项目中抽取出来的小工具:Toggle(https://github.com/xianlinbox/Toggle), 这儿来记录下其整个实现过程:

Step1: 编写自己的Annotation

Java从1.5版本引入了Annotation, 其从本质上来说不带有任何逻辑,只是可以附着在Package,Class,Method,Field等上面,为这些元素提供很多附加信息。当外部工具在解析这些元素的时候,可以读取到附加的信息,然后添加相应的功能,从而实现了Annotation的功能。

JDK本身自带了几个基础的Annotation:
@Deprecated: 标明某个类或方法不再推荐使用。
@Override: 方法重载了父类的方法
@SuppressWarnings: 忽略指定的警告信息
@Target: 定义的Annotation可以附加在哪些元素上,具体有哪些元素,可以查看JDK的ElementType。
@Retention: 定义的Annotation的作用域,具体有哪些作用域,可以查看JDK的RetentionPolicy 从上面的基础Annotation的解释,
可以看出前三个在JDK中非常常见,后2个是为大家定义自己的Annotation准备的。

定义一个基本的Annotation的基本语法如下:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ToggleDisabled {
}

然后,需要定义该Annotation的member type,即希望在该Annotation上附着哪些信息,在使用Annotation时,有2种方式传递信息给Annotation: * 在Annotation后面直接添加值,eg:
@ToggleEnabled("STAGE1")
@ToggleEnabled({"STAGE1","STAGE2"})

这种情况,在Annotation中可以直接以value()方法即可获得附着的信息,如果想支持多值,则把返回值设为数组,
String[] value();

在Annotation后面添加键值对:
@ToggleEnabled(toggleClass = "example.MyFeatureToggle",toggleNames = {"STAGE1","STAGE2"})

这种方式想要获取键值对的“值”,就需以“键”为名定义一个方法:
String toggleClass();
String[] toggleNames();
在实现该Annotation的时候,原想使用Interface作为Member Type,这样,在为Annotation附着信息的时候,我们就可以有更大的扩展性,只要继承自某接口的类都可以作为该Annotation的值,可是在JLS规定,Annotation的Member Type只支持如下的类型:
* primitive
* String
* Enum
* Class
* 以上四类元素的数组
具体为什么有这样的限制,没找到原因,猜测是因为Annotation的静态特征,要求附着在其上的信息在整个运行过程是不能改变。

因为MemberType的限制,我不得不把该Annotation的用法从直接添加值方式,改为添加键值对的方式。完整的Annotation定义代码非常简单:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ToggleDisabled {
String toggleClass();
String[] toggleNames();
}

Step2: 编写自己的TestRule

前面提到,Annotation的功能就是为元素附着更多的信息而已,如果没有框架来解析这些信息,那么该Annotation基本上也就是废的。这个Annotation的作用是想在跑某个测试之前,能够根据设置设定Feature Toggle的状态,从而能够在一个测试类中测试Toggle On 和Toggle Off的逻辑。

Junit从4.7版本引入了TestRule, 该接口的作用是让开发人员更加方便的控制测试运行的过程,可以使用它重写关于@After,@Before等Annotation的逻辑,从而可以让该部分逻辑可以跨多个类重用。 在Toggle中,实现原理是在运行每个测试之前,读取到Step 1创建的Annotation的信息,然后根据Annotation的信息去设置Feature Toggle的状态,然后在运行测试,运行完测试之后,把Feature Toggle还原到测试之前的状态。因此,首先编写自己的TestRule:
public class ToggleRule implements TestRule {
  @Override
  public Statement apply(final Statement statement, final Description description) {
  }
statement表示即将执行的一个测试动作,Desccription表示即将运行的测试的全部信息,即Annotation的信息也可以从decription中读取出来。
 ToggleEnabled toggleEnabledAnnotation = description.getAnnotation(ToggleEnabled.class);
 ToggleDisabled toggleDisabledAnnotation = description.getAnnotation(ToggleDisabled.class);
然后,需要读取其中的信息,把ToggleEnbled的所有Toggle设置为Status On,ToggleDisabled的所有Toggle设置为Status Off,在修改Toggle的值的时候,需要先把原始的值存储在Map里,后面在还原Feature Toggle状态时需要用到。
if (enabledAnnotation != null) {
  String[] toggleNames = enabledAnnotation.toggleNames();
  String toggleClassName = enabledAnnotation.toggleClass();

  Object[] toggles = getToggleEnumObjects(toggleClassName);
  for (Object toggle : toggles) {
       addToggleIntoMapIfAbsent(originStatusMap, toggle);
      updateToggleStatus(toggleNames, (Toggle) toggle, ToggleStatus.ON);
  }
 }

设置完状态之后,调用statement的evaluate()方法,执行测试,执行完之后,根据之前Map的值,还原Feature Toggle的状态
try {
  statement.evaluate();
} finally {
  rollBackToggleStatusToOrigin(originStatusMap, toggleEnabledAnnotation, toggleDisabledAnnotation);
}
这样,就可以通过在测试类中添加TestRule和Anotation来测试不同Toggle状态下的系统行为了。
分享到:
评论

相关推荐

    jquery css3实现列表toggle特效.zip

    在本项目中,"jquery css3实现列表toggle特效.zip"是一个包含了使用JavaScript库jQuery和CSS3技术来创建交互式列表切换效果的资源包。这个效果主要用于网页设计,它提供了一个直观且动态的方式来控制内容的可见性,...

    LEDTOGGLE_ledtoggle_

    标题 "LEDTOGGLE_ledtoggle_" 暗示我们讨论的主题是关于STM32F411 Nucleo开发板上实现LED灯闪烁的程序。STM32F411 Nucleo是一款基于ARM Cortex-M4内核的微控制器开发板,广泛应用于嵌入式系统设计。"LED TOGGLE"通常...

    Unity3D之Toggle实例

    Toggle是unity中常用的控件之一, 该项目是Unity3D中的Toggle使用事件的方式控制交互方式,简单实用。

    bootstrap-toggle-buttons

    Bootstrap Toggle Buttons正是利用jQuery的事件监听和DOM操作功能来实现按钮的切换效果。 ### Toggle Button功能 Toggle按钮是一种在两种状态间切换的按钮,通常表现为开关或复选形式。在Bootstrap Toggle Buttons...

    S7-200SMART_库文件_翻转输出状态_toggle_单按钮启停功能.rar

    本资源“S7-200SMART_库文件_翻转输出状态_toggle_单按钮启停功能.rar”提供了一种巧妙的方法,通过库指令实现了一个简单的单按钮启停控制逻辑,这对于许多工业应用来说非常实用。 首先,我们需要了解S7-200SMART ...

    Toggle组件踩坑学习笔记.7z

    在Unity引擎中,Toggle组件是UI系统的一部分,用于创建用户界面中的开关或复选框功能。Toggle组件在很多场合都非常实用,例如设置选项、选择开关等。本学习笔记将深入探讨Toggle组件及其相关组件ToggleGroup的一些...

    可作为Web组件的纯CSS切换Toggle按钮

    总结一下,创建纯CSS切换(Toggle)按钮的关键在于理解CSS选择器和伪类的使用,以及如何通过CSS实现状态的切换。通过这种方式,我们可以创建出功能完整且无JavaScript依赖的Web组件。同时,这样的组件也易于维护和...

    Samsung Toggle Mode DDR NAND Specification

    它在NAND闪存的基础上,通过改进的数据传输机制,实现了更快的数据读写速度。 Toggle DDR NAND的主要特点包括: 1. 高速数据传输:与传统的NAND闪存相比,Toggle DDR NAND使用双倍数据速率(DDR)技术,允许在时钟...

    微信小程序实现多个按钮toggle功能的实例

    微信小程序实现多个按钮toggle功能的实例 微信小程序实现多个按钮toggle功能的实例主要是为了解决在小程序中实现多个按钮的toggle功能的问题。下面是实现该功能的步骤和代码解释: 1. 首先,我们需要在数据中添加...

    STM32 Led Toggle

    STM32 Led Toggle STM32 Led Toggle STM32 Led Toggle STM32 Led Toggle

    jquery+css3实现列表toggle特效.zip

    本示例"jquery+css3实现列表toggle特效.zip"是关于如何使用这些技术来实现一个交互式的列表切换效果,这种效果常见于菜单、折叠面板或者显示/隐藏内容的场景。以下是对这个主题的详细说明: 首先,jQuery是一个强大...

    Toggle切换按钮

    在实现自定义Toggle开关时,我们需要考虑以下几个关键步骤: 1. **布局设计**:首先,我们需要设计一个XML布局文件,用于定义Toggle按钮的外观。这可能包括两个状态的背景图片(开启和关闭)以及文字标签等元素。...

    ToggleButtons,符合材料设计文档的android切换按钮。.zip

    ToggleButtons是针对Android平台的一个开源项目,专门设计用于实现符合材料设计规范的切换按钮。材料设计是Google推出的一种设计语言,旨在提供一致、直观且富有表现力的用户体验,而ToggleButtons则是这一设计理念...

    toggle的使用

    总结来说,`toggle()`是jQuery中一个非常有用的工具,它使得在网页上轻松地实现元素的显示和隐藏成为可能,同时还能通过传入函数来实现更复杂的逻辑。无论是在简单的网页交互还是复杂的应用场景中,`toggle()`都是一...

    jquery.toggle-password显示密码插件

    《jQuery Toggle Password插件详解与应用实践》 在Web开发中,用户界面的友好性和安全性是至关重要的。尤其是在涉及用户密码输入的场景下,如何在保证安全的同时提供良好的用户体验,是一个值得探讨的问题。jQuery ...

    Unity UI Toggle学习经典demo,音乐开关设计,背包商城设计

    U3D学习入门到高级,UGUI中Toggle的经典分析,经典demo,看这个demo就能掌握Toggle的经典使用,随心自定义Toggle的使用!

    toggle button

    在Android和iOS开发中,toggle button有各自的实现方式。 在描述中提到的“https://github.com/kyleduo/SwitchButton”是一个GitHub仓库,它由用户kyleduo创建,专门针对Android平台提供了一个自定义的Toggle ...

    Unity单选菜单(ToggleMenu)

    Unity单选菜单(ToggleMenu)

    Toggle Comment 1.5(VS最好的注释代码插件)

    Toggle Comment 1.5(VS最好的注释代码插件), Ctrl+/ 快速进行代码注释,方便好用!

Global site tag (gtag.js) - Google Analytics