Should I extend ArrayList to add attributes that isn't null?

南楼画角 提交于 2019-11-29 10:09:02

问题


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

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

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 ?


回答1:


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

}

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.

Implementation notes

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.

Good OO design

Finaly I wrote:

validate(element)

but consider:

element.validate()

which is a better design.

Stacking validations

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

}

...and few implementations:

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
    }
}

Want to only validate foo?

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

Want to validate both foo and bar?

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



回答2:


If you would like to enforce this I don't see why not (although you should check the return value of the add method whenever you do add to make sure that it succeeded).

This is a good way to get rid of that redundant logic which may or may not stick around in later software iterations.




回答3:


I don't think this is a good practice. Consider instead writing a Util-Method in a Util-Class taking two parameters: The array list and the object you would like to add. There you can check whatever you want and can reuse the logic all over your code.




回答4:


Only issue would be if you go to reuse this code and you don't remember you've overriden the ArrayList class, make sure to comment thoroughly.



来源:https://stackoverflow.com/questions/9358821/should-i-extend-arraylist-to-add-attributes-that-isnt-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!