zoukankan      html  css  js  c++  java
  • 代码重构与单元测试——将方法移到合适[依赖]的类中(六)

     

    六、重构3:将方法移到合适[依赖]的类中

            经过之前的重构(见文章 代码重构与单元测试——“提取方法”重构(三)  代码重构与单元测试——对方法的参数进行重构(五) ),我们从Statement()方法中提取了两个方法。观察这两个重构后的方法我们不难看出,这两个封装出来的新方法都只需要一个参数,这个参数就是Rental类的对象。也就是这两个方法都依赖于Rental类,而对该方法所在的当前类不太依赖。之所以会这种情况,是因为这两个方法放错了地方,因为这两个方法放在Customer类中但不依赖与Customer类而依赖于Rental类,那就足以说明这两个方法应该放在Rental类中。

    1.经过简单的分析后,我们就可以决定要将新提取的方法放到Rental类中,并且方法的参数去掉。因为方法在Rental类中,所以在方法中直接使用this即可。将计算金额的方法和计算积分的方法移到Rental类中。

    2. 在Visual Studio 2019代码编辑器中打开Rental.cs文件,将GetAmount和GetFrequentRenterPoints方法从Customer.cs文件中移到Rental.cs文件中。具体代码如下所示:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    
    namespace LeasePowerBank
    {
    
        /// <summary>
        /// 租赁类
        /// </summary>
        public class Rental
        {
    
          public  PowerBank Power ; //充电宝名称
            public int RentedTime;//租赁时间
    
            public Rental(PowerBank powerbk,int rentedTime)
            {
    
                Power = powerbk;
                RentedTime = rentedTime;
            }
    
    
            public int GetFrequentRenterPoints()
            {
    
                int frequentRenterPoints = 0;
     
                decimal amount = GetAmount();
                //计算积分
                if (this.Power.PriceCode == PowerBank.HighTraffic && this.RentedTime > 4)
    
                {
                    frequentRenterPoints += (int)Math.Ceiling(amount * 1.5M);
    
                }
                else
                    frequentRenterPoints += (int)Math.Ceiling(amount);
    
                return frequentRenterPoints;
            }
    
            /// <summary>
            /// 根据充电宝订单,计算总金额
            /// </summary>
            /// <param name="item"></param>
            /// <returns></returns>
           public decimal GetAmount()
            {
                decimal amount = 0M;
    
    
                switch (this.Power.PriceCode)
                {
                    case 0:
                        amount = this.RentedTime;
                        if (this.RentedTime > 12)
                        {
                            amount = 12;
                        }
                        break;
                    case 1:
                        amount = this.RentedTime * 3;
                        if (this.RentedTime > 24)
                        {
                            amount = 24;
                        }
                        break;
                    case 2:
     
                        amount = this.RentedTime * 5;
                        if (this.RentedTime > 50)
                        {
                            amount = 50;
                        }
                        break;
                    default:
                        break;
                }
                return amount;
            }
    
       }
    }
    3. 在我们的Customer中的Statement()方法中的代码也要进行一些修改,在计算金额和计算积分时,直接调用Rental中的方法。代码如下:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace LeasePowerBank
    {
    
        /// <summary>
          /// 客户类
        /// </summary>
       public  class Customer
        {
    
            string Name;//用户名称
        public    List<Rental> listRentals=new List<Rental>();//用户租赁的充电宝
    
            public Customer(string name)
            {
    
                Name = name;
            }
            public void AddRental(Rental rental)
            {
                listRentals.Add(rental);
            }
    
    
            public string Statement()
            {
    
                decimal totalAmount = 0M; //总金额
                int frequentRenterPoints = 0; //用户积分
                string result = $"{Name} 的租赁账单:
    ";
    
              
                foreach (var item in listRentals)
                {
                    decimal amount = item.GetAmount();//总价计算
                    totalAmount += amount;
    
                    frequentRenterPoints = item.GetFrequentRenterPoints();
                }
    
     
                result += $"总金额为:{totalAmount}
    ";
                result += $"你本次获得了:{frequentRenterPoints}积分 ";
    
                return result;
    
            }
        }
    }   

    4. 在Visual Studio 2019中打开测试项目LeasePowerBankTest中的UnitTest1.cs测试类文件,对单元测试中的测试用例我们也要进行一下修改。将调用Customer类中的方法,修改为调用Rental类中的方法。代码如下:

     [TestMethod]
            public void ValidGetAmountTest()
            {
                double expected = 5;
    
                //创建用户
                var customer = new Customer("张三");
    
                //创建充电宝
                PowerBank regularPowerBank = new PowerBank("低-充电宝", PowerBank.LowTraffic);
     
    
                //创建租赁数据
                var rental1 = new Rental(regularPowerBank, 5);
    
                // Act
                double actual = (double)rental1.GetAmount();
    
                // Assert      
                Assert.AreEqual(expected,actual,0.001, $"总金额计算错误,实际计算金额{actual},期望金额:{expected}");
    
            }
    
            [TestMethod]
            public void ValidGetFrequentRenterPointsTest()
            {
                int expected = 5;
                //创建用户
                var customer = new Customer("张三");
                //创建充电宝
                PowerBank regularPowerBank = new PowerBank("低-充电宝", PowerBank.LowTraffic);
    
     
                //创建租赁数据
                var rental1 = new Rental(regularPowerBank, 5);
                // Act
                int actual = rental1.GetFrequentRenterPoints();
    
                // Assert
                Assert.AreEqual(expected, actual, 0.001, "积分计算错误");
            }

      5. 在Visual Studio 2019的菜单栏上找到“测试-->运行所有测试”菜单项。或者在“测试资源管理器中”选择 “在视图中运行所有测试”按钮, 运行测试用例。监测重构的结果是否正确。如下图。

     

  • 相关阅读:
    【重要】攻击动作时间段判断~使用动画time比较动画length和使用一个变量数组做延迟
    角色头上冒数字
    ApplicationListener接口的生命周期
    Blender软件基本介绍(3D建模软件)
    unity中给图片换颜色
    Unity中建立文本保存数据
    UGUI脚本添加Btn回调的方法
    碰撞体速度过快穿透的问题
    Unity中的点击,长按,划动
    在对话系统中实现打字机效果
  • 原文地址:https://www.cnblogs.com/chillsrc/p/15108825.html
Copyright © 2011-2022 走看看