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: Computer{mBoard=‘英特尔主板‘, 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); }
原文地址:https://www.cnblogs.com/LittleSpring/p/11417463.html
时间: 2024-10-09 10:38:15