思考生成者模式
生成器模式就是将对象构建和对象内部构建分离,将一个复杂对象的构建(外壳) 与 它的表示(内部实现)分离,使得同样的构建过程可以创建不同的表示
对象构建:手机的构建
对象内部构建:手机中屏幕、电池和芯片的构建
1.生成器模式的本质
生成器模式的本质:分离整体对象构建算法和对象的部件构造。
构建一个复杂的对象,本来就有构建的过程,以及构建过程中具体的实现(表示形式)。生成器模式就是用来分离这两个部分,从而使得程序结构更松散、扩展更容易、复用性更好,同时也会使得代码更清晰,意图更明确。
对象的构建过程和表示形式指的是什么?
对象的构建过程指的是将一个复杂对象逐步构建的过程,这个过程通常需要按照一定的顺序完成多个步骤,每个步骤可能包括创建对象的某些部分、初始化对象的状态等。例如,在汽车生成器模式中,对象的构建过程包括构建车身、构建发动机和构建轮胎等多个步骤。
表示形式指的是复杂对象的最终表现形式,也就是我们最终要创建的对象的形态和特征。例如,在汽车生成器模式中,表示形式指的是车辆的各个部分的组合方式和特定的配置。不同的表示形式可能需要使用不同的生成器来创建,但是它们的构建过程可能是相同的。
在生成器模式中,将对象的构建过程和表示形式分离开来,可以使得我们能够更加灵活地创建对象,并且能够重用构建过程的代码,减少重复工作。
2.何时选用生成器模式
建议在以下情况中选用生成器模式。
- 对象构建的属性不会变,而其组合经常变化的时候 ,就可以选择这样的设计模式来构建代码
- 如果同一个构建过程有着不同的表示时。
- 在软件开发中,有些复杂对象的构建过程可能是相同的,但是最终的表示形式却可能存在差异。这时候,如果我们采用传统的工厂模式或者抽象工厂模式来创建对象,那么就需要针对每种表示形式都编写对应的工厂方法,这样会导致代码的复杂度增加。
相比之下,生成器模式则提供了一种更加灵活的解决方案。通过将对象的构建过程与表示分离开来,生成器模式允许我们使用相同的构建过程来创建不同的表示形式。这是因为,生成器模式将对象的构建过程抽象为一个生成器接口,并提供了不同的具体生成器实现,每个具体生成器实现都负责创建特定的表示形式。而指挥者类则负责协调不同的具体生成器,按照特定的顺序调用生成器的方法,完成表示对象的构建。
因此,当我们需要使用同一个构建过程来创建不同的表示形式时,使用生成器模式可以帮助我们提高代码的复用性和灵活性。
- 在软件开发中,有些复杂对象的构建过程可能是相同的,但是最终的表示形式却可能存在差异。这时候,如果我们采用传统的工厂模式或者抽象工厂模式来创建对象,那么就需要针对每种表示形式都编写对应的工厂方法,这样会导致代码的复杂度增加。
3.优缺点
生成器模式有以下优点
-
松散耦合
生成器模式可以用同一个构建算法构建出表现上完全不同的产品,实现产品构建和产品表现上的分离。生成器模式正是把产品构建的过程独立出来,使它和具体产品的表现松散耦合,从而使得构建算法可以复用,而具体产品表现也可以灵活地、方便地扩展和切换。 -
可以很容易地改变产品的内部表示
在生成器模式中,由于Builder对象只是提供接口给Director使用,那么具体的部件创建和装配方式是被 Builder 接口隐藏了的,Director并不知道这些具体的实现细节。这样一来,要想改变产品的内部表示,只需要切换 Builder的具体实现即可,不用管Director,因此变得很容易。 -
更好的复用性
生成器模式很好地实现了构建算法和具体产品实现的分离。这样一来,使得构建产品的算法可以复用。同样的道理,具体产品的实现也可以复用,同一个产品的实现,可以配合不同的构建算法使用。
4.生成器模式的结构
- Builder:生成器接口,定义创建一个Product对象所需的各个部件的操作。
- ConcreteBuilder:具体的生成器实现,实现各个部件的创建,并负责组装 Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法。
- Director:指导者,也被称为导向者,主要用来使用Builder接口,以一个统一的过程来构建所需要的 Product对象。
- Product:产品,表示被生成器构建的复杂对象,包含多个部件。
5.实现
生成器模式构建对象的多种表示形式
/**
* @description:手机构建器接口
*/
public interface PhoneBuilder {
/**
* 构建屏幕
*/
void buildScreen();
/**
* 构建电池
*/
void buildBattery();
/**
* 构建芯片
*/
void buildChip();
/**
* 获取构造的手机对象
*/
Phone getPhone();
}
/**
* @description:苹果手机构建类
*/
@Data
public class ApplePhone implements PhoneBuilder{
private Phone phone;
public ApplePhone(){
//初始化手机对象
phone=new Phone();
}
@Override
public void buildScreen() {
phone.setScreenSize("16寸");
}
@Override
public void buildBattery() {
phone.setBatteryCapacity(5000d);
}
@Override
public void buildChip() {
phone.setChipType("苹果芯片");
}
@Override
public Phone getPhone() {
return this.phone;
}
}
/**
* @description:oppo手机构建类
*/
@Data
public class OppoPhone implements PhoneBuilder{
private Phone phone;
public OppoPhone(){
//初始化手机对象
phone=new Phone();
}
@Override
public void buildScreen() {
phone.setScreenSize("18寸");
}
@Override
public void buildBattery() {
phone.setBatteryCapacity(6000d);
}
@Override
public void buildChip() {
phone.setChipType("华为芯片");
}
@Override
public Phone getPhone() {
return this.phone;
}
}
指导者
/**
* @description:指导者对象(指导如何构建手机)
*/
@Data
public class Director {
/**
* 手机构建器
*/
private PhoneBuilder phoneBuilder;
public Phone build(){
//按顺序构建手机对象
phoneBuilder.buildScreen();
phoneBuilder.buildBattery();
phoneBuilder.buildChip();
return phoneBuilder.getPhone();
}
}
测试
/**
* @description:测试类
*/
public class Client {
public static void main(String[] args) {
//指导者对象
Director director = new Director();
Phone phone;
//指导苹果手机构建
PhoneBuilder phoneBuilder1=new ApplePhone();
director.setPhoneBuilder(phoneBuilder1);
phone = director.build();
System.out.println(phone);
//指导oppo手机构建
PhoneBuilder phoneBuilder2=new OppoPhone();
director.setPhoneBuilder(phoneBuilder2);
phone = director.build();
System.out.println(phone);
}
}
结果:
Phone(screenSize=16寸, batteryCapacity=5000.0, chipType=苹果芯片)
Phone(screenSize=18寸, batteryCapacity=6000.0, chipType=华为芯片)
生成器模式链式构建对象
构建器接口
/**
* @description:手机构建器接口
*/
public interface PhoneBuilder2 {
/**
* 构建屏幕
*/
PhoneBuilder2 buildScreen(String screenSize);
/**
* 构建电池
*/
PhoneBuilder2 buildBattery(Double batteryCapacity);
/**
* 构建芯片
*/
PhoneBuilder2 buildChip(String chipType);
/**
* 获取构造的手机对象
*/
String getPhone();
}
/**
* @description:手机构建器过程
*/
@NoArgsConstructor
public class ConcreteBuilder implements PhoneBuilder2 {
/**
* 手机品牌
*/
private String phoneBrand;
/**
* 手机对象
*/
private Phone phone = new Phone();
public ConcreteBuilder(String phoneBrand) {
this.phoneBrand = phoneBrand;
}
@Override
public PhoneBuilder2 buildScreen(String screenSize) {
this.phone.setScreenSize(screenSize);
return this;
}
@Override
public PhoneBuilder2 buildBattery(Double batteryCapacity) {
this.phone.setBatteryCapacity(batteryCapacity);
return this;
}
@Override
public PhoneBuilder2 buildChip(String chipType) {
this.phone.setChipType(chipType);
return this;
}
@Override
public String getPhone() {
return phoneBrand + "{" +
"screenSize='" + phone.getScreenSize() + '\'' +
", batteryCapacity=" + phone.getBatteryCapacity() +
", chipType='" + phone.getChipType() + '\'' +
'}';
}
}
指导者
/**
* @description:指导者对象
*/
public class Director2 {
/**
* 指导构建苹果手机
* @return
*/
public PhoneBuilder2 buildAppPhone() {
return new ConcreteBuilder("苹果手机").buildScreen("16寸")
.buildBattery(5000d).buildChip("苹果芯片");
}
/**
* 指导构建oppo手机
* @return
*/
public PhoneBuilder2 buildOppoPhone() {
return new ConcreteBuilder("Oppo手机").buildScreen("18寸")
.buildBattery(6000d).buildChip("华为芯片");
}
}
测试类
public class Client {
public static void main(String[] args) {
Director2 director=new Director2();
System.out.println(director.buildAppPhone().getPhone());
System.out.println(director.buildOppoPhone().getPhone());
}
}
结果
苹果手机{screenSize='16寸', batteryCapacity=5000.0, chipType='苹果芯片'}
Oppo手机{screenSize='18寸', batteryCapacity=6000.0, chipType='华为芯片'}