建造者模式
将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。
适合的场景
有些对象不是 new 一下就完事了,比如:
RPG角色:职业、属性、装备、技能全都不同
游戏剧情事件:同样的事件框架,不同剧情内容
如果你每次都手动一个个设置字段、判断状态,代码就会很难维护; 建造者模式让你「按步骤、按顺序」拼装对象,既灵活又有条理!
创建流程固定但步骤多的复杂对象
不同版本/类型的对象有相同建造过程但不同内容
希望通过链式调用、分步组装提高代码可读性和复用性
基本结构
产品类(Product):被创建的复杂对象
抽象建造者(Builder):定义构建方法
具体建造者(ConcreteBuilder):实现这些方法
指挥者(Director,可选):负责控制构建顺序
示例
csharp
// 产品
public class Character
{
public string Class;
public string Weapon;
public string Armor;
public void Show()
{
Console.WriteLine($"职业: {Class}, 武器: {Weapon}, 盔甲: {Armor}");
}
}
// 抽象建造者
public interface ICharacterBuilder
{
void SetClass();
void SetWeapon();
void SetArmor();
Character GetResult();
}
// 具体建造者:战士
public class WarriorBuilder : ICharacterBuilder
{
private Character _character = new Character();
public void SetClass() => _character.Class = "战士";
public void SetWeapon() => _character.Weapon = "大剑";
public void SetArmor() => _character.Armor = "重甲";
public Character GetResult() => _character;
}
// 指挥者
public class CharacterDirector
{
private ICharacterBuilder _builder;
public CharacterDirector(ICharacterBuilder builder)
{
_builder = builder;
}
public Character Build()
{
_builder.SetClass();
_builder.SetWeapon();
_builder.SetArmor();
return _builder.GetResult();
}
}
// 使用
var builder = new WarriorBuilder();
var director = new CharacterDirector(builder);
var character = director.Build();
character.Show();有时候我们会去掉 Director,让 Builder 自己负责整个流程, 还能支持链式调用
c#
// 抽象建造者
public interface ICharacterBuilder
{
ICharacterBuilder SetClass();
ICharacterBuilder SetWeapon();
ICharacterBuilder SetArmor();
Character GetResult();
}
// 具体建造者:战士
public class WarriorBuilder : ICharacterBuilder
{
private Character _character = new Character();
public ICharacterBuilder SetClass()
{
_character.Class = "战士";
return this;
}
public ICharacterBuilder SetWeapon()
{
_character.Weapon = "大剑";
return this;
}
public ICharacterBuilder SetArmor()
{
_character.Armor = "重甲";
return this;
}
public Character GetResult() => _character;
}GDScript 示例
gdscript
# 产品类
class Character:
var job := ""
var weapon := ""
var armor := ""
func show():
print("职业: %s, 武器: %s, 盔甲: %s" % [job, weapon, armor])
# 建造者基类
class CharacterBuilder:
func set_job(): pass
func set_weapon(): pass
func set_armor(): pass
func get_result() -> Character: return null
# 具体建造者:骑士
class KnightBuilder extends CharacterBuilder:
var _char = Character.new()
func set_job(): _char.job = "骑士"
func set_weapon(): _char.weapon = "长枪"
func set_armor(): _char.armor = "银甲"
func get_result() -> Character: return _char
# 指挥者(可选)
class CharacterDirector:
func build(builder: CharacterBuilder) -> Character:
builder.set_job()
builder.set_weapon()
builder.set_armor()
return builder.get_result()
# 使用
func _ready():
var builder = KnightBuilder.new()
var director = CharacterDirector.new()
var knight = director.build(builder)
knight.show()