1.此文章讨论在构建Java对象时遇到多参数问题(有些是非必须的)如何进行合理的构建。

2.遇到这种情况有三种处理方式:

  1. 重叠构造器:
  2. JavaBean模式
  3. 建造者(Builder)模式

创建的虚拟实体类为Book类,其中:

//必需的参数
private String bookName;
private float price;
//以下为非必需的参数	
private String authorName;
private String bookPublishing;
private String classify;

3.重叠构造器模式:

在这种模式下,提供第一个构造器只有必要的参数,第二个构造器有一个可选的参数,第三个构造器有两个可选的参数,依次类推,最后一个构造器包含全部参数。

/**
 * 1.使用重载构造器的方法初始化对象的多个属性
 */
public class Book {
    //require parameters
    private String bookName;
    private float price;

    //notrequire parameters
    private String authorName;
    private String classify;
    private String bookPublishing;

    /*
        overlode constructor
     */

    //必要参数的构造器
    public Book(String bookName,  float price){
        this.bookName = bookName;
        this.price = price;
    }
    
    //含一个可选参数的构造器
    public Book(String bookName,  float price, String authorName){
        this.bookName = bookName;
        this.price = price;
        this.authorName = authorName;
    }
    
    //含两个可选参数的构造器
    public Book(String bookName, String authorName, float price, String classify){
        this.bookName = bookName;
        this.authorName = authorName;
        this.price = price;
        this.classify = classify;
    }
    
    //含三个可选参数的构造器
    public Book(String bookName, String authorName, float price, String classify, String bookPublishing){
        this.bookName = bookName;
        this.authorName = authorName;
        this.price = price;
        this.classify = classify;
        this.bookPublishing = bookPublishing;
    }
    
    //方便打印数据
    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", authorName='" + authorName + '\'' +
                ", price=" + price +
                ", classify='" + classify + '\'' +
                ", bookPublishing='" + bookPublishing + '\'' +
                '}';
    }
}

下面为使用的时候如何进行构造:

  • 创建只包含两个必要参数的对象
//创建只知道书名和价钱的对象
   Book book1 = new Book("Java", 25);
   System.out.println(book1);

结果为:

java 函数 多参数 java多个参数怎么办_构造器

  • 创建包含一个可选参数的对象:
//包含可选参数authorName
 Book book2 = new Book("C++", 21, "谭浩强");
 System.out.println(book2);

结果为:

java 函数 多参数 java多个参数怎么办_设计模式_02

  • 创建包含全部参数的对象
Book book3 = new Book("数据结构", "严蔚敏", 20, "计算机系列丛书", "清华大学出版社");
 System.out.println(book3);

结果为:

java 函数 多参数 java多个参数怎么办_可选参数_03

但是当我们需要设置bookName, price, authorName, bookPublishing 时会遇到下面的情况:

Book book4 = new Book("操作系统", 30, "冯裕忠", null, "清华大学出版社");
	//此时因为不知道 classify 属性的值,也没有仅含已知参数的构造器,所以不得不对 classify 传递 null 值。

且随着参数的增多,它很快会失去控制。
总结:重叠构造器是可行的,但是当有许多参数时,客户端代码会很难写,并且阅读困难。

4.JavaBean模式:

在这中模式下,先调用一个无参构造器来创建对象,然后调用set方法设置每个必要的值,以及每个可选的参数。

/**
 * 使用JavaBean模式创建对象
 * 有些属性是可选的
 */
public class Book {
    //require parameters
    private String bookName;
    private float price;

    //notrequire parameters
    private String authorName;
    private String classify;
    private String bookPublishing;

    /*
    提供一个空的构造器
     */
    public Book(){};

    /*
    设置属性的set方法
     */

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public void setClassify(String classify) {
        this.classify = classify;
    }

    public void setBookPublishing(String bookPublishing) {
        this.bookPublishing = bookPublishing;
    }

    //重写toString方法。

    @Override
    public String toString() {
        return "BookBean{" +
                "bookName='" + bookName + '\'' +
                ", authorName='" + authorName + '\'' +
                ", price=" + price +
                ", classify='" + classify + '\'' +
                ", bookPublishing='" + bookPublishing + '\'' +
                '}';
    }
}

创建对象的代码为:

//先调用无参构造创建对象
Book book = new Book();
//然后调用set方法对需要的参数进行赋值
book.setBookName("Java");
book.setPrice(30);
book.setAuthorName("李兴华");

特点:创建容易,但是把构造过程分为几个调用中,易使JavaBean对像处于不一致的状态。

5.构建者(builder)模式

不直接生成对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂)得到一个Buiding对象。然后在Building对象上调用类似的set方法来设置每个可选的参数。最后客户端调用无参的build方法来生成对象,代码如下:

public class Book {
    //必需的参数
    private String bookName;
    private float price;
    //以下为非必需的参数
    private String authorName;
    private String bookPublishing;
    private String classify;

    //设置私有构造器,传递一个内部类参数,允许内部类调用
    private Book(Building builder){
        this.bookName = builder.bookName;
        this.authorName = builder.authorName;
        this.price = builder.price;
        this.bookPublishing = builder.bookPublishing;
        this.classify = builder.classify;
    }

    //自定义Building内部类
    public static class Building{
        //必需的参数
        private String bookName;
        private float price;
        //以下为非必需的参数
        private String authorName;
        private String bookPublishing;
        private String classify;

        //必要参数构造一个Building对象
        public Building(String bookName, float price){
            this.bookName = bookName;
            this.price = price;
        }

        //把Building对象传递给外部的Book构造器
        public Book build(){
            return new Book(this);
        }

        //设置可选参数
        public Building authorName(String authorName){
            this.authorName = authorName;
            return this;
        }
        public Building bookPublishing(String bookPublishing){
            this.bookPublishing = bookPublishing;
            return this;
        }
        public Building classify(String classify){
            this.classify = classify;
            return this;
        }

    }
    //重写toString便于输出
    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", price=" + price +
                ", authorName='" + authorName + '\'' +
                ", bookPublishing='" + bookPublishing + '\'' +
                ", classify='" + classify + '\'' +
                '}';
    }
}

客户端使用为:

Book book = new Book.Building("机器学习", 35).authorName("周志华").bookPublishing("清华大学出版社").classify("深度学习系类丛书").build();
    System.out.println(book);

输出为:

java 函数 多参数 java多个参数怎么办_设计模式_04