Java 构建器

假如我们的一个实体类有很多的属性值,但是这些属性值又是可选的。如果我们遇到这样的是类,如何设计出方便的实体类呢?

通常解决办法一: 重叠构造器

public class User {

    private String id;                 // id(必填)

    private String name;             // 用户名(必填)

    private String email;             // 邮箱(可选)

    private int age;                 // 年龄(可选)

    private String phoneNumber;     // 电话(可选)

    private String address;         // 地址(可选)

    public User(String id, String name) {
        this(id, name, null, 0, null, null);
    }

    public User(String id, String name, String email) {
        this(id, name, email, 0, null, null);
    }

    public User(String id, String name, String email, int age) {
        this(id, name, email, age, null, null);
    }

    public User(String id, String name, String email, int age, String phoneNumber) {
        this(id, name, email, age, phoneNumber, null);
    }

    public User(String id, String name, String email, int age, String phoneNumber, String address) {
        super();
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
        this.phoneNumber = phoneNumber;
        this.address = address;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", email=" + email + ", age=" + age + ", phoneNumber="
                + phoneNumber + ", address=" + address + "]";
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getAge() {
        return age;
    }

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

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

}

注:重叠构造器模式可行,但是当有很多参数的时候,客户端代码会很难编写,并且难以阅读

通常解决办法二:JavaBean模式

public class User {

    private String id;                 // id(必填)

    private String name;             // 用户名(必填)

    private String email;             // 邮箱(可选)

    private int age;                 // 年龄(可选)

    private String phoneNumber;     // 电话(可选)

    private String address;         // 地址(可选)

    public User(String id, String name, String email, int age, String phoneNumber, String address) {
        super();
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
        this.phoneNumber = phoneNumber;
        this.address = address;
    }

    public User() {
        super();
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", email=" + email + ", age=" + age + ", phoneNumber="
                + phoneNumber + ", address=" + address + "]";
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getAge() {
        return age;
    }

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

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

}

注:JavaBean存在很多缺点,构造过程被分到几个中调用,在多线程很难保证线程安全。

构建器解决

public class NutritionFacts {

    private int servingSize;

    private int servings;

    private int calorizs;

    private int fat;

    private int soduim;

    private int carbophydrate;

    public static class Builder {

        private int servingSize;

        private int servings;

        private int calorizs = 0;

        private int fat = 0;

        private int soduim = 0;

        private int carbophydrate = 0;

        public Builder(int servingSize, int servings) {
            super();
            this.servingSize = servingSize;
            this.servings = servings;
        }

        public Builder colorizes(int val) {
            calorizs = val;
            return this;
        }

        public Builder fat(int val) {
            fat = val;
            return this;
        }

        public Builder soduim(int val) {
            soduim = val;
            return this;
        }

        public Builder carbophydrate(int val) {
            carbophydrate = val;
            return this;
        }

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

    private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calorizs = builder.calorizs;
        fat = builder.fat;
        soduim = builder.soduim;
        carbophydrate = builder.carbophydrate;
    }

    public int getServingSize() {
        return servingSize;
    }

    public int getServings() {
        return servings;
    }

    public int getCalorizs() {
        return calorizs;
    }

    public int getFat() {
        return fat;
    }

    public int getSoduim() {
        return soduim;
    }

    public int getCarbophydrate() {
        return carbophydrate;
    }

    @Override
    public String toString() {
        return "NutritionFacts [servingSize=" + servingSize + ", servings=" + servings + ", calorizs=" + calorizs
                + ", fat=" + fat + ", soduim=" + soduim + ", carbophydrate=" + carbophydrate + "]";
    }

}

测试代码

    public static void main( String[] args )
    {
        User user = new User.Builder(UUID.randomUUID().toString(), "parry").address("广州").builder();
        System.out.println(user.toString());
    }
时间: 2024-12-09 01:35:36

Java 构建器的相关文章

Java构建器模式

当创建对象需要传入多个参数的时候我们通常会根据参数的数量写不同的构造器,具体如下 public A(int a){} public A(int a, int b){} public A(int a, int b, int c){} 根据不同的参数调用不同的构造器,但是当参数多了的时候,这种方式不够灵活,所以会实现动态传参的方法 public A(){} public void seta(int a){} public void setb(int b){} public void setc(int

java构建器

最近在看"Effective Java 中文第二版",看到了构建器这个知识,感觉很不错,比挨个调用setter方法看起来简便多了,代码如下: 1 public class User { 2 3 private String name; 4 private int age; 5 private String sex; 6 private String number; 7 private String address; 8 private int phone; 9 private Stri

Java 《Effective Java 中文版 第2版》学习笔记 遇到多个构造器时要考虑用构建器

静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数. 当一个类中有若干个必选属性和多个可选属性时,采用重叠构造器模式.JavaBeans模式或者Builder模式,但各有优劣. 当有很多参数的时候,重叠构造器模式下客户端代码会很难编写,并且仍然较难以阅读. JavaBeans模式调用一个无参构造器来创建对象,然后调用setter方法来设置每个必要的参数,以及每个相关的可选参数.因为构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态.与此相关的另一点不

【读书笔记 - Effective Java】02. 遇到多个构造器参数时要考虑用构建器

类有多个可选参数的解决方案:1. 重叠构造器模式可行,但是当有许多参数的时候,客户端代码会很难编写,并且仍然较难以阅读.2. JavaBeans模式,调用一个无参构造器来创造对象,然后调用setter方法来设置每个必要的参数,以及每个相关的可选参数. 缺点:构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态.阻止了把类做成不可变的可能,需要程序员确保线程安全.3. Builder模式,模拟了具名的可选参数. 模式 优 劣 重叠构造器 写法最简单 多参数时候难读.难写.难

Java设计模式:Builder(构建器)模式

基本概念 Builder模式是一步一步创建一个复杂对象的创建型模式.该模式将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的表示隔离开来. 应用场景 对象创建过程比较复杂,或对创建顺序或组合有依赖(经典Builder模式,可参阅GOF<设计模式>). 创建对象时所需参数较多,且包含较多可选参数(变种Builder模式,可参阅<Effective Java>构建器小节). 示例代码 本节侧重变种Builder模式,示例代码如下: public class RobustPerso

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

java利用构建器来创建实例而不是构造器 1.对于类而言,为了让客户端获取他本身的一个实例, 2.最传统的方法就是提供一个公有的构造器. 一个类中 重载多个构造器 客户面对多个构造器这种API永远也记不住该用哪个构造器, 并且每次调用构造器必然会创建新的对象, 如果程序需要重复使用对象,构造器无法避免创建不必要的对象. 静态工厂方法与构造器不同的 第一大优势为:他们有名称 第二大优势为:不必每一次调用他们的时候创建一个新对象 第三大优势为:他们可以返回原返回类型的任何子类型的对象 第四大优势为:

遇到多个构造器参数时要考虑用构建器——Effective Java 读书笔记

/** * 如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是种不错的选择,特别是当大多数参数都是可选的时候. * 与使用传统的重叠构造器模式相比,使用Builder模式的客户端代码将更易于阅读和编写,构建器也比JavaBeans更加安全. * * @author 刘向峰 * */ public class NutritionFacts { // 所有的参数 private final int servingSize; private final int servin

深入探讨 Java 类加载器

转自:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 类加载器(class loader)是 Java™中的一个很重要的概念.类加载器负责加载 Java 类的字节代码到 Java 虚拟机中.本文首先详细介绍了 Java 类加载器的基本概念,包括代理模式.加载类的具体过程和线程上下文类加载器等,接着介绍如何开发自己的类加载器,最后介绍了类加载器在 Web 容器和 OSGi™中的应用. 类加载器是 Java 语言的一个创新,也是

Mybatis——SQL语句构建器类

SQL语句构建器类 问题 Java程序员面对的最痛苦的事情之一就是在Java代码中嵌入SQL语句.这么来做通常是由于SQL语句需要动态来生成-否则可以将它们放到外部文件或者存储过程中.正如你已经看到的那样,MyBatis在它的XML映射特性中有一个强大的动态SQL生成方案.但有时在Java代码内部创建SQL语句也是必要的.此时,MyBatis有另外一个特性可以帮到你,在减少典型的加号,引号,新行,格式化问题和嵌入条件来处理多余的逗号或 AND 连接词之前.事实上,在Java代码中来动态生成SQL