为了账号安全,请及时绑定邮箱和手机立即绑定

子类化Java Builder类

子类化Java Builder类

白衣非少年 2019-08-30 16:10:17
给这篇Dr Dobbs文章,特别是Builder Pattern,我们如何处理子类化Builder的情况?以我们想要子类化添加GMO标签的示例的简化版本为例,一个简单的实现将是:public class NutritionFacts {                                                                                                        private final int calories;                                                                                                      public static class Builder {                                                                                                        private int calories = 0;                                                                                                        public Builder() {}                                                                                                              public Builder calories(int val) { calories = val; return this; }                                                                                                                                public NutritionFacts build() { return new NutritionFacts(this); }                                                           }                                                                                                                                protected NutritionFacts(Builder builder) {                                                                                          calories = builder.calories;                                                                                                 }                                                                                                                            }现在,我们可以编写如下代码:GMOFacts.Builder b = new GMOFacts.Builder();b.GMO(true).calories(100);但是,如果我们得到错误的订单,那一切都会失败:GMOFacts.Builder b = new GMOFacts.Builder();b.calories(100).GMO(true);问题当然是NutritionFacts.Builder返回a NutritionFacts.Builder而不是a GMOFacts.Builder,所以我们如何解决这个问题,还是有更好的模式可以使用?
查看完整描述

3 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

您可以使用泛型来解决它。我认为这被称为“奇怪的反复出现的通用模式”


使基类构建器方法的返回类型成为通用参数。


public class NutritionFacts {


    private final int calories;


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


        private int calories = 0;


        public Builder() {}


        public T calories(int val) {

            calories = val;

            return (T) this;

        }


        public NutritionFacts build() { return new NutritionFacts(this); }

    }


    protected NutritionFacts(Builder<?> builder) {

        calories = builder.calories;

    }

}

现在使用派生类构建器作为泛型参数来实例化基础构建器。


public class GMOFacts extends NutritionFacts {


    private final boolean hasGMO;


    public static class Builder extends NutritionFacts.Builder<Builder> {


        private boolean hasGMO = false;


        public Builder() {}


        public Builder GMO(boolean val) {

            hasGMO = val;

            return this;

        }


        public GMOFacts build() { return new GMOFacts(this); }

    }


    protected GMOFacts(Builder builder) {

        super(builder);

        hasGMO = builder.hasGMO;

    }

}


查看完整回答
反对 回复 2019-08-30
  • 3 回答
  • 0 关注
  • 641 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信