java - 构造不可变对象(immutable对象)的抽象生成器

标签 java oop design-patterns reflection builder

我有以下实现抽象构建器的代码(如有效的 java 书中所示):

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

这是一个小用例

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
}

我想做的是 - 从 A 类中的 ret() 方法,我想构造不了解父类型的不可变对象(immutable对象) - 所以在我的示例是具有新内部字符串的新类 B

问题是 A 类不知道 B 类,因为 B 是它的父级。

如果不求助于泛型,这样的事情是否可能?

如果我使用可变类,它会像 this.s = newS; 一样简单。

更新

abstract class A implements I {

    private String s = "";

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

    @Override
    public I ret() {
        String s = "SOME NEW STING FROM CALCULATION";
        return builder().withString(s).build();
    }

    abstract Builder<?> builder();

    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 {

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

    @Override
    Builder builder() {
        return new Builder();
    }

    static class Builder extends A.Builder<Builder> {

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

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

最佳答案

你需要在A中提供一个抽象方法来构造一个合适的Builder实例:

abstract Builder<A> toBuilder();

然后在具体的子类中实现它,并调用:

return toBuilder().withString(s).build();

关于java - 构造不可变对象(immutable对象)的抽象生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53815128/

相关文章:

java - 如何在Spring Boot中将父项目的gradle属性传递给logback.xml?

php - 我什么时候编写自己的异常类?

java - 发现循环依赖问题

c# - 条件生成器方法链接 Fluent 接口(interface)

java - 如何找到我的项目中寻址/访问文件系统的每一段代码?

java - Camel 将 Java DSL 转换为 Spring DSL

java - Servlet URL 模式与斜杠前缀匹配

java - 什么是temp,temp在java中有什么用?

php - 为什么 PHP 允许通过子类中的重写将 protected 方法和私有(private)方法公开?

iphone - 两个非常相似的应用程序,具有不同的文本和UI图形