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的类,长期添加新代码就变得更简单了。

相关推荐
呆呆敲代码的小Y2 小时前
UnityMCP+Claude+VSCode,构建最强AI游戏开发环境
人工智能·vscode·游戏·unity·游戏引擎·u3d·mcp
C蔡博士2 小时前
Unity TextMeshPro 中文本地化:动态生成最小字体集(解决边缘模糊、乱码问题)
unity·游戏引擎
m0_630182462 小时前
Unity TMP 中文字体生成
unity·游戏引擎
weixin_409383123 小时前
godot y排序定位 sprite原点 等轴视角地图块测试 isometric 碰撞测试 初学godot
游戏引擎·godot
万兴丶4 小时前
Unity用C#完成抖音小游戏接入引力引擎(Gravity Engine)完整指南,一篇文章讲清楚!
unity·c#·游戏引擎·抖音
WarrenMondeville6 小时前
4.Unity面向对象-接口隔离原则
java·unity·接口隔离原则
WarrenMondeville7 小时前
3.Unity面向对象-里氏替换原则
unity·游戏引擎·里氏替换原则
WarrenMondeville8 小时前
5.Unity面向对象-依赖倒置原则
unity·设计模式·依赖倒置原则
万兴丶9 小时前
Unity 用AI自动开发游戏近一年----最新Cursor使用心得
人工智能·游戏·unity·cursor