java利用构建器来创建实例

java利用构建器来创建实例而不是构造器

对于类而言,为了让客户端获取他本身的一个实例,
最传统的方法就是提供一个公有的构造器。

一个类中

重载多个构造器

  客户面对多个构造器这种API永远也记不住该用哪个构造器,
  并且每次调用构造器必然会创建新的对象,
  如果程序需要重复使用对象,构造器无法避免创建不必要的对象。

静态工厂方法与构造器不同的

  1. 第一大优势为:他们有名称
  2. 第二大优势为:不必每一次调用他们的时候创建一个新对象
  3. 第三大优势为:他们可以返回原返回类型的任何子类型的对象
  4. 第四大优势为:所返回的对象的类随着每次调用发生变化,这取决于静态方法的参数值

下面是静态工厂方法的一些惯用名称
1)from---------------------类型转换方法
Date d = Date.from(instant)
2)of------------------------聚合方法,带有多个参数,返回该类型的一个实例,把他们合并起来
Set<Rank> faceCard = EnumSet.of(JACK,QUEEN,KING)
3)valueOf-----------------比前两个更繁琐的方法BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE)

一个构造器中有多个参数时

静态工厂和构造器有个共同的局限性:
他们都不能很好的扩展到大量的可选参数。
比如用一个类来表示食品外面的营养成分标签。
构造器调用了通常你不想设置的参数,
仅仅是几个参数还可接受,但随着参数的增加,很快就失去了控制。

简而言之,重叠构造器模式可行,但当有更多的参数是,客户端的代码会看起来非常糟糕。
javaBean看起来强于上述的重叠构造器模式,但同时也会带来多线程下不安全的问题

那么,我们的构建器出场了。

利用静态内部类Builder,定义与外部类的成员完全相同的成员变量。
类似于javaBean的模式设置每一个参数
最后用build方法构建外部类的新实例(调用外部类的私有构造器)

Main.java

public class Main
{

    public static void main(String[] args)
    {
        //初始化一个NutritionFacts实例,一定要最后调用build()方法去调用NutritionFacts类的构造器去实例化NutritionFacts的对象
        NutritionFacts cocaCola = new NutritionFacts.Builder(120,200).calories(1).carbohydrate(22).build();
        //并且参数由客户端调用时决定,并不是一定要固定输入参数,改进写重载很多构造器给用户带来麻烦
        //javaBean改进了重载一大堆构造器的问题,却也带来了线程不安全的问题
        NutritionFacts cocaCola1  = new NutritionFacts.Builder(223,233).build();
    }
}

NutritionFacts.java

public class NutritionFacts
{
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;
    //私有构造器方法
    private NutritionFacts(Builder build)
    {
        this.servingSize=build.servingSize;
        this.servings=build.servings;
        this.calories=build.calories;
        this.fat=build.fat;
        this.sodium=build.sodium;
        this.carbohydrate=build.carbohydrate;
    }
    //构建者模式(Builder为静态内部类)可由外部直接访问
    public static class Builder
    {
        private final int servingSize;
        private final int servings;
        //初始化默认值
        private int calories=0;
        private int fat=0;
        private int sodium=0;
        private int carbohydrate=0;
        //构造器用于初始化不可变(final)参数
        public Builder(int servingSize,int servings)
        {
            this.servingSize=servingSize;
            this.servings=servings;
        }
        //以下的方法均用于初始化每一个成员
        public Builder calories(int calories)
        {
            this.calories=calories;
            return this;
        }
        public Builder fat(int fat)
        {
            this.fat=fat;
            return this;
        }
        public Builder sodium(int sodium)
        {
            this.sodium=sodium;
            return this;
        }
        public Builder carbohydrate(int carbohydrate)
        {
            this.carbohydrate=carbohydrate;
            return this;
        }
        //最后构造NutritionFacts类的实例,该方法定义于Builder类中
        public NutritionFacts build()
        {
            return new NutritionFacts(this);
        }
    }
}
  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bia!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值