访问者模式是一种行为设计模式,它允许在不改变对象结构的前提下,定义作用于这些对象元素的新操作。
优点:
1.符合开闭原则:新增操作只需添加新的访问者类,无需修改现有对象结构。
2.操作逻辑集中管理:将相关操作聚合在同一个访问者中,避免代码分散。
3.支持跨对象计算:通过遍历对象结构,实现跨元素的全局计算。
4.增强代码可读性:操作逻辑与数据结构分离,代码结构更易维护。如渲染、战斗伤害、AI决策等不同模块的代码独立为不同访问者。
缺点:
1.破坏对象封装性:访问者需要直接访问对象内部状态,强制暴露私有字段或方法。
优化:1.接口隔离,通过显式接口限制访问范围。
2.元素类型扩展困难:新增元素类型(如新增NPC类)需修改所有访问者接口和实现。
优化:1.访问者适配器模式:通过中间适配器隔离变化。
3.性能损耗:频繁创建访问者对象导致性能下降。
优化:1.访问者对象池:复用访问者实例减少GC压力。2.批处理模式:合并多次访问为单次遍历。3.静态委托优化:通过预编译减少虚方法调用开销。
4.复杂对象结构支持弱:对嵌套结构(如树形结构的场景节点)访问逻辑复杂。
优化:1.组合模式集成:将复杂结构抽象为组合元素。2.访问者责任链:拆分复杂操作为多个子访问者链式处理:
说明例子:
1.UML类图:
2.实现:
1.定义图基类:
public abstract class IGraph
{
public abstract void Draw(); //绘制
public abstract float GetArea(); //获取面积
public abstract int GetVectorCount(); //获取顶点数
public abstract void RunVisitor(IGraphVisitor theVisitor);
}
2.定义访问者基类:
public abstract class IGraphVisitor
{
//由Cicle类来调用
public virtual void VisitCicle(CicleGraph theCicle) { }
//由Rectangle类调用
public virtual void VisitRectangle(RectangleGraph theRect) { }
//由Triangle类调用
public virtual void VisitTriangle(TriangleGraph theTriangle) { }
}
3.定义容器类:
public class GraphContainer
{
List<IGraph> m_Graphs = new List<IGraph>();
public GraphContainer() { }
//新增
public void AddShape(IGraph graph)
{
m_Graphs.Add(graph);
}
//共享的访问者接口
public void RunVisitor(IGraphVisitor theVisitor)
{
foreach (IGraph graph in m_Graphs)
{
graph.RunVisitor(theVisitor);
}
}
}
4.定义具体图形类:
public class CicleGraph : IGraph
{
public override void Draw()
{
Debug.Log("Draw CicleGraph...");
}
public override int GetVectorCount()
{
return 9999;
}
public override float GetArea()
{
return Mathf.PI * 5 * 5;
}
public override void RunVisitor(IGraphVisitor theVisitor)
{
theVisitor.VisitCicle(this);
}
}
public class RectangleGraph : IGraph
{
public override void Draw()
{
Debug.Log("Draw RectangleGraph...");
}
public override int GetVectorCount()
{
return 4;
}
public override float GetArea()
{
return 4 * 5;
}
public override void RunVisitor(IGraphVisitor theVisitor)
{
theVisitor.VisitRectangle(this);
}
}
public class TriangleGraph : IGraph
{
public override void Draw()
{
Debug.Log("Draw TriangleGraph...");
}
public override int GetVectorCount()
{
return 3;
}
public override float GetArea()
{
return .5f * 3 * 5;
}
public override void RunVisitor(IGraphVisitor theVisitor)
{
theVisitor.VisitTriangle(this);
}
}
5.定义具体访问者类:
public class DrawVisitor : IGraphVisitor
{
public override void VisitCicle(CicleGraph theCicle)
{
theCicle.Draw();
}
public override void VisiRectangle(RectangleGraph theRect)
{
theRect.Draw();
}
public override void VisitTriangle(TriangleGraph theTriangle)
{
theTriangle.Draw();
}
}
public class VertexCountVisitor : IGraphVisitor
{
public int Count = 0;
//由Cicle类调用
public override void VisitCicle(CicleGraph theCicle)
{
Count = theCicle.GetVectorCount();
Debug.Log("VisitCicle Count:" + Count);
}
//由Rectangle类调用
public override void VisitRectangle(RectangleGraph theRect)
{
Count += theRect.GetVectorCount();
Debug.Log("VisitRectangle Count:" + Count);
}
//由Triangle类调用
public override void VisitTriangle(TriangleGraph theTriangle)
{
Count += theTriangle.GetVectorCount();
Debug.Log("VisitTriangle Count:" + Count);
}
}
public class CicleAreaVisitor : IGraphVisitor
{
public float Area;
//由Sphere类来调用
public override void VisitCicle(CicleGraph theCicle)
{
Area += theCicle.GetArea();
Debug.Log("VisitCicle Area:" + Area);
}
}
6.测试:
public class VisitorPattern : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GraphContainer graphContainer = new GraphContainer();
graphContainer.AddShape(new CicleGraph());
graphContainer.AddShape(new RectangleGraph());
graphContainer.AddShape(new TriangleGraph());
graphContainer.RunVisitor(new DrawVisitor());
graphContainer.RunVisitor(new VertexCountVisitor());
graphContainer.RunVisitor(new CicleAreaVisitor());
}
}
游戏中使用场景:
1.战斗系统:计算不同角色(玩家、敌人)之间的伤害。
2.存档系统:序列化不同类型的游戏对象状态。
3.渲染优化:根据对象类型选择渲染策略(如LOD、材质替换)。
4.AI行为决策:根据场景元素类型生成不同的AI反应。
5.成就系统:检测特定游戏对象的状态变化(如击杀稀有敌人)。
总结:
在游戏开发中,访客模式特别适合需要跨多种对象类型执行统一逻辑的场景,如战斗计算、存档系统和数据分析模块。
参考书籍或链接:
C# 常用设计模式 (refactoringguru.cn)
《Hands-On Game Development Patterns with Unity 2019》
《设计模式与游戏完美开发》