5.Unity面向对象-依赖倒置原则

依赖倒置原则(DIP)指出高层模块不应该直接从低层模块导入任何东西。两者都应该依赖于抽象。

让我们解译这是什么意思。当一个类与另一个类有关系时,它有依赖或耦合。软件设计中的每个依赖都带有一些风险。

如果一个类对另一个类的工作方式了解太多,修改第一个类可能会损坏第二个类,反之亦然。高耦合被认为是不干净的代码实践。应用程序中一个地方的错误可能会滚雪球成很多。

理想情况下,目标是尽量减少类之间的依赖关系。每个类还需要其内部部分协同工作,而不是依赖外部连接。当你的对象基于内部或私有逻辑运行时,它被认为是内聚的。

在最佳情况下,目标是松耦合和高内聚。

你需要能够修改和扩展你的游戏应用程序。如果它是脆弱的并抵制修改,请调查它当前的结构方式。依赖倒置原则可以帮助减少类之间的紧密耦合。

在构建应用程序中的类时,有些自然"高级",有些"低级"。高级类依赖于低级类来完成某事。SOLID告诉我们切不要这样干。

假设你正在制作一个角色探索关卡并触发打开门的游戏。你可能想要创建一个名为Switch的类和另一个名为Door的类。

没有依赖倒置

Switch(高级)直接依赖于Door(低级)类。在高级层面,你希望角色移动到特定位置并发生某事。Switch将负责这一点。

在低级层面是另一个类Door,它包含如何打开门几何体的实际实现。为简化起见,添加了一个Debug.Log语句来表示开门和关门的逻辑。

复制代码
public class Switch : MonoBehaviour
{
    public Door door;
    public bool isActivated;
    
    public void Toggle()
    {
        if (isActivated)
        {
            isActivated = false;
            door.Close();
        }
        else
        {
            isActivated = true;
            door.Open();
        }
    }
}

public class Door : MonoBehaviour
{
    public void Open()
    {
        Debug.Log("The door is open.");
    }
    
    public void Close()
    {
        Debug.Log("The door is closed.");
    }
}

Switch可以调用Toggle方法来打开和关闭门。它有效,但问题是从Door直接向Switch连接了依赖。如果Switch的逻辑需要不仅仅适用于门,例如激活一盏灯或巨型机器人,该怎么办?

你可以在Switch类中添加额外的方法,但你违反了开闭原则。每次你想扩展功能时都必须修改原始代码。

再次是抽象来拯救。你可以在你的类之间插入一个名为ISwitchable的接口。

使用依赖倒置

两个类之间的接口ISwitchable

ISwitchable只需要一个公共属性,以便你知道它是否处于活动状态,再加上几个激活和停用它的方法。

复制代码
public interface ISwitchable
{
    public bool IsActive { get; }
    public void Activate();
    public void Deactivate();
}

然后Switch变成这样,依赖于ISwitchable客户端,而不是直接依赖于门。

复制代码
public class Switch : MonoBehaviour
{
    public ISwitchable client;
    
    public void Toggle()
    {
        if (client.IsActive)
        {
            client.Deactivate();
        }
        else
        {
            client.Activate();
        }
    }
}

另一方面,你需要重构Door来实现ISwitchable:

复制代码
public class Door : MonoBehaviour, ISwitchable
{
    private bool isActive;
    public bool IsActive => isActive;
    
    public void Activate()
    {
        isActive = true;
        Debug.Log("The door is open.");
    }
    
    public void Deactivate()
    {
        isActive = false;
        Debug.Log("The door is closed.");
    }
}

现在你倒置了依赖。接口在它们之间创建了一个抽象,而不是将开关硬连线到门。Switch不再直接依赖于门特定的方法(Open和Close)。相反,它使用ISwitchable的Activate和Deactivate。

这个小而重要的变化促进了可重用性。Switch以前只与Door一起工作,现在它与任何实现ISwitchable的东西一起工作。

这使你能够创建Switch可以激活的更多类。高级Switch将有效,无论是活板门还是激光束。它只需要一个实现ISwitchable的兼容客户端。

Switch现在可以激活任何ISwitchable对象。

与SOLID的其余部分一样,依赖倒置原则要求你检查你通常如何设置类之间的关系。通过松耦合方便地扩展你的项目。

相关推荐
万兴丶3 小时前
Unity 用AI自动开发游戏近一年----最新Cursor使用心得
人工智能·游戏·unity·cursor
张老师带你学15 小时前
UnityVR弯曲UI
科技·游戏·unity·游戏引擎·模型
张老师带你学16 小时前
unity作业,街角小场景
科技·游戏·unity·游戏引擎·模型
加个鸡腿儿18 小时前
从"包裹器"到"确认按钮"——一个组件的三次重构
前端·vue.js·设计模式
ALex_zry19 小时前
现代C++设计模式实战:从AIDC项目看工业级代码架构
c++·设计模式·架构
mxwin19 小时前
Unity Shader LOD:动态 Shader 等级切换技术详解
unity·游戏引擎·shader
ALex_zry19 小时前
C++高性能日志与监控系统设计
c++·unity·wpf
君主黑暗20 小时前
设计模式-工厂模式
设计模式
han_1 天前
JavaScript设计模式(四):发布-订阅模式实现与应用
前端·javascript·设计模式