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

相关推荐
郝学胜-神的一滴9 小时前
[简化版 GAMES 101] 计算机图形学 17:纹理技术从基础原理到多场景实战应用
c++·unity·游戏引擎·图形渲染·three.js·opengl·unreal
_ZHOURUI_H_1 天前
MyFramework: 同样是 Unity 游戏开发框架,和 HTFramework 的设计取向有什么不同?(下)
unity·游戏引擎·游戏开发·游戏ui·手游开发
进击的前栈1 天前
鸿蒙实战:19 页面全景汇总与 7 大共享设计模式回顾
华为·设计模式·harmonyos
刀法如飞1 天前
Spring Boot 4.1 + JDK 25 DDD开源脚手架,面向 AI 编程
设计模式·架构·ai编程
折哥的程序人生 · 物流技术专研1 天前
第8篇:模板方法模式的优缺点与面试高频考点
java·设计模式·面试·模板方法模式·行为型模式·优缺点·扩充系列
workflower1 天前
人形机器人全身运动控制能力大幅提升
人工智能·深度学习·机器学习·设计模式·机器人·自动化
折哥的程序人生 · 物流技术专研1 天前
Java 23 种设计模式:从踩坑到精通 | 备忘录模式 —— 快照与撤销,给对象装一个“后悔药”
java·设计模式·备忘录模式·行为型模式·java设计模式·从踩坑到精通·撤销重做
Kel1 天前
万物皆 Runnable:LangChain 如何用一个接口统一模型、链与图
人工智能·设计模式·架构
ttod_qzstudio1 天前
【软考设计模式】策略模式:算法族的封装与动态切换精讲
设计模式·策略模式
咖啡八杯2 天前
GoF设计模式——迭代器模式
java·后端·设计模式·迭代器模式