我应该扩展 ArrayList 以添加不为空的属性吗? [英] Should I extend ArrayList to add attributes that isn't null?

查看:37
本文介绍了我应该扩展 ArrayList 以添加不为空的属性吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将一组对象添加到 arrayList 中,前提是特定属性不为空.

I would like to add a collection of objects to an arrayList ,only if the particular attribute is not null.

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

I am thinking of extending the ArrayList and implementing the check inside the child class.

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

One alternate way is to check for the the attribute before putting it in a Arraylist, but that would mean , i will have to scatter the if checks every where if i need to add the objects to the arraylist based on the logic.

我想知道您对此的看法……再想一想是不是有点矫枉过正?

I would like to know your thoughts on it ... on a second thought is it a overkill ?

推荐答案

装饰模式

我实际上建议使用有据可查的 Decorator<包装 ArrayList/em> 模式.您只需将 ArrayList 与另一个 List 实现包装起来,该实现委托大多数方法但添加了验证逻辑:

Decorator pattern

I would actually recommend wrapping ArrayList using well-documented Decorator pattern. You simply wrap your ArrayList with another List implementation that delegates most of the methods but adds validation logic:

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 实现,您可以向 LinkedListHibernate 支持的持久列表.您甚至可以考虑使用通用的 Collection 装饰器来验证任何集合.
  • Advantages:

    • You can still access raw list without validation if you want (but you can restrict this)
    • Easier to stack different validations, turn them on and off selectively.
    • Promotes composition over inheritance as noted by @helios
    • Improves testability
    • Does not tie you to a specific List implementation, you can add validation to LinkedList or Hibernate-backed persistent lists. You can even think about generic Collection decorator to validate any collection.
    • 尽管实现了请记住,在覆盖时您必须记住很多方法:add()addAll()set()subList()(?) 等

      Despite the implementation remember there are quite a lot of methods you have to remember about while overriding: add(), addAll(), set(), subList() (?), etc.

      另外你的对象必须是不可变的,否则用户可以添加/设置有效的对象并在之后修改它以违反合同.

      Also your object must be immutable, otherwise the user can add/set valid object and modify it afterwards to violate the contract.

      最后我写道:

      validate(element)
      

      但请考虑:

      element.validate()
      

      这是一个更好的设计.

      如前所述,如果您想堆叠验证,在单个单独的类中验证每个属性/apsect,请考虑以下习惯用法:

      As noted before if you want to stack validations, validating each proprty/apsect in a single, separate class, consider the following idiom:

      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);
      

      想要同时验证 foobar 吗?

      Want to validate both foo and bar?

      List<MyBusinessObject> list = 
        new BarValidatingDecorator(new FooValidatingDecorator(rawArrayList));
      

      这篇关于我应该扩展 ArrayList 以添加不为空的属性吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆