ue 属性
@Retention(RetentionPolicy.RUNTIME)
public @interface Unique {
Class scope() default Unique.class;
}
演化架构和紧急设计: 利用可重用代码,第2部分 - 捕捉惯用模式(6)
时间:2011-08-18 IBM Neal Ford
Unique 属性实现类扩展了 清单 6 中所示的 Validator 抽象类。如清单 10 所示:
清单 10. 惟一验证程序实现
public class UniqueValidator extends Validator{
@Override
protected void validateMethod(Object obj, Method method, Annotation annotation) {
Unique unique = (Unique) annotation;
try {
Method scopeMethod = obj.getClass().getMethod("get" +
unique.scope().getSimpleName());
Object scopeObj = scopeMethod.invoke(obj, new Object[0]);
Method collectionMethod = scopeObj.getClass().getMethod(
"get" + obj.getClass().getSimpleName() + "s");
List collection = (List)collectionMethod.invoke(scopeObj, new Object [0]);
Object returnValue = method.invoke(obj, new Object[0]);
for(Object otherObj: collection){
Object otherReturnValue = otherObj.getClass().
getMethod(method.getName()).invoke(otherObj, new Object[0]);
if (!otherObj.equals(obj) && otherReturnValue.equals (returnValue))
throw new ValidationException(method.getName() + " on " +
obj.getClass().getSimpleName() + " should be unique but is not since");
}
} catch (Exception e) {
System.out.println(e.getMessage());
throw new ValidationException(e.getMessage());
}
}
@Override
protected Class getAnnotationType() {
return Unique.class;
}
}
该类必须执行相当数量的工作来确保一个国家名的值是惟一的,不过它也展示了属性在 Java 编程中 的强大功能。
属性是 Java 语言中备受青睐的一部分。您可以通过它们精确地定义有较广影响而在目标类中有较少 语法残留的行为。但是,与 JRuby 等 JVM 上更具表达性的语言相比,它们所做的工作仍然很有限。
使用 JRuby 的 sticky 属性
Ruby 语言也有属性(不过它们不像 “属性” 一样有特定名称 — 它们是 Ruby 提供的其中一种元程 序设计方法)。这里有一个例子。请看清单 11 中的测试类:
清单 11. 测试一个复杂的运算
class TestCalculator < Test::Unit::TestCase
def test_complex_calculation
assert_equal(4, Calculator.new.complex_calculation)
end
end
演化架构和紧急设计: 利用可重用代码,第2部分 - 捕捉惯用模式(7)
时间:2011-08-18 IBM Neal Ford
如果 complex_calculation 方法运行时间较长,您只想在执行验收测试时运行它,而不想在单元测试 期间运行它。进行该限制的一种方式见清单 12:
清单 12. 限制测试范围
class TestCalculator < Test::Unit::TestCase
if ENV[''BUILD''] == ''ACCEPTANCE''
def test_complex_calculation
assert_equal(4, Calculator.new.complex_calculation)
end
end
end
这是与测试相关的一种技术惯用模式,我可在多个上下文中轻松预见该测试的有用性。在一个 if 块 中包装方法声明为我的代码增加了复杂度,因为并非所有方法 |