使用unity实现计算器功能

1.搭建ui,在Canvas中新建一个panel,新建两个InputField,作为两个输入框,获取输入的数值。新建四个button组件作为点击的按钮。新建一个Text组件作为计算结果的展示。界面搭建完成如下图

 2.编写代码

using System;
using UnityEngine;
using UnityEngine.UI;

namespace JiSuanQi.UI
{
    public class JISuanQiPanel : MonoBehaviour
    {
        public Button mBtnJiaFa, mBtnJianFa, mBtnChengFa, mBtnChuFa;
        public Text mResult;
        public InputField mInputNumA;
        public InputField mInputNumB;
        private void Awake()
        {
            mBtnJiaFa.onClick.AddListener(JiaFa);
            mBtnJianFa.onClick.AddListener(JianFa);
            mBtnChengFa.onClick.AddListener(ChengFa);
            mBtnChuFa.onClick.AddListener(ChuFa);
        }

        private void JiaFa()
        {
            double result = Operation(0);
            UpdateResult(result);
        }

        private void JianFa()
        {
            double result = Operation(1);
            UpdateResult(result);
        }

        private void ChengFa()
        {
            double result = Operation(2);
            UpdateResult(result);
        }

        private void ChuFa()
        {
            double result = Operation(3);
            UpdateResult(result);
        }

        private double Operation(int index)
        {
            if (string.IsNullOrEmpty(mInputNumA.text)||string.IsNullOrEmpty(mInputNumB.text))
            {
                return -1;
            }
            double NumA = double.Parse(mInputNumA.text);
            double NumB = double.Parse(mInputNumB.text);
            switch (index)
            {
                case 0:
                    return NumA + NumB;
                case 1:
                    return NumA - NumB;
                case 2:

                    return NumA * NumB;
                case 3:
                    if (NumB == 0)
                    {
                        return -1;
                    }
                    else
                    {
                        return NumA / NumB;
                    }
                default:
                    return -1;
            }
        }

        private void UpdateResult(double result)
        {
            mResult.text = "结果:" + result;
        }
    }
}

ui组件使用拖拽的方式进行赋值。ui组件赋值的方式一种是使用代码查找transform.Find("组件的ui面板路径").getComponent<组件类型>();在Awake或者Start方法中初始化。我比较喜欢拖拽的方式赋值。因为界面是经常改动的东西,使用的拖拽的方式赋值,如果ui删除了,代码部分并不需要修改。如果使用代码查找的方式,组件删除了,代码里查找的部分就会报错,会牵扯到代码部分的修改。不过用代码查找的方式可以在脚本中看到完整的方法绑定逻辑。容易阅读。

以上简单的加减乘除代码就完成了,开发中这种方式是最容易想到的,一个界面里就实现了所有的功能。

3.以上代码功能正常,但是是有问题的。界面业务逻辑都掺杂在一起了。但是界面会有很多种,如果现在新增了一个界面,同样要使用加减乘除的业务逻辑,但是界面不是计算器的界面。这时候就要重新写一边计算的逻辑,如果以后计算的逻辑改变了,那么两个界面都要修改计算的逻辑,这样既会增加工作量,还不能保证每次修改都是一样的,导致bug的产生。如果说现在要使用gui来实现同样的计算器功能,同样要把界面业务逻辑,复制一份到gui的代码中。每次更换ui界面的时候都会遇到同样的问题。

4.代码优化:ui逻辑业务逻辑实现分离

ui界面逻辑:

using System;
using UnityEngine;
using UnityEngine.UI;

namespace JiSuanQi.UI
{
    public class JISuanQiPanel : MonoBehaviour
    {
        public Button mBtnJiaFa, mBtnJianFa, mBtnChengFa, mBtnChuFa;
        public Text mResult;
        public InputField mInputNumA;
        public InputField mInputNumB;
        private TestOperation mOperation;
        private void Awake()
        {
            mOperation = new TestOperation();
            mBtnJiaFa.onClick.AddListener(JiaFa);
            mBtnJianFa.onClick.AddListener(JianFa);
            mBtnChengFa.onClick.AddListener(ChengFa);
            mBtnChuFa.onClick.AddListener(ChuFa);
        }

        private void JiaFa()
        {
            double result = Operation(0);
            UpdateResult(result);
        }

        private void JianFa()
        {
            double result = Operation(1);
            UpdateResult(result);
        }

        private void ChengFa()
        {
            double result = Operation(2);
            UpdateResult(result);
        }

        private void ChuFa()
        {
            double result = Operation(3);
            UpdateResult(result);
        }

        private double Operation(int index)
        {
            if (string.IsNullOrEmpty(mInputNumA.text)||string.IsNullOrEmpty(mInputNumB.text))
            {
                return -1;
            }
            double NumA = double.Parse(mInputNumA.text);
            double NumB = double.Parse(mInputNumB.text);
            return mOperation.GetResult(NumA, NumB, index);
        }

        private void UpdateResult(double result)
        {
            mResult.text = "结果:" + result;
        }
    }
}

业务逻辑:

namespace JiSuanQi
{
    public class TestOperation 
    {
        public double GetResult(double NumA,double NumB,int index)
        {
            switch (index)
            {
                case 0:
                    return NumA + NumB;
                case 1:
                    return NumA - NumB;
                case 2:

                    return NumA * NumB;
                case 3:
                    if (NumB == 0)
                    {
                        return -1;
                    }
                    else
                    {
                        return NumA / NumB;
                    }
                default:
                    return -1;
            }
        }
    }
}

把业务逻辑提取到了新的类TestOperation中,这样业务逻辑就抽取出来了。

以上代码,计算功能正常。

4.代码存在的问题:TestOperation类中维护了所有的计算逻辑。如果说后面新增了其他计算逻辑,如开根,求余数,等新的计算逻辑,或者对加减乘除的逻辑进行特殊的修改,都会牵扯到TestOperation类的修改,这样如果Operation类中出现了错误,会导致计算功能异常。并且不能保证每次修改都不会影响已使用的功能。因为修改的是TestOperation这个类。

5.代码优化:

using UnityEngine;

namespace JiSuanQi
{
    public abstract class Operation
    {
        public double NumberA;
        public double NumberB;
        public abstract double GetResult();
    }
}



namespace JiSuanQi
{
    public class OperationAdd:Operation
    {
        public override double GetResult()
        {
            return NumberA + NumberB;
        }
    }
}


namespace JiSuanQi
{
    public class OperationReduce:Operation
    {
        public override double GetResult()
        {
            return NumberA - NumberB;
        }
    }
}

namespace JiSuanQi
{
    public class OperationChengFa:Operation
    {
        public override double GetResult()
        {
            return NumberA * NumberB;
        }
    }
}

namespace JiSuanQi
{
    public class OperationChuFa:Operation
    {
        public override double GetResult()
        {
            return NumberA / NumberB;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using JiSuanQi;
using UnityEngine;

public class SimpleFactory 
{
   public static Operation CreateOperate(int index)
   {
      switch (index)
      {
         case 0:
            return new OperationAdd();
         case 1:
            return new OperationReduce();
         case 2:

            return new OperationChengFa();
         case 3:
            return new OperationChuFa();
         default:
            return null;
      }
   }
}

业务逻辑优化,将Operation类提取出来,加减乘除的操作作为一个对象,Operation类作为操作的基类,基类只要持有NumA和NumB两个字段和一个GetResult方法即可。具体的实现由字类重写。实现不同的逻辑。

SimpleFactory类。属于对象创建的工厂。根据输入的index不同,实例化不同的Operation。如果后期有修改,只需要修改对应的字类即可。

猜你喜欢

转载自blog.csdn.net/xiaonan1996/article/details/125233643