Skip to content

UniRx入门

OldMoM edited this page Jun 14, 2021 · 4 revisions

为什么代码难以修改

为了解这个问题,我们先从一个控制玩家移动的简单脚本分析入手,很多教程或新手都会将代码写成如下形式。

 public class NaivePlayerController : MonoBehaviour
    {
        //实体(Enitity)
        public Rigidbody2D rigid;
        public Animator animator;
        //数据
        public float speed;
        // Start is called before the first frame update
        void Start()
        {
            rigid = GetComponent<Rigidbody2D>();
            animator = GetComponent<Animator>();
        }

        // Update is called once per frame
        void Update()
        {
            //Rigidbody2D工作逻辑
            rigid.velocity = Vector2.right * Input.GetAxisRaw("Horizontal") * speed;
            //Animator工作逻辑
            if (Input.GetAxisRaw("Horizontal") == 0)
            {
                animator.Play("player_idle");
            }
            else
            {
                animator.Play("player_run");
            }
        }
    }

在这个脚本看起来功能运行正常,其实有以下隐患:

  • 数据和功能逻辑代码全放在一个脚本中。当数据被分散在各个脚本中时,就会造成数据访问的困难,然后形成很深的引用路径,每个脚本就像套娃一样一层套一层的进行引用。

  • 脚本中出现了大量闭包(Closure)。类方法直接引用类成员变量时,这意味着这个方法和类被牢牢粘在了一起。我们在重构或者修改代码时,想要将AClass.FuctionA()移动至BClass,但FunctionA中含有AClass成员memberA,肯定没办法直接移动。那如果memberA又恰好依赖于ClassC,对FunctionA的移动简直就是一场灾难。

  • 脚本具有太多功能,违背单一职责原则。按键监听、速度计算、移动RigidBody和播放动画4项功能全被揉进了这个脚本。当脚本容量被扩充至400行时,又有人能够说清脚本有那些功能呢?当开发进入中后期时,从盘根错节的引用关系网中将相同功能的代码分离出来何尝不是一种灾难呢?

  • 这个脚本无法进行测试。第一,脚本继承自Mono类,无法使用new实例化;第二,脚本是完全面向过程的,无法执行单元测试Arrange-Act-Assert流程。

我将在下面的篇章中对这4个问题进行解释。

Clone this wiki locally