创建型模式 - 建造者模式 (Builder Pattern)

发布于:2025-02-26 ⋅ 阅读:(169) ⋅ 点赞:(0)

创建型模式 - 建造者模式 (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 建造者模式
抽象工厂注重的是相同的产品家族同一系列产品的构建。不关心构建过程,不同的产品交给不同的具体工厂去构建.
举例,苹果电脑工厂,你知道结果就是一台苹果电脑。而如果使用建造者模式.你需要知道每个零件由什么构成.你使用不同的零件组装出来的就是不同的电脑.


网站公告

今日签到

点亮在社区的每一天
去签到