重构影片租赁系统(上)

重构之前代码如下

影片类:

View Code
public class Moive
    {
        public Moive()
        {
            this.MoiveName = "十二生肖";
            this.MoiveType = (int)MoivesType.New;
        }

        /// <summary>
        /// 影片名称
        /// </summary>
        public string MoiveName { get; set; }
        /// <summary>
        /// 影片类型
        /// </summary>
        public int MoiveType { get; set; }
        
        /// <summary>
        /// 返回影片类型
        /// </summary>
        /// <returns></returns>
        public int GetMoiveType()
        {
            return this.MoiveType;
        }
    }

租赁类:

View Code
public class Rental
    {
        private Moive aMoive=new Moive();

        public Moive GetMoive()
        {
            return aMoive;
        }

        /// <summary>
        /// 返回租片天数
        /// </summary>
        /// <returns></returns>
        public int GetRentalDay()
        {
            return 5;
        }
    }

客户类:

View Code
public class Customer
    {
        public List<Rental> rentalList = new List<Rental>() { new Rental(),new Rental(),new Rental()};
        
        public string Name { get; set; }

        /// <summary>
        /// 打印消费信息
        /// </summary>
        /// <returns></returns>
        public string Print()
        {
            double totalMoney = 0;
            int freequen = 0;
            double currentMoney=0;
            Console.WriteLine("customer name is "+this.Name);
            //********************************
            //其他业务逻辑
            //********************************
            foreach (var aRental in rentalList)
            {
                switch (aRental.GetMoive().GetMoiveType())
                {
                    case (int)MoivesType.Normal:
                        {
                            currentMoney = aRental.GetRentalDay() * 1.2;
                            break;
                        }
                    case (int)MoivesType.New:
                        {
                            currentMoney = aRental.GetRentalDay() * 3.3;
                            break;
                        }
                    case (int)MoivesType.Child:
                        {
                            currentMoney = aRental.GetRentalDay() * 0.3;
                            break;
                        }
                }
                Console.WriteLine("movie name is "+aRental.GetMoive().MoiveName+" and currentTotalMoney equals "+currentMoney);

                if ((int)MoivesType.New == aRental.GetMoive().MoiveType &&
                    aRental.GetRentalDay() > 1)
                {
                    freequen++;
                }

                totalMoney+=currentMoney;
            }
            return "totalMoney equals " + totalMoney + " you earned " + freequen + " frequent";
        }
    }

首先,让我们先看看客户类中Print()这个方法,该方法中存在switch语句,将其提出一个单独的方法:

View Code
        private static double AmountFor(double currentMoney, Rental aRental)
        {
            switch (aRental.GetMoive().GetMoiveType())
            {
                case (int)MoivesType.Normal:
                    {
                        currentMoney = aRental.GetRentalDay() * 1.2;
                        break;
                    }
                case (int)MoivesType.New:
                    {
                        currentMoney = aRental.GetRentalDay() * 3.3;
                        break;
                    }
                case (int)MoivesType.Child:
                    {
                        currentMoney = aRental.GetRentalDay() * 0.3;
                        break;
                    }
            }
            Console.WriteLine("movie name is " + aRental.GetMoive().MoiveName + " and currentTotalMoney equals " + currentMoney);
            return currentMoney;
        }

此时再将double currentMoney这个多余的参数给去掉:

View Code
        private static double AmountFor(Rental aRental)
        {
            double currentMoney = 0;
            switch (aRental.GetMoive().GetMoiveType())
            {
                case (int)MoivesType.Normal:
                    {
                        currentMoney = aRental.GetRentalDay() * 1.2;
                        break;
                    }
                case (int)MoivesType.New:
                    {
                        currentMoney = aRental.GetRentalDay() * 3.3;
                        break;
                    }
                case (int)MoivesType.Child:
                    {
                        currentMoney = aRental.GetRentalDay() * 0.3;
                        break;
                    }
            }
            Console.WriteLine("movie name is " + aRental.GetMoive().MoiveName + " and currentTotalMoney equals " + currentMoney);
            return currentMoney;
        }

再仔细观察后不难发现该方法中使用的对象属于租赁类,因此我们将该方法放置租赁类当中,将方法参数移除,并将方法体内aRental改为this当前对象的调用:

View Code
public class Rental
    {
        private Moive aMoive=new Moive();

        public Moive GetMoive()
        {
            return aMoive;
        }

        /// <summary>
        /// 返回租片天数
        /// </summary>
        /// <returns></returns>
        public int GetRentalDay()
        {
            return 5;
        }

        public  double AmountFor()
        {
            double currentMoney = 0;
            switch (this.GetMoive().GetMoiveType())
            {
                case (int)MoivesType.Normal:
                    {
                        currentMoney = this.GetRentalDay() * 1.2;
                        break;
                    }
                case (int)MoivesType.New:
                    {
                        currentMoney = this.GetRentalDay() * 3.3;
                        break;
                    }
                case (int)MoivesType.Child:
                    {
                        currentMoney = this.GetRentalDay() * 0.3;
                        break;
                    }
            }
            Console.WriteLine("movie name is " + this.GetMoive().MoiveName + " and currentTotalMoney equals " + currentMoney);
            return currentMoney;
        }
    }

客户类修改后代码如下:

View Code
 public class Customer
    {
        public List<Rental> rentalList = new List<Rental>() { new Rental(),new Rental(),new Rental()};
        
        public string Name { get; set; }

        /// <summary>
        /// 打印消费信息
        /// </summary>
        /// <returns></returns>
        public string Print()
        {
            double totalMoney = 0;
            int freequen = 0;
            double currentMoney=0;
            Console.WriteLine("customer name is "+this.Name);
            //********************************
            //其他业务逻辑
            //********************************
            foreach (var aRental in rentalList)
            {
                currentMoney = aRental.AmountFor();

                if ((int)MoivesType.New == aRental.GetMoive().MoiveType &&
                    aRental.GetRentalDay() > 1)
                {
                    freequen++;
                }

                totalMoney+=currentMoney;
            }
            return "totalMoney equals " + totalMoney + " you earned " + freequen + " frequent";
        }

以同样的手法继续重构pinrt()方法,再次修改后的客户类如下:

View Code
public class Customer
    {
        public List<Rental> rentalList = new List<Rental>() { new Rental(),new Rental(),new Rental()};
        
        public string Name { get; set; }

        /// <summary>
        /// 打印消费信息
        /// </summary>
        /// <returns></returns>
        public string Print()
        {
            double totalMoney = 0;
            int freequen = 0;
            //double currentMoney=0; //去除临时变量
            Console.WriteLine("customer name is " + this.Name);
            //********************************
            //其他业务逻辑
            //********************************
            foreach (var aRental in rentalList)
            {
                freequen += aRental.GetFrenquent();

                totalMoney += aRental.AmountFor(); ;
            }
            //return "totalMoney equals " + totalMoney + " you earned " + freequen + " frequent";
            return "totalMoney equals " + totalMoney + " you earned " + freequen + " frequent";
        }

租赁类如下:

View Code
public class Rental
    {
        private Moive aMoive=new Moive();

        public Moive GetMoive()
        {
            return aMoive;
        }

        /// <summary>
        /// 返回租片天数
        /// </summary>
        /// <returns></returns>
        public int GetRentalDay()
        {
            return 5;
        }

        public  double AmountFor()
        {
            double currentMoney = 0;
            switch (this.GetMoive().GetMoiveType())
            {
                case (int)MoivesType.Normal:
                    {
                        currentMoney = this.GetRentalDay() * 1.2;
                        break;
                    }
                case (int)MoivesType.New:
                    {
                        currentMoney = this.GetRentalDay() * 3.3;
                        break;
                    }
                case (int)MoivesType.Child:
                    {
                        currentMoney = this.GetRentalDay() * 0.3;
                        break;
                    }
            }
            Console.WriteLine("movie name is " + this.GetMoive().MoiveName + " and currentTotalMoney equals " + currentMoney);
            return currentMoney;
        }

        public int GetFrenquent()
        {
            int freequen = 0;
            if ((int)MoivesType.New == this.GetMoive().MoiveType &&
                this.GetRentalDay() > 1)
            {
                freequen++;
            }
            return freequen;
        }
    }

在此重构过程中,主要是将实现某一功能的代码段分别提出为一个单独的方法,然后将不必要的方法参数给去掉,并将该方法放置其所对应的类中去,再修改之前引用的地方,改为引用重构之后的方法,同时,可以将一些不需要的临时变量给去除。
注意:

重构的步骤需要一步步执行,每次执行完之后需要编译、测试,确认此次重构没有问题了之后,然后再进行下一步的重构。

只有写出人类看的懂的代码,才是优秀的程序员。

代码下载

原文地址:https://www.cnblogs.com/buguangchao/p/2973735.html