创建型模式 - 建造者模式 (Builder Pattern)
创建型模式 - 建造者模式 (Builder Pattern)
建造者模式是一种创建型设计模式,它将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
需求描述
在游戏开发中,创建一个复杂的游戏角色,角色具有多种属性,如姓名、性别、职业、武器等。不同类型的角色这些属性的组合和设置方式可能不同。使用建造者模式可以将角色的创建过程和具体表示分离,方便创建不同类型的角色。
// 产品类:游戏角色
class GameCharacter {
private String name;
private String gender;
private String profession;
private String weapon;
public void setName(String name) {
this.name = name;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setProfession(String profession) {
this.profession = profession;
}
public void setWeapon(String weapon) {
this.weapon = weapon;
}
@Override
public String toString() {
return "GameCharacter{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", profession='" + profession + '\'' +
", weapon='" + weapon + '\'' +
'}';
}
}
// 抽象建造者类
abstract class CharacterBuilder {
protected GameCharacter character;
public GameCharacter getCharacter() {
return character;
}
public void createNewCharacter() {
character = new GameCharacter();
}
public abstract void buildName();
public abstract void buildGender();
public abstract void buildProfession();
public abstract void buildWeapon();
}
// 具体建造者类:战士角色建造者
class WarriorBuilder extends CharacterBuilder {
@Override
public void buildName() {
character.setName("战士-亚瑟");
}
@Override
public void buildGender() {
character.setGender("男");
}
@Override
public void buildProfession() {
character.setProfession("战士");
}
@Override
public void buildWeapon() {
character.setWeapon("大剑");
}
}
// 具体建造者类:法师角色建造者
class MageBuilder extends CharacterBuilder {
@Override
public void buildName() {
character.setName("法师-梅林");
}
@Override
public void buildGender() {
character.setGender("男");
}
@Override
public void buildProfession() {
character.setProfession("法师");
}
@Override
public void buildWeapon() {
character.setWeapon("法杖");
}
}
// 指挥者类
class CharacterDirector {
private CharacterBuilder builder;
public CharacterDirector(CharacterBuilder builder) {
this.builder = builder;
}
public GameCharacter constructCharacter() {
builder.createNewCharacter();
builder.buildName();
builder.buildGender();
builder.buildProfession();
builder.buildWeapon();
return builder.getCharacter();
}
}
// 客户端代码
public class GameCharacterBuilderExample {
public static void main(String[] args) {
// 创建战士角色
CharacterBuilder warriorBuilder = new WarriorBuilder();
CharacterDirector warriorDirector = new CharacterDirector(warriorBuilder);
GameCharacter warrior = warriorDirector.constructCharacter();
System.out.println(warrior);
// 创建法师角色
CharacterBuilder mageBuilder = new MageBuilder();
CharacterDirector mageDirector = new CharacterDirector(mageBuilder);
GameCharacter mage = mageDirector.constructCharacter();
System.out.println(mage);
}
}
建造者模式拓展
使用这一种方式,就相当于代码中调用方法者来充当指挥者角色。
public class Phone {
private String cpu;
private String screen;
private String memory;
private String brand;
// 私有构造函数
private Phone(Builder builder) {
this.cpu = builder.cpu;
this.screen = builder.screen;
this.memory = builder.memory;
this.brand = builder.brand;
}
// 内部类构造器
public static final class Builder {
private String cpu;
private String screen;
private String memory;
private String brand;
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder screen(String screen) {
this.screen = screen;
return this;
}
public Builder memory(String memory) {
this.memory = memory;
return this;
}
public Builder brand(String brand) {
this.brand = brand;
return this;
}
// 利用 Java 内部类可以访问外部类的私有成员变量的特性,调用私有构造方法返回 Phone 对象
public Phone build() {
return new Phone(this);
}
}
}
// 使用的时候非常方便也非常清晰
Phone iPhone20 = new Phone.Builder()
.cpu("Apple A100")
.screen("LG屏幕")
.memory("三星内存")
.brand("Apple")
.build();
// btw: 这种使用方式还是挺常见的, 在一些第三方库配置 Config 的时候,例如 Rocket MQ 配置
小结
工厂方法模式 vs 建造者模式.
工厂方法注重的是整体的构建.
建造者模式注重零部件细节的过程.
抽象工厂模式 vs 建造者模式
抽象工厂注重的是相同的产品家族同一系列产品的构建。不关心构建过程,不同的产品交给不同的具体工厂去构建.
举例,苹果电脑工厂,你知道结果就是一台苹果电脑。而如果使用建造者模式.你需要知道每个零件由什么构成.你使用不同的零件组装出来的就是不同的电脑.