工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
适合的场景
创建过程复杂(涉及多个步骤或条件)
创建的对象可能有多种类型(多子类)
希望解耦调用者和具体类的依赖关系
当你在代码中频繁地写 new 某个类,一旦要改某个类名、构造逻辑或切换不同实现, 就得到处找找改改,工厂模式的出现,就是为了——把“new”这件事交给一个“工厂”来处理,调用者不用关心怎么创建,只管要。
比如:
游戏中根据不同关卡,创建不同类型的敌人 → EnemyFactory!
UI里根据配置,生成按钮或滑条 → WidgetFactory!
基本结构
定义一个抽象产品(接口或基类)
每个具体产品都实现这个产品接口
定义一个抽象工厂类,提供“创建方法”接口
每个具体工厂类负责创建具体产品!
示例
csharp
// 抽象产品
public interface IEnemy
{
void Attack();
}
// 具体产品 A
public class Slime : IEnemy
{
public void Attack() => Console.WriteLine("Slime攻击!");
}
// 具体产品 B
public class Goblin : IEnemy
{
public void Attack() => Console.WriteLine("Goblin突袭!");
}
// 抽象工厂
public abstract class EnemyFactory
{
public abstract IEnemy CreateEnemy();
}
// 具体工厂 A
public class SlimeFactory : EnemyFactory
{
public override IEnemy CreateEnemy() => new Slime();
}
// 具体工厂 B
public class GoblinFactory : EnemyFactory
{
public override IEnemy CreateEnemy() => new Goblin();
}
// 使用
EnemyFactory factory = new GoblinFactory();
IEnemy enemy = factory.CreateEnemy();
enemy.Attack();注意:
这只是传统工厂模式的标准实现,也有其他不同的工厂模式的实现,例如:
用静态工厂方法来构造对象
用字符串匹配来构造对象
在游戏开发中,为了灵活性和性能,通常还会结合资源管理器、场景实例化等方式来处理。
GDScript 示例
gdscript
# 抽象敌人
class Enemy:
func attack():
pass
# 具体敌人
class Slime extends Enemy:
func attack():
print("Slime攻击!")
class Goblin extends Enemy:
func attack():
print("Goblin突袭!")
# 敌人工厂
class EnemyFactory:
static func create_enemy(enemy_type: String) -> Enemy:
match enemy_type:
"slime":
return Slime.new()
"goblin":
return Goblin.new()
_:
push_error("未知敌人类型: %s" % enemy_type)
return null
# 使用
func _ready():
var enemy = EnemyFactory.create_enemy("goblin")
enemy.attack()