我应该扩展ArrayList以添加非null的属性吗?

我想将一个对象集合添加到arrayList,只有当特定属性不为null时。

我正在考虑扩展ArrayList并在子类中实现检查。

另一种方法是在将它放入Arraylist之前检查属性,但这意味着,如果我需要根据逻辑将对象添加到arraylist,我必须分散if检查每个位置。

我想知道你对它的想法……再想一想,这是一种矫枉过正吗?

装饰图案

我实际上建议使用记录良好的Decorator模式包装ArrayList 。 您只需将ArrayList与另一个List实现包装在一起,该实现委派大多数方法,但添加了validation逻辑:

 public class ValidatingListDecorator extends AbstractList { private final List target; public ValidatingListDecorator(List 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 } 

优点:

  • 如果需要,您仍然可以访问原始列表而无需validation(但您可以限制此操作)
  • 更容易堆叠不同的validation,有选择地打开和关闭它们。
  • @helios所述,促进组合而不是inheritance
  • 提高可测试性
  • 不会将您绑定到特定的List实现,您可以向LinkedList或Hibernate -backed持久列表添加validation。 您甚至可以考虑使用通用Collection装饰器来validation任何集合。

实施说明

尽管实现了,但是在重写时需要记住很多方法: add()addAll()set()subList() (?)等。

此外,您的对象必须是不可变的,否则用户可以添加/设置有效对象,然后修改它以违反合同。

良好的OO设计

最后我写道:

 validate(element) 

但考虑一下:

 element.validate() 

这是一个更好的设计。

堆叠validation

如前所述,如果要堆叠validation,在单个单独的类中validation每个proprty / apsect,请考虑以下习惯用法:

 public abstract class ValidatingListDecorator extends AbstractList { private final List target; public ValidatingListDecorator(List 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 target) { super(target); } @Override protected void validate(MyBusinessObject element) { //throw if "foo" not met } } class BarValidatingDecorator extends ValidatingListDecorator { public BarValidatingDecorator(List target) { super(target); } @Override protected void validate(MyBusinessObject element) { //throw if "bar" not met } } 

想只validationfoo

 List list = new FooValidatingDecorator(rawArrayList); 

想validationfoobar

 List list = new BarValidatingDecorator(new FooValidatingDecorator(rawArrayList)); 

如果你想强制执行此操作,我不明白为什么不这样做(尽管你应该在添加时检查add方法的返回值,以确保它成功)。

这是摆脱冗余逻辑的好方法,这种冗余逻辑在以后的软件迭代中可能会或可能不会存在。

我认为这不是一个好习惯。 考虑使用两个参数在Util-Class中编写Util-Method:数组列表和您想要添加的对象。 在那里,您可以检查您想要的任何内容,并可以在您的代码中重用逻辑。

唯一的问题是如果你去重用这个代码并且你不记得你已经覆盖了ArrayList类,请确保彻底评论。