2.Unity面向对象- 开闭原则

SOLID设计中的开闭原则(OCP)指出类必须对扩展开放但对修改关闭。构建你的类,这样你就可以创建新行为而不修改原始代码。

一个经典的例子是计算形状的面积。你可以创建一个名为AreaCalculator的类,其中有返回矩形和圆形面积的方法。

为了计算面积,Rectangle类有宽度和高度。A Circle只需要半径和π的值。

复制代码
public class AreaCalculator
{
    public float GetRectangleArea(Rectangle rectangle)
    {
        return rectangle.width * rectangle.height;
    }
    
    public float GetCircleArea(Circle circle)
    {
        return circle.radius * circle.radius * Mathf.PI;
    }
}

public class Rectangle
{
    public float width;
    public float height;
}

public class Circle
{
    public float radius;
}

这工作得很好,但如果你想向AreaCalculator添加更多形状,你需要为每个新形状创建一个新方法。假设你想传递一个五边形或八边形怎么办?如果你需要20个更多的形状怎么办?AreaCalculator类会很快失控。

你可以创建一个名为Shape的基类,并创建一个方法来处理形状。但是,这样做需要在逻辑内部使用多个if语句来处理每种类型的形状。这不会很好地扩展。

你希望对扩展开放(使用新形状的能力)而不修改原始代码(AreaCalculator的内部)。虽然它能工作,但当前的AreaCalculator违反了开闭原则。

我们如何设计AreaCalculator来接受新形状?

相反,考虑定义一个抽象Shape类:

复制代码
public abstract class Shape
{
    public abstract float CalculateArea();
}

这包含一个名为CalculateArea的抽象方法。然后,如果你让Rectangle和Circle继承自Shape,每个形状可以计算自己的面积并返回以下结果:

复制代码
public class Rectangle : Shape
{
    public float width;
    public float height;
    
    public override float CalculateArea()
    {
        return width * height;
    }
}

public class Circle : Shape
{
    public float radius;
    
    public override float CalculateArea()
    {
        return radius * radius * Mathf.PI;
    }
}

AreaCalculator可以简化为这样:

复制代码
public class AreaCalculator
{
    public float GetArea(Shape shape)
    {
        return shape.CalculateArea();
    }
}

修订后的AreaCalculator类现在可以获取任何正确实现抽象Shape类的形状的面积。然后你可以在不更改其任何原始源代码的情况下扩展AreaCalculator功能。

为开闭原则修订类

每次你需要一个新的多边形,只需定义一个继承自Shape的新类。然后每个子类化的形状覆盖CalculateArea方法以返回正确的面积。

这种新设计使调试更容易。如果一个新形状引入错误,你不必重新访问AreaCalculator。旧代码保持不变,所以你只需要检查新代码中是否存在错误的逻辑。

在Unity中创建新类时,利用接口和抽象。这有助于避免在你的逻辑中出现难以扩展的笨拙的switch或if语句。一旦你习惯于设置尊重OCP的类,长期添加新代码就变得更简单了。

相关推荐
寂寞的船1 天前
【Unity Bug挑战】第12期 Awaitable 二次 await 死锁之谜 —— 为什么同一个异步操作等两次就卡死?
unity·c#·游戏引擎·bug
一名网络界的大虾1 天前
AI核心功能解析:问答、编码与逻辑推理
命令模式·开闭原则
探求虚无2 天前
用 AI 在 Unity 里做一款 RTS:最难的不是生成代码,而是证明它真的能玩
人工智能·unity·游戏引擎
17岁的勇气3 天前
Unity Shader unity文档学习笔记(二十二):shader变体
笔记·学习·unity
寂寞的船4 天前
【Unity知识速递】第10期 Unity GC 零分配实战:从 UnityEngine.Pool 到手动 GC 控制的全链路优化
jvm·unity·c#·游戏引擎·lucene
Martina_03215 天前
AI生成3D场景的霓虹灯一开就糊成光团?用6步检查Emissive、Bloom与曝光
人工智能·3d·ai·自然语言处理·游戏引擎·材质·贴图
寂寞的船6 天前
【Unity知识速递】第8期 IL2CPP 托管堆内存碎片与原生堆交互机制深度解析
unity·游戏引擎·交互
寂寞的船7 天前
【Unity知识速递】第5期 Unity 6.2 深度解析:AI Assistant 登场,World Space UI 与 Sentis 全面升级
人工智能·ui·unity
寂寞的船7 天前
【Unity知识速递】第4期 MCP for Unity:用 AI 自然语言控制编辑器
人工智能·unity·编辑器
淡海水7 天前
09-04-内存-Unity原生对象生命周期
unity·c#·游戏引擎·gc