Unity 设计模式 之 行为型模式 -【访问者模式】【模板模式】【策略模式】
目录
Unity 设计模式 之 行为型模式 -【访问者模式】【模板模式】【策略模式】
4、实现具体访问者类(ShapeRenderer 和 ShapeScaler)
5、客户端代码(VisitorPatternExample)
四、模板方法模式(Template Method Pattern)
(2) 定义具体策略类 WalkStrategy、RunStrategy 和 JumpStrategy
一、简单介绍
设计模式 是指在软件开发中为解决常见问题而总结出的一套 可复用的解决方案。这些模式是经过长期实践证明有效的 编程经验总结,并可以在不同的项目中复用。设计模式并不是代码片段,而是对常见问题的 抽象解决方案,它提供了代码结构和模块间交互的一种设计思路,帮助开发者解决特定的设计问题。
设计模式的特点:
- 通用性:设计模式针对的是软件开发中常见的设计问题,适用于各种软件工程项目。
- 可复用性:设计模式可以在不同项目和环境下被重复使用,提高代码的可维护性和扩展性。
- 可扩展性:设计模式有助于让代码结构更加灵活,易于扩展和修改。
- 模块化:通过设计模式,可以减少代码的耦合性,增强模块间的独立性。
- 提高沟通效率:设计模式为开发者提供了一种通用的设计语言,使得团队成员能够快速理解并讨论设计方案。
二、访问者模式(Visitor Pattern)
访问者模式(Visitor Pattern) 是一种行为型设计模式,它允许你在不修改已有类的前提下,向这些类添加新的功能。该模式通过将操作逻辑与对象结构分离,使得你可以在不改变类结构的情况下为对象添加新功能。
访问者模式的关键是定义一个访问者接口,包含一组针对不同类的访问操作。然后,将访问者传递给对象,让对象接受访问者并调用相应的操作。
1、什么时候使用访问者模式
-
对象结构相对稳定,操作行为频繁变化:如果你的对象结构是稳定的,但需要频繁添加新功能,那么访问者模式非常适合。它可以在不修改原始类的前提下添加新的操作。
-
需要对不同类型的对象执行不同操作:当你有一组类型各异的对象,并且希望对这些对象执行多种不同的操作时,访问者模式可以使操作代码与对象结构分离,避免在对象中添加大量的
if-else
或switch-case
语句。 -
复杂对象结构:在复杂的对象层次结构中,访问者模式通过集中管理操作,使得你可以避免修改对象层次结构中的每个类。
2、使用访问者模式的好处
-
增加新功能而不修改原有代码:访问者模式使得在不修改已有类的情况下,轻松扩展新的操作或行为,符合开闭原则。
-
分离行为与数据结构:它将操作逻辑与数据结构分离,维护起来更加灵活。在复杂系统中,尤其是涉及多个对象类型时,这种模式非常有用。
-
清晰的责任划分:可以将不同的操作封装到不同的访问者类中,使得每个访问者负责一类操作,职责划分更加明确。
-
支持不同的操作顺序:通过不同的访问者,可以灵活控制操作顺序,适用于需要多次遍历不同类对象并进行操作的情况。
3、使用访问者模式时的注意事项
-
违反依赖倒置原则:访问者模式将具体访问者的操作逻辑硬编码在对象类中,可能会导致对象类对访问者的强依赖。
-
增加复杂性:访问者模式虽然带来扩展性,但它也增加了系统的复杂性,尤其是对象结构较为复杂时,每个元素类都需要提供
Accept
方法。 -
访问者与对象耦合:当对象结构频繁变化时,访问者模式并不合适。因为每次对象结构变化时,所有访问者都需要做出相应的调整,违背了扩展性原则。
-
类型安全性问题:在访问者模式中,访问者接口方法通常针对不同的对象类型,因此需要考虑类型安全性,避免类型转换错误。
三、在 Unity 中使用 访问者模式
在 Unity 中,访问者模式可以用于在不同类型的 3D 对象(例如立方体、球体等)上执行特定操作,而无需修改这些对象的代码。以下是一个使用访问者模式的示例,展示如何在 Unity 中渲染不同的 3D 对象,并通过访问者模式实现不同操作,比如渲染、缩放等。
参考类图如下:
1、定义元素接口(IShapeElement)
首先,我们定义一个元素接口 IShapeElement
,3D 对象(立方体、球体等)将实现该接口,并接受访问者的操作。
public interface IShapeElement
{
void Accept(IShapeVisitor visitor);
}
2、定义具体的 3D 对象类(Cube 和 Sphere)
我们定义立方体和球体类,这些类实现了 IShapeElement
接口,并提供 Accept
方法来接受访问者。
using UnityEngine;
public class Cube : IShapeElement
{
private GameObject cubeObject;
public Cube()
{
cubeObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
cubeObject.name = "Cube";
cubeObject.transform.position = new Vector3(-2, 0, 0); // 设置初始位置
}
public void Accept(IShapeVisitor visitor)
{
visitor.VisitCube(this); // 立方体接受访问者
}
public void SetScale(Vector3 scale)
{
cubeObject.transform.localScale = scale; // 设置立方体缩放
}
public void SetColor(Color color)
{
cubeObject.GetComponent<Renderer>().material.color = color; // 设置立方体颜色
}
}
public class Sphere : IShapeElement
{
private GameObject sphereObject;
public Sphere()
{
sphereObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphereObject.name = "Sphere";
sphereObject.transform.position = new Vector3(2, 0, 0); // 设置初始位置
}
public void Accept(IShapeVisitor visitor)
{
visitor.VisitSphere(this); // 球体接受访问者
}
public void SetScale(Vector3 scale)
{
sphereObject.transform.localScale = scale; // 设置球体缩放
}
public void SetColor(Color color)
{
sphereObject.GetComponent<Renderer>().material.color = color; // 设置球体颜色
}
}
3、定义访问者接口(IShapeVisitor)
我们定义访问者接口 IShapeVisitor
,其中包含针对不同 3D 对象的访问操作。
public interface IShapeVisitor
{
void VisitCube(Cube cube);
void VisitSphere(Sphere sphere);
}
4、实现具体访问者类(ShapeRenderer 和 ShapeScaler)
接下来,我们创建两个具体的访问者类,分别用于渲染和缩放 3D 对象。
4.1 渲染访问者:
using UnityEngine;
public class ShapeRenderer : IShapeVisitor
{