lundi 17 décembre 2018

Abstract builder constructing immutable object

I have following code implementing abstract builder (as in effective java book):

interface I {
    I ret();
}

abstract class A implements I {

    private String s = "";

    A(Builder b) {
        s = b.s;
    }

    @Override
    public I ret() {
        String s = "some new string from calc.";
        //HERE I NEED TO CONSTRUCT class B
        //THIS IS PROBLEMATIC LINE BELOW <<<<--------------------------------------
        return new Builder<>().withString(s).build();
    }

    static abstract class Builder<T extends Builder<T>> {

        String s = "";

        T withString(String s) {
            this.s = s;
            return self();
        }

        protected abstract A build();

        //simulated self-type idiom
        protected abstract T self();
    }
}

class B extends A {

    private B(A.Builder b) {
        super(b);
    }

    static class Builder extends A.Builder<Builder> {

        @Override
        protected B build() {
            return new B(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }
}

and this is small use-case

public static void main(String[] args) {
    I b = new B.Builder().withString("bclass").build();
    I b2 = b.ret(); //<---- this one should construct new immutable B
}

What I want to do is - from ret() method in the class A, I would like to construct immutable object that is ignorant of parent type - so in my example it would be new class B that has new inner string.

Problem is that class A does not know about class B, since B is it's parent.

Is something like this possible without resorting for generics?

If I use mutable class, it would be as simple as this.s = newS;.





Aucun commentaire:

Enregistrer un commentaire