builder 设计模式

Posted littlespring

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了builder 设计模式相关的知识,希望对你有一定的参考价值。

1、经典的Builder模式

Product

技术图片
/**
 * 计算机抽象类, 即Product角色
 */
public abstract class Computer 

    protected String mBoard;
    protected String mDisplay;
    protected String mOS;

    public Computer() 
    

    public void setBoard(String board) 
        mBoard = board;
    

    public void setDisplay(String display) 
        mDisplay = display;
    

    public abstract void setOS();

    @Override
    public String toString() 
        return "Computer"
                + "mBoard=‘"
                + mBoard
                + ‘\‘‘
                + ", mDisplay=‘"
                + mDisplay
                + ‘\‘‘
                + ", mOS=‘"
                + mOS
                + ‘\‘‘
                + ‘‘;
    

复制代码

作者:mundane
链接:https://juejin.im/post/5aa3dfd66fb9a028c42dd13a
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
View Code
具体的Product
技术图片
/**
 * 具体的Computer类
 */
public class Macbook extends Computer 

    public Macbook() 
    

    @Override
    public void setOS() 
        mOS = "Mac OS X 10.10";
    


作者:mundane
链接:https://juejin.im/post/5aa3dfd66fb9a028c42dd13a
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
View Code

抽象Builder

/**
 * 抽象Builder类
 */
public abstract class Builder 

    public abstract void buildBoard(String board);

    public abstract void buildDisplay(String display);

    public abstract void buildOS();

    public abstract Computer create();



作者:mundane
链接:https://juejin.im/post/5aa3dfd66fb9a028c42dd13a
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

ConcreteBuilder

/**
 * 具体的Builder类, MacbookBuilder
 */
public class MacbookBuilder extends Builder 
    private Computer mComputer = new Macbook();

    @Override
    public void buildBoard(String board) 
        mComputer.setBoard(board);
    

    @Override
    public void buildDisplay(String display) 
        mComputer.setDisplay(display);
    

    @Override
    public void buildOS() 
        mComputer.setOS();
    

    @Override
    public Computer create() 
        return mComputer;
    

复制代码

 


作者:mundane
链接:https://juejin.im/post/5aa3dfd66fb9a028c42dd13a
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
/**
 * Director类, 负责构造Computer
 */
public class Director 

    Builder mBuilder;

    public Director(Builder builder) 
        mBuilder = builder;
    

    public void construct(String board, String display) 
        mBuilder.buildBoard(board);
        mBuilder.buildDisplay(display);
        mBuilder.buildOS();
    



作者:mundane
链接:https://juejin.im/post/5aa3dfd66fb9a028c42dd13a
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
public class Main 

    public static void main(String[] args) 
        Builder builder = new MacbookBuilder();
        Director pcDirector = new Director(builder);
        pcDirector.construct("英特尔主板", "Retina 显示器");
        Computer macBook = builder.create();
        System.out.println("Computer Info: " + macBook.toString());
    



作者:mundane
链接:https://juejin.im/post/5aa3dfd66fb9a028c42dd13a
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

输出结果:

Computer Info: ComputermBoard=‘英特尔主板‘, mDisplay=‘Retina 显示器‘, mOS=‘Mac OS X 10.10‘

可以看出, 经典的 Builder 模式重点在于抽象出对象创建的步骤,并通过调用不同的具体实现类从而得到不同的结果, 但是在创建过程中依然要传入多个参数, 不是很方便, 所以有了变种的Builder模式

2、变种的Builder模式

public class User 

    private final String firstName;     // 必传参数
    private final String lastName;      // 必传参数
    private final int age;              // 可选参数
    private final String phone;         // 可选参数
    private final String address;       // 可选参数

    private User(UserBuilder builder) 
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.address = builder.address;
    

    public String getFirstName() 
        return firstName;
    

    public String getLastName() 
        return lastName;
    

    public int getAge() 
        return age;
    

    public String getPhone() 
        return phone;
    

    public String getAddress() 
        return address;
    

    public static class UserBuilder 
        private final String firstName;
        private final String lastName;
        private int age;
        private String phone;
        private String address;

        public UserBuilder(String firstName, String lastName) 
            this.firstName = firstName;
            this.lastName = lastName;
        

        public UserBuilder age(int age) 
            this.age = age;
            return this;
        

        public UserBuilder phone(String phone) 
            this.phone = phone;
            return this;
        

        public UserBuilder address(String address) 
            this.address = address;
            return this;
        

        public User build() 
            return new User(this);
        
    
使用
new
User.UserBuilder("王", "小二") .age(20) .phone("123456789") .address("亚特兰蒂斯大陆") .build();

唯一可能存在的问题就是会产生多余的Builder对象,消耗内存。然而大多数情况下我们的Builder内部类使用的是静态修饰的(static),所以这个问题也没多大关系。

由于Builder是非线程安全的,所以如果要在Builder内部类中检查一个参数的合法性,必需要在对象创建完成之后再检查。

public User build() 
  User user = new user(this);
  if (user.getAge() > 120) 
    throw new IllegalStateException(“Age out of range”); // 线程安全
  
  return user;

上面的写法是正确的,而下面的代码是非线程安全的:

public User build() 
  if (age > 120) 
    throw new IllegalStateException(“Age out of range”); // 非线程安全
  
  return new User(this);

 

以上是关于builder 设计模式的主要内容,如果未能解决你的问题,请参考以下文章

关于Builder模式

Java设计模式Builder建造者模式,Builder设计模式简单代码示例

设计模式-建造者(Builder)

设计模式之建造者(Builder)模式

构造者模式(builder)

Builder设计模式,模板设计模式,Adapter设计模式笔记