• 重构影片租赁系统(上)


    重构之前代码如下

    影片类:

    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;
            }
        }

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

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

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

    代码下载

  • 相关阅读:
    [BIRT]WebViewerExample4.6.0版本启动报java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
    [转载][MySQL]slave have equal MySQL Server UUIDs原因及解决
    mvn package时设置了maven.test.skip=true依旧执行单元测试
    [转载]log4j输出日志级别控制
    使用Apache pdfbox: 从Linux安装字体到log4j设置日志级别
    [转载]过滤器(filter)和拦截器(interceptor)区别
    设置response的Header使得Chrome浏览器打开PDF而不自动下载
    cf 1174 D Ehab and the Expected XOR Problem
    cf 1169 C Increasing by Modulo
    蓝精灵之小饭写数字
  • 原文地址:https://www.cnblogs.com/buguangchao/p/2973735.html
Copyright © 2020-2023  润新知