装饰图案
实际上,我建议
ArrayList使用记录良好的
Decorator
模式包装。您只需
ArrayList用另一个
List实现来包装您的方法,该实现委派大多数方法,但添加验证逻辑:
public class ValidatingListDecorator extends AbstractList<MyBusinessObject>{ private final List<MyBusinessObject> target; public ValidatingListDecorator(List<MyBusinessObject> target) { this.target = target; } @Override public MyBusinessObject set(int index, MyBusinessObject element) { validate(element); return target.set(index, element); } @Override public boolean add(MyBusinessObject o) { validate(o); return target.add(o); } //few more to implement}优点:
- 您仍然可以根据需要访问原始列表,而无需验证(但是您可以限制它)
- 轻松堆叠不同的验证,可以有选择地打开和关闭它们。
- 如 @helios 所述,促进对继承的 合成
- 提高可测试性
- 不需要将您绑定到特定的
List
实现上,您可以向Hibernate支持的持久性列表linkedList
或Hibernate支持的持久性列表中添加验证。您甚至可以考虑使用通用Collection
装饰器来验证任何集合。
实施说明
尽管实施记得有相当多的方法,你必须要记住,同时覆盖:
add(),
addAll(),
set(),
subList()(?),等等。
此外,您的对象必须是不可变的,否则用户可以添加/设置有效对象,然后对其进行修改以违反合同。
好的OO设计
最后我写了:
validate(element)
但请考虑:
element.validate()
这是一个更好的设计。
堆叠验证
如前所述,如果要堆叠验证,在单个单独的类中验证每个属性/认识,请考虑以下惯用法:
public abstract class ValidatingListDecorator extends AbstractList<MyBusinessObject>{ private final List<MyBusinessObject> target; public ValidatingListDecorator(List<MyBusinessObject> target) { this.target = target; } @Override public MyBusinessObject set(int index, MyBusinessObject element) { validate(element); return target.set(index, element); } protected abstract void validate(MyBusinessObject element);}…以及一些实现:
class FooValidatingDecorator extends ValidatingListDecorator { public FooValidatingDecorator(List<MyBusinessObject> target) { super(target); } @Override protected void validate(MyBusinessObject element) { //throw if "foo" not met }}class BarValidatingDecorator extends ValidatingListDecorator { public BarValidatingDecorator(List<MyBusinessObject> target) { super(target); } @Override protected void validate(MyBusinessObject element) { //throw if "bar" not met }}是否只想验证 foo ?
List<MyBusinessObject> list = new FooValidatingDecorator(rawArrayList);
要同时验证 foo 和 bar 吗?
List<MyBusinessObject> list = new BarValidatingDecorator(new FooValidatingDecorator(rawArrayList));



