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 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
具体的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 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
抽象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 设计模式的主要内容,如果未能解决你的问题,请参考以下文章