mercredi 6 mai 2020

Best practices for extending an object graph in Java

Consider an immutable (due to it being an external dependency, such as from a library) object graph such as:

public class A {
    private B reference;
    private List<C> moreReferences = new ArrayList<>();

    public void setReference(B ref) {
        reference = ref;
    }

    public B getReference() {
        return reference;
    }

    public addMoreReference(C ref) {
        moreReferences.add(ref);
    }

    public List<C> getMoreReferences() {
        return moreReferences;
    }
}

public class B {
    private A backlink;

    public void setBacklink(A link) {
        backlink = link;
    }

    public A getBacklink() {
        return backlink;
    }
}

public class C {}

What are best practices when attempting to extending all of those classes? Let's assume I'm subclassing all three classes: MyA, MyB and MyC, adding additional methods and fields to all of them. Then I'm always facing the issue that MyA::getReference() still returns instances of B even though I would need MyB here. Typecasting everything doesn't seem like an elegant solution and leads to issues as soon as Collections or Generics are involved: MyA::getMoreReferences() can't be simply cast from List<C> to List<MyC>. I considered covariant return types (overriding the return type of a method in my subclass), but this also fails when Generics are involved.

What patterns or practices are recommended in this case? I'm not so much looking for a simple "fix" to specific issues, but rather a versatile pattern to base my class hierarchy on.

Aucun commentaire:

Enregistrer un commentaire