1.Unity面向对象-单一职责原则

单一职责原则

一个类应该只有一个更改理由,即只有单一职责。

SOLID原则中最重要的第一条是单一职责原则(SRP),它指出每个模块、类或函数负责一件事,并仅封装该部分逻辑。

用许多较小的组件组装你的项目,而不是构建庞大的类。更短的类和方法更容易解释、理解和实现。

如果你用Unity工作了一段时间,你可能已经熟悉这个概念。当你创建一个GameObject时,它包含各种较小的组件。例如,它可能包含:

  • 一个MeshFilter,存储对3D模型的引用
  • 一个Renderer,控制模型表面在屏幕上的显示方式
  • 一个Transform组件,存储缩放、旋转和位置
  • 一个Rigidbody,如果需要与物理模拟交互

每个组件只做一件事,而且做得很好。你整个场景都是用GameObject构建的。它们组件之间的交互使得游戏成为可能。

你将以相同的方式构建脚本组件。设计它们,使每个组件都能被清楚地理解。然后让它们协同工作,形成复杂的行为。

如果你忽略单一职责,你可能会创建这样一个自定义组件:

一个具有多重职责的Player脚本

复制代码
public class UnrefactoredPlayer : MonoBehaviour
{
    [SerializeField] private string inputAxisName;
    [SerializeField] private float positionMultiplier;
    private float yPosition;
    private AudioSource bounceSfx;
    
    private void Start()
    {
        bounceSfx = GetComponent<AudioSource>();
    }
    
    private void Update()
    {
        float delta = Input.GetAxis(inputAxisName) * Time.deltaTime;
        yPosition = Mathf.Clamp(yPosition + delta, -1, 1);
        transform.position = new Vector3(transform.position.x, yPosition * positionMultiplier, transform.position.z);
    }
    
    private void OnTriggerEnter(Collider other)
    {
        bounceSfx.Play();
    }
}

这个UnrefactoredPlayer类混合了多种职责。它在玩家与某物碰撞时播放声音,管理输入,并处理移动。即使这个类目前相对较短,随着项目的发展,维护起来也会变得棘手。考虑将Player类拆分成更小的类。

重构后的Player类,具有单一职责

复制代码
[RequireComponent(typeof(PlayerAudio), typeof(PlayerInput), typeof(PlayerMovement))]
public class Player : MonoBehaviour
{
    [SerializeField] private PlayerAudio playerAudio;
    [SerializeField] private PlayerInput playerInput;
    [SerializeField] private PlayerMovement playerMovement;
    
    private void Start()
    {
        playerAudio = GetComponent<PlayerAudio>();
        playerInput = GetComponent<PlayerInput>();
        playerMovement = GetComponent<PlayerMovement>();
    }
}

public class PlayerAudio : MonoBehaviour { ... }
public class PlayerInput : MonoBehaviour { ... }
public class PlayerMovement : MonoBehaviour { ... }

Player脚本仍然可以管理其他脚本组件,但每个类只做一件事。这种设计使代码更易于修改,特别是随着项目需求的变化。

另一方面,你需要将单一职责原则与常识保持平衡。不要过度简化到极端,创建只有一种方法的类。

在处理单一职责原则时,牢记这些目标:

  • 可读性:短类更容易阅读。没有硬性规定,但许多开发者将限制设为200-300行。自行或作为团队决定什么是"短"。超过这个阈值时,决定是否可以将其重构为更小的部分。
  • 可扩展性:你更容易继承小类。修改或替换它们而不必担心破坏意外的功能。
  • 可重用性:将你的类设计得小而模块化,这样你就可以将它们重用到游戏的其他部分。

进行重构时,需考虑代码重排如何提升自身或团队成员的工作效率与体验。

刚开始时多花些功夫,日后就能省去不少麻烦。

简单并不容易

简单性在软件设计中经常被讨论,是可靠性的前提。你的软件设计能处理生产中的变化吗?你能随着时间的推移扩展和维护你的应用程序吗?

本指南中介绍的许多设计模式和原则都帮助你实施简单性。这样做,它们使你的代码更可扩展、更灵活和更具可读性。但是,它们需要一些额外的工作和规划。"简单"不等于"容易"。

虽然你可以不使用这些模式创建相同的功能(而且通常更快),但快速和容易并不一定能导致简单。简单意味着专注。设计它做一件事,不要用其他任务使它复杂化。

请查看Rich Hickey的讲座"Simple Made Easy",了解简单性如何帮助你构建更好的软件。

相关推荐
上班摸鱼下班游戏7 小时前
从零开始玩转 DOTween
unity·游戏引擎
阿松爱学习13 小时前
【Unity开发】Unity长截图功能实现
unity·c#·游戏引擎
小小数媒成员13 小时前
Rect Transform
游戏·unity·游戏引擎
是2的10次方啊14 小时前
设计模式与生活①:你的脸,为什么不能有第二个?
设计模式
_oP_i15 小时前
Windows 11 家庭中文版 25H2
c#
unicrom_深圳市由你创科技15 小时前
电池化成曲线MES追溯:关键点提取与验证
c#
老王IT16 小时前
C#语言基础语法介绍
开发语言·c#
高晶16 小时前
ARM 嵌入式 Linux 命令系统 BusyBox 实战指南
linux·设计模式·程序员
高晶16 小时前
语音合成与变声技术十大业务场景落地实战:从电商直播到规模化生产
设计模式·程序员
人丰17 小时前
一次生产卡顿复盘:BI 数据抽取引发 PostgreSQL 长事务事故
数据库·c#