Unity 访问者模式
初学者,自用笔记
用于在不修改一组对象结构(Element/对象树、集合、AST 等)类的前提下,把对这些对象的操作抽离出来,并且能根据“元素的实际类型”分派到不同的处理逻辑(双重分派)
较少见,可让能力组件化实现代替
- Element(元素接口):声明 Accept(IVisitor visitor)。
- ConcreteElement(具体元素):实现 Accept,在其中调用 visitor.Visit(this)。
- Visitor(访问者接口):为每种元素类型提供对应的 Visit(ConcreteElementX x) 方法。
- ConcreteVisitor(具体访问者):实现具体操作(导出、统计、渲染、校验、生成代码等)。
简单例子
Element
public interface IVisitable
{
void Accept(IVisitor visitor);
}
ConcreteElement
// 两种“被访问”的物体(Element)
public sealed class Coin : IVisitable
{
public int amount = 10;
public void Accept(IVisitor visitor) => visitor.Visit(this);
}
public sealed class Trap : IVisitable
{
public int damage = 20;
public void Accept(IVisitor visitor) => visitor.Visit(this);
}
Visitor
public interface IVisitor
{
void Visit(Coin coin);
void Visit(Trap trap);
}
ConcreteVisitor
// 两种“访问者”(交互者):玩家/敌人
public sealed class Player : IVisitor
{
public int gold;
public int hp = 100;
public void Visit(Coin coin)
{
gold += coin.amount;
Debug.Log($"Player picks coin +{coin.amount}, gold={gold}");
}
public void Visit(Trap trap)
{
hp -= trap.damage;
Debug.Log($"Player hits trap -{trap.damage}, hp={hp}");
}
}
public sealed class Enemy : IVisitor
{
public int hp = 50;
public void Visit(Coin coin)
{
// 敌人碰到金币:不捡,直接无视(或销毁)
Debug.Log("Enemy ignores coin.");
}
public void Visit(Trap trap)
{
// 敌人碰到陷阱:同样会受伤,但受伤规则不同(比如更脆弱)
int dmg = trap.damage * 2;
hp -= dmg;
Debug.Log($"Enemy hits trap -{dmg}, hp={hp}");
}
}
