zoukankan      html  css  js  c++  java
  • Builder设计模式

    Builder模式

    创建一个entity或者javabean通常使用三种方法。

    • 使用无参构造函数,用setter方法来设置对象的初始值。
    • 使用带参构造函数,通过构造函数来初始化参数
    • 使用builder设计模式创建对象。

    如果使用常用的getter/setter方法,那么通常在构造一个我们需要的对象时,使用一长串的setter方法,并且该对象也变成是可变的,即可以使用setter方法随意的修改对象的状态。

    使用带参构造函数能够避免创建可变的对象,但是需要大量的构造函数,要想考虑到每一种情况,构造函数的数量需要用排练组合来计算,或者是创建一个包含全部参数的构造函数,当我们不关注该对象的某个属性时,通过给它设置个默认值即可,通常是null,0,false等。但是当存在大量的参数时,会出现很难把值与变量的位置匹配起来,给阅读与书写带来大量的麻烦。

    为了避免上述的情况,我们可以使用builder模式来创建一个java对象。主要是利用静态内部类的方式。

    见代码如下:

    package com.manager.design;
    
    public class Student2 {
    private final int id;
    private final String name;
    private int age;
    
    private Student2(){}   //定义私有构造器,只能在类内部使用(提供给静态内部类创建一个对象)
    
    private Student2(Student2 origin){  // 拷贝一个对象,即把静态内部类对象的属性给外部类,由静态内部类调用
    	this.id = origin.id;  
    	this.name = origin.name; 
    	this.age = origin.age;
    }
    
    public int getId(){
    	return this.id;
    }
    
    public String getName(){
    	return this.name;
    }
    
    public int getAge(){
    	return this.age;
    }
    
    public static class Builder{  //静态内部类,通过该类来创建一个外部类对象,使用链式调用
    	private Student2 target;  //创建一个外部类对象
    	
    	/**
    	 * 构造一个内部类对象,通过该对象设置属性值
    	 * 如果存在必填参数,可以以带参构造函数的方式传过来
    	 * @param id  必填参数
    	 * @param name 必填参数
    	 */
    	public Builder(int id , String name){ 
    		target= new Student2();
    		target.id = id;
    		target.name = name;
    	}
    	
    	/**
    	 * 调动builder对象的id方法设置id值
    	 * 返回builder对象,用来下一个方法设置属性值
    	 * 这就是链式调用
    	 * @param id
    	 * @return
    	 */
    	
    	
    	public Builder age(int age){
    		target.age = age;
    		return this;
    	}
    	
    	
    	/**
    	 *
    	 * @return
    	 */
    	public Student2 build(){
    		Student2 st = new Student2(target); //调用外部类的带参构造函数初始化外部类的参数
    		
    		if(st.id < 100)   //builder模式是线性不安全的,所以我们必须要类创建完毕后才能对异常处理			
    		try{
    			throw new IllegalStateException("Age out of range"); // 非线程安全
    		}
    		catch( IllegalStateException e){
    			st.id = 1000;
    			e.printStackTrace();
    		}
    		return st; //返回一个外部类
    	}
    }
    
    
    public static void main(String [] args){
    	Student2 st = new Student2.Builder(1, "hubin").id(23).build();
    	System.out.println(st.getId());
    }
    }
    

    注:
    1. builder模式中的构造函数都是私有的,不允许外部调用
    2. builder模式中只有getter方法,没有setter方法
    3. builder模式中使用了链式调用,更具有可读性
    4. 对于一个对象如果需要传入必填参数,则可以在构造函数中传入参数,且类对应的参数应当有fianl修饰,如果没有,如下代码中id,name作为参数传入毫无意义,因为仍然可以被修改。

    public Builder(int id , String name){ 
        target= new Student2();
        target.id = id;
        target.name = name;
    }
    
    public Builder id(int id){   
        target.id = id;
        return this;
    }
    
    public Builder name(String name){
        target.name = name;
        return this;
    }
    不积跬步无以至千里
  • 相关阅读:
    进制
    变量
    cmd命令和快捷键
    面向对象和面向过程
    iterations 快捷键
    SQL语句分类和语法
    MySQL语法规范
    Web-Scale-IT 到底是啥?
    安全的应用程序开发和应用程序安全防御
    如何像后端一样写前端代码?
  • 原文地址:https://www.cnblogs.com/jinxiuze/p/7895164.html
Copyright © 2011-2022 走看看