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

相关推荐
玖玥拾6 小时前
Cocos学习笔记:滚动视图、关卡系统与本地存储
游戏引擎·cocos2d
元气少女小圆丶13 小时前
SenseGlove Nova 2+Unity开发笔记2
笔记·unity·游戏引擎
Oiiouui16 小时前
Godot(4.x): 游戏管理器: Godot 内注入数据处理与总接口实现
游戏·游戏引擎·godot
想不明白的过度思考者18 小时前
Unity学习笔记——虚拟摇杆实现笔记(事件触发器的使用、UGUI 坐标转换)
笔记·学习·unity
魔士于安18 小时前
unity volumefog带各种demo第一人称 wsad 穿墙控制
游戏·unity·游戏引擎·贴图·模型
魔士于安21 小时前
红色文化馆技术文档
前端·unity·游戏引擎·贴图·模型
LONGZETECH21 小时前
Unity 3D工业级教育软件实战:200+无人机装调任务的碰撞检测与交互落地
3d·unity·架构·游戏引擎·无人机·交互·cocos2d
淡海水21 小时前
08-认知篇-对比-injectfix深度解析
unity·c#·热更新·clr·hybrid·injectfix
迪普阳光开朗很健康21 小时前
BepInEx 插件开发文档中文翻译 - 项目分享
unity·bepinex
元气少女小圆丶1 天前
SenseGlove Nova 2+Unity开发笔记1
笔记·学习·unity