【代码设计】Java 用注解简洁明了的标注数据筛选特性
基础设计
默认值:仅包含正常状态数据,例如账户:不包含离职账户的正常账户 即为 deletedData = false, wantsEnabled = true, wantsDisabled = false
场景举例:
- 场景一:正常的只展示正常的账户,则为默认的情况
- 场景二:只搜索不正常的已经删除的账户,则与上一条完全相反,则为 wantsEnabled = false, wantsDisabled = true
- 场景三:不考虑状态的查询,无限制查询,则所有的值都是为true,可以使用 @Record
基础注解
@interface Restriction {
/**
* 该接口是否返回 deleted的数据
*/
boolean deleted() default false;
/**
* 该接口是否筛选了状态为正常的数据
*/
boolean enabled() default true;
/**
* 该接口是否筛选了状态为非正常的数据
*/
boolean disabled() default false;
}
场景注解
@Restriction(deleted = true, enabled = false, disabled = true)
@interface Deleted {
}
@Restriction(deleted = false, enabled = true, disabled = false)
@interface Visible {
}
@Restriction(deleted = false, enabled = true, disabled = true)
@interface NonDeleted {
}
@Restriction(deleted = true, disabled = true)
@interface Record {
}
进阶设计
注解+枚举
枚举对应值,注解是枚举的容器,且支持混合策略,支持向后扩展
public enum PolicyType {
RECORD, NON_DELETED, DELETED, VISIBLE
}
public @interface Policy {
PolicyType[] value() default PolicyType.VISIBLE;
}
使用方法
方法一(推荐):
@Policy(PolicyType.NON_DELETED)
public User queryByUserName(String userName) ;
方法二:
@Restriction.NonDeleted
public User queryByUserName(String userName) ;
方法三:
@Restriction(deleted = false, enabled = true, disabled = true)
public User queryByUserName(String userName) ;
- 可读性:方法一 >= 方法二 > 方法三
- 简洁性:方法二 > 方法一 > 方法三
- 原子性:方法一 > 方法二 > 方法三
- 扩展性:方法一 >= 方法二 >= 方法三
- 精确性:方法三 > 方法一 >= 方法二
- 灵活性:方法三 > 方法一 >= 方法二
对比原则
- 原子性:方法一使用了枚举类型,不会被意外修改
- 简洁性:方法二的代码长度最短
单一类实现
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Policy {
Type[] value() default Type.VISIBLE;
@interface DELETED {
Type value() default Type.DELETED;
}
@interface Visible {
Type value() default Type.VISIBLE;
}
@interface NonDeleted{
Type value() default Type.NON_DELETED;
}
@interface Record {
Type value() default Type.UNLIMITED;
}
enum Type {
UNLIMITED, NON_DELETED, NEGATIVE, VISIBLE
}
}
使用方法参考方法二
实际应用
避免复杂的设计,实际上为了一眼看出数据范围,标明清楚即可。
public @interface QueryHint {
Type[] value() default {QueryHint.Type.VISIBLE};
public static enum Type {
UNLIMITED,
NON_DELETED,
DELETED,
ENABLED,
VISIBLE;
private Type() {
}
}
public @interface Deleted {
Type value() default QueryHint.Type.DELETED;
}
public @interface NonDeleted {
Type value() default QueryHint.Type.NON_DELETED;
}
public @interface Record {
Type value() default QueryHint.Type.UNLIMITED;
}
public @interface Visible {
Type value() default QueryHint.Type.VISIBLE;
}
}