思考生成者模式
生成者模式就是将对象构建和对象内部构建分离
对象构建:手机的构建
对象内部构建:手机中屏幕和电池的构建
1.生成者模式的本质
生成器模式的本质:分离整体对象构建算法和对象的部件构造。
构建一个复杂的对象,本来就有构建的过程,以及构建过程中具体的实现。生成器模式就是用来分离这两个部分,从而使得程序结构更松散、扩展更容易、复用性更好,同时也会使得代码更清晰,意图更明确。
虽然在生成器模式的整体构建算法中,会一步一步引导 Builder来构建对象,但这并不是说生成器主要就是用来实现分步骤构建对象的。生成器模式的重心还是在于分离整体构建算法和部件构造,而分步骤构建对象不过是整体构建算法的一个简单表现,或者说是一个附带产物。
2.何时选用生成者模式
建议在以下情况中选用生成器模式。
- 如果创建对象的算法,应该独立于该对象的组成部分以及它们的装配方式时。
- 如果同一个构建过程有着不同的表示时。
3.实现
/**
* @description:手机接口
*/
public interface PhoneBuilder {
/**
* 构建手机对象
*/
void buildPhone();
}
/**
* @description:苹果手机实现类
*/
public class ApplePhone implements PhoneBuilder{
private Screen screen;
private Battery battery;
//初始化屏幕
private Screen initScreen(){
return screen=new Screen(16d,9d);
}
//初始化电池
private Battery initBattery(){
return battery=new Battery(5000d);
}
@Override
public void buildPhone() {
initScreen();
initBattery();
System.out.println("开始组装屏幕"+screen+"电池"+battery);
}
}
/**
* @description:屏幕对象
*/
@Data
@ToString
@AllArgsConstructor
public class Screen {
//屏幕长度
private Double length;
//屏幕宽度
private Double width;
}
/**
* @description:电池对象
*/
@Data
@ToString
@AllArgsConstructor
public class Battery {
//电池容量
private Double capacity;
}
指导者
/**
* @description:指导者对象
*/
public class Director {
//多态
private PhoneBuilder phoneBuilder;
public Director(PhoneBuilder phoneBuilder) {
this.phoneBuilder = phoneBuilder;
}
public void build(){
phoneBuilder.buildPhone();
}
}
测试
/**
* @description:测试类
*/
public class Client {
public static void main(String[] args) {
new Director(new ApplePhone()).build();
}
}
类图
生成器模式构建复杂对象
用户类
/**
* @description:用户类
*/
public class User {
private String userName;
private String password;
private Integer age;
public User(UserBuilder userBuilder) {
this.userName = userBuilder.getUserName();
this.password = userBuilder.getPassword();
this.age = userBuilder.getAge();
}
public void test(){
System.out.println("userName:"+userName+",password:"+password+",age:"+age);
}
}
用户生成器
/**
* @description:TODO
*/
@Getter
public class UserBuilder {
private String userName;
private String password;
private Integer age;
public UserBuilder(String userName) {
this.userName = userName;
}
public User build(){
//校验
if (password.length()<6){
throw new RuntimeException("密码长度不能小于6位");
}else if (age>20){
throw new RuntimeException("年龄不能大于20");
}
return new User(this);
}
/**
* 链式set
*/
public UserBuilder setPassword(String password) {
this.password = password;
return this;
}
/**
* 链式set
*/
public UserBuilder setAge(Integer age) {
this.age = age;
return this;
}
}
测试
public class Clent {
public static void main(String[] args) {
User user = new UserBuilder("张三").setPassword("123456").setAge(21).build();
user.test();
}
}