栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中级——利用构建器模式代替多参构造器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中级——利用构建器模式代替多参构造器

利用构建器模式代替多参构造器

构造器和构建器模式是什么?问题引入解决方案1——javabean解决方案2——Builder扩展——Builder和继承 构造器和构建器模式是什么?

构造器即构造函数,用于生成类实例构建器模式即 Builder 设计模式,也是用于生成类的实例 问题引入

当一个类具有多个可选域时(如对于Person,名字是必须的,其他可选),会出现多个重叠构造器,如下

class Person {
    private String name;
    private int age;
    private int height;
    private int weight;

    public Person(String name) {
        this(name, 0);
    }

    public Person(String name, int age) {
        this(name, age, 0);
    }

    public Person(String name, int age, int height) {
        this(name, age, height, 0);
    }

    public Person(String name, int age, int height, int weight) {
        this.name = name;
        this.age = age;
        this.height = height;
        this.weight = weight;
    }
}

当想创建实例时,需要不得不对本不需要设置的域设置值,如下只想对name、height和weight赋值,但不得不对age也赋值

Person person = new Person("song", 0, 170, 52);

与此同时,当域数量增多时,需要仔细查看每一个域的位置和用途,以避免错误的设置顺序

解决方案1——javabean

利用javabean,可先用无参构造器生成空对象,再用setter方法来为需要的参数赋值

class Person {
    private String name;
    private int age;
    private int height;
    private int weight;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

创建实例

Person person = new Person();
person.setName("song");
person.setHeight(170);
person.setWeight(52);

javabean将类的构造过程分成了多个步骤,在构造过程中对象的状态可能处于不一致的状态,即并发修改,为避免出现这样的情况,需要额外的加锁操作

解决方案2——Builder

采用构建器模式,并不直接生成想要的实例,而是先构造一个Builder,利用Builder来为所需的参数赋值,最后再设置到实例中去

class Person {
    private String name;
    private int age;
    private int height;
    private int weight;

    public Person(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.height = builder.height;
        this.weight = builder.weight;
    }

    public static class Builder {
        private String name;
        private int age = 0;
        private int height = 0;
        private int weight = 0;

        public Builder(String name) {
            this.name = name;
        }

        public Builder age(int age) {
            this.age = age;
            return this;
        }

        public Builder height(int height) {
            this.height = height;
            return this;
        }

        public Builder weight(int weight) {
            this.weight = weight;
            return this;
        }

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

创建实例

Person person = new Person.Builder("song").height(170).weight(52).build();

利用Builder可单独为每个参数赋值,从而实现可选参数的设定

扩展——Builder和继承

如下是奶茶抽象类

利用enmu规定配料,Set记录添加的配料

EnumSet记录Builder添加的配料

addTopping()添加配料返回Builder

build()和self()为抽象类由子类实现

abstract class MilkTea {
public enum Topping {Pudding, Pearl, Sago}

private final Set toppings;

abstract static class Builder> {
    private EnumSet toppings = EnumSet.noneOf(Topping.class);

    public T addTopping(Topping topping) {
        toppings.add(topping);
        return self();
    }

    abstract MilkTea build();

    protected abstract T self();
}

MilkTea(Builder builder) {
    toppings = builder.toppings.clone();
}

}

如下是其实现类

利用enmu规定大小

重写父类的build()和self()返回自身的实例和Builder

class GreenTea extends MilkTea {
public enum Size {Small, Medium, Large}

private final Size size;

public static class Builder extends MilkTea.Builder {
    private final Size size;

    public Builder(Size size) {
        this.size = size;
    }

    @Override
    GreenTea build() {
        return new GreenTea(this);
    }

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

private GreenTea(Builder builder) {
    super(builder);
    size = builder.size;
}

}

创建实例

GreenTea greenTea = new GreenTea.Builder(GreenTea.Size.Small).addTopping(MilkTea.Topping.Pudding).addTopping(MilkTea.Topping.Pearl).build();
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/776095.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号