zoukankan      html  css  js  c++  java
  • C# 重构

    一、Pull Up Field 提取字段

    多个类中有相同的字段,可以提取到父类中。

    重构前:

       public class Engineer
        {
            public string name { get; set; }
        }
    
        public class Salesman
        {
            public string name { get; set; }
        }

    重构后:

        public class Employee
        {
            public string name { get; set; }
        }
    
    
        public class Engineer:Employee
        {
            
        }
    
        public class Salesman : Employee
        {
             
        }

    二、Pull_Up_Method 提取方法

    多个类中有相同或相似的方法时,可以提取到父类

    重构前:

        class Preferred_Customer 
        {
            void CreateBill(DateTime date)
            {
                double chargeAmount = ChargeFor();
                AddBill(date, chargeAmount);
            }
    
    
            void AddBill(DateTime date, double amount)
            {
                 
            }
    
            public  double ChargeFor()
            {
                return 1;
            }
        }
        class Regular_Customer
        {
            void CreateBill(DateTime date)
            {
                double chargeAmount = ChargeFor();
                AddBill(date, chargeAmount);
            }
    
    
            void AddBill(DateTime date, double amount)
            {
    
            }
    
            double ChargeFor()
            {
                return 2;
            }
        }

    重构后:

     abstract class Customer
        {
            void CreateBill(DateTime date)
            {
                double chargeAmount = ChargeFor();
                AddBill(date, chargeAmount);
            }
    
    
            void AddBill(DateTime date, double amount)
            {
    
            }
    
            public abstract double ChargeFor();
    
    
        }
    
        class Preferred_Customer: Customer
        {
            public override  double ChargeFor()
            {
                return 1;
            }
        }
    
        class Regular_Customer:Customer
        {
    
            public override  double ChargeFor()
            {
                return 2;
            }
        }

    子类中的ChargeFor方法实现不同,父类中的ChargeFor为抽象方法。子类通过重写实现。

    三、Pull_Up_Constructor_Body 提取构造函数

    多个类的构造函数代码类似,可以提取到父类中

    重构前:

        class Manager 
        {
            string _name;
            int _id;
    
            public Manager(string name,int id)
            {
                _name = name;
                _id = id;
    
                Init();
            }
    
            void Init()
            {
                object obj1 = new object();
            }
        }
    
        class Manager1
        {
            string _name;
            int _id;
            int _grade;
            public Manager1(string name,int id,int grade)
            {
                _name = name;
                _id = id;
                _grade = grade;
    
                Init();
            }
    
            void Init()
            {
                object obj2 = new object();
                _grade = 2;
            }
        }

    重构后:

     abstract class Employee
        {
            protected string _name;
            protected int _id;
    
            public Employee(string name, int id)
            {
                _name = name;
                _id = id;
                Init();
            }
    
            protected abstract void Init();
        }
    
        class Manager:Employee
        {
    
            public Manager(string name, int id):base(name,id)
            {
    
            }
    
            protected override void Init()
            {
                object obj1 = new object();
            }
        }
    
        class Manager1 : Employee
        {
            int _grade;
            public Manager1(string name, int id, int grade) : base(name, id)
            {
                _grade = grade;
            }
    
            protected override void Init()
            {
                object obj2 = new object();
                _grade = 2;
            }
        }

    子类中的构造函数中调用的Init方法实现不同,在父类中做成抽象方法。

    四、Extract_Subclass 提炼子类

    当一个类中出现根据类型调用不同的方法,或者一个类中有多个职责的时候,我们可以考虑提炼子类

    重构前:

      class PrintClass
        {
            string _path;
            string _jsonData;
            string _sourceBillFlag;
            List<int> _sourceBillId;
            int _lableType;
    
            public PrintClass(string path, string jsonData, string sourceBillFlag, List<int> sourceBillId, int lableType)
            {
                _path = path;
                _jsonData = jsonData;
                _sourceBillFlag = sourceBillFlag;
                _sourceBillId = sourceBillId;
                _lableType = lableType;
            }
    
           public void Print()
            {
                switch(_lableType)
                {
                    case 1:
                        PrintBartender(_path,_jsonData);
                        break;
                    case 2:
                        PrintCodeSoft(_path, _jsonData);
                        break;
                    case 3:
                        PrintCloud(_sourceBillFlag,_sourceBillId);
                        break;
                }
            }
    
            void PrintBartender(string path, string jsonData)
            {
    
            }
    
            void PrintCodeSoft(string path, string jsonDat)
            {
    
            }
    
            void PrintCloud(string sourceBillFlag, List<int> sourceBillId)
            {
    
            }
        }
    View Code

    比如这个打印类中,根据类型,调不同的打印方法。

     重构后:

    namespace Extract_Subclass
    {
        class PrintBase
        {
            string _path;
            string _jsonData;
            public PrintBase(string path, string jsonData)
            {
                _path = path;
                _jsonData = jsonData;
            }
    
           public virtual void Print( )
            {
    
            }
        }
    
        class BartenderPrint : PrintBase
        {
            public BartenderPrint(string path, string jsonData):base(path,jsonData)
            {
                
            }
    
            public override void Print()
            {
                //call bartender api
            }
        }
    
        class CodeSoftPrint : PrintBase
        {
            public CodeSoftPrint(string path, string jsonData) : base(path, jsonData)
            {
    
            }
    
            public override void Print()
            {
                //call CodeSoft api
            }
        }
    
        class CloudPrint:PrintBase
        {
            string _sourceBillFlag;
            List<int> _sourceBillId;
            public CloudPrint(string sourceBillFlag, List<int> sourceBillId) :base("","")
            {
                _sourceBillFlag = sourceBillFlag;
                _sourceBillId = sourceBillId;
            }
    
            public override void Print()
            {
               //Cloud print
            }
        }
    }
    View Code

    五、Extract Superclass 提炼父类

    几个类的字段,方法,构造函数等都有部分相同之处,可以提取到父类中。

    重构前:

      class Department
        {
            string _name;
    
            public Department(string name)
            {
                _name = name;
                 
            }
    
            public string GetName()
            {
                return _name;
            }
    
            public int GetTotalaAnnualCost()
            {
                int result = 0;
    
                GetStaff().ForEach(p=>
                {
                    result += p.GetAnnualCost();
                });
    
                return result;
            }
    
            private List<Employee> GetStaff()
            {
                return default(List<Employee>);
            }
        }
    View Code
     class Employee
        {
            string _name;
            string _id;
            int _annualCost;
    
            public Employee(string name,string id,int annualCost)
            {
                _name = name;
                _id = id;
                _annualCost = annualCost;
            }
    
            public string GetName()
            {
                return _name;
            }
    
            public int GetAnnualCost()
            {
                return _annualCost;
            }
        }
    View Code

    Department类中有个GetTotalaAnnualCost方法,获取总费用,Employee中有个GetAnnualCost方法,获取费用。我们可以提取到父类中,修改成相同的名称。

    重构后:

    namespace RefactoringDome.Extract_Superclass
    {
       abstract class Part
        {
            string _name;
    
            public Part(string name)
            {
                _name = name;
    
            }
    
            public string GetName()
            {
                return _name;
            }
    
            public abstract int GetAnnualCost();
             
        }
    }
    
    namespace RefactoringDome.Extract_Superclass.Dome
    {
        class Employee : Part
        {
            string _id;
            int _annualCost;
    
            public Employee(string name, string id, int annualCost) : base(name)
            {
                _id = id;
                _annualCost = annualCost;
            }
    
            public override int GetAnnualCost()
            {
                return _annualCost;
            }
        }
    
        class Department:Part
        {
        
            public Department(string name):base(name)
            {
    
            }
    
            public override int GetAnnualCost()
            {
                int result = 0;
    
                GetStaff().ForEach(p =>
                {
                    result += p.GetAnnualCost();
                });
    
                return result;
            }
    
            private List<Employee> GetStaff()
            {
                return default(List<Employee>);
            }
        }
    
       
    
    }
    View Code

    六、Form Template Method 模板方法

    两个方法中的流程大致相同,我们可以提炼成模板方法。

    重构前:

       class Customer
        {
            public string Statement()
            {
                List<string> details = GetDetails();
    
                string result = "Rental Record for" + GetName() + "
    ";
                details.ForEach(p=>
                {
                    result += "Details is" + p + "
    ";
                });
    
                result += "Total Charge:"+GetTotalCharge();
    
                return result;
            }
    
            public string HtmlStatement()
            {
                List<string> details = GetDetails();
    
                string result = "<h1>Rental Record for<EM>" + GetName() + "</EM></h1>
    ";
                details.ForEach(p =>
                {
                    result += "<p>Details is<EM>" + p + "</EM></p>
    ";
                });
    
                result += "<p>Total Charge:<EM>" + GetTotalCharge()+"</EM></p>";
    
                return result;
            }
    
            public List<string> GetDetails()
            {
                return default(List<string>);
            }
    
            public string GetName()
            {
                return "";
            }
    
            public decimal GetTotalCharge()
            {
                return 0;
            }
    
            
        }

    Customer类中有两个打印小票的方法,一个是winform调的,一个是Html调的。方法中代码结构一样,只是部分显示字符串不同。

    这种很符合提取成模板函数。

    重构后:

    namespace RefactoringDome.Form_Template_Method
    {
        abstract class Statement
        {
            public string Value(Customer customer)
            {
                List<string> details = customer.GetDetails();
    
                string result = HeaderString(customer);
                details.ForEach(p =>
                {
                    result += DetailString(p);
                });
    
                result += FooterString(customer);
    
                return result;
            }
    
    
            protected abstract string HeaderString(Customer customer);
            protected abstract string DetailString(string detailInfo);
            protected abstract string FooterString(Customer customer);
    
        }
    
        class TextStatement : Statement
        {
    
            protected override string HeaderString(Customer customer)
            {
                return "Rental Record for" + customer.GetName() + "
    ";
            }
            protected override string DetailString(string detailInfo)
            {
                return "Details is" + detailInfo + "
    ";
            }
    
            protected override string FooterString(Customer customer)
            {
                return "Total Charge:" + customer.GetTotalCharge();
            }
        }
    
        class HtmlStatement : Statement
        {
    
            protected override string HeaderString(Customer customer)
            {
                return "<h1>Rental Record for<EM>" + customer.GetName() + "</EM></h1>
    ";
            }
    
            protected override string DetailString(string detailInfo)
            {
                return "<p>Details is<EM>" + detailInfo + "</EM></p>
    ";
            }
    
            protected override string FooterString(Customer customer)
            {
                return "<p>Total Charge:<EM>" + customer.GetTotalCharge() + "</EM></p>";
            }
    
        }
    }

     把不同的部分,用抽象函数代替。子类中去重写实现具体实现。

    七、Replace Inheritance with Delegation 继承替换为委托

    子类只用了父类一小部分方法。这种情况可以考虑将继承替换为委托。

    重构前:

        class List
        {
            public object FirstElement()
            {
                return default(object);
            }
    
            public void Insert(object element)
            {
    
            }
    
            public void Remove(object element)
            {
                
            }
    
    
            public int FindIndex(object obj)
            {
                return 0;
            }
    
            public void Sort()
            {
    
            }
        }
    
        class Queue: List
        {
            public void Push(object element)
            {
                Insert(element);
            }
    
            public void Pop()
            {
                object obj = FirstElement();
                Remove(obj);
            }
        }

    Queue类继承了List类,使用了List类的Insert、Remove、FirstElement方法。但是List类中还有Sort、FindIndex方法在子类中没有用到。这样父类传达给调用端的信息并不是你想要体现的。这种情况我们应该使用List的委托。

    重构后:

     class Queue  
        {
            List _list = new List();
            public void Push(object element)
            {
                _list.Insert(element);
            }
    
            public void Pop()
            {
                object obj = _list.FirstElement();
                _list.Remove(obj);
            }
        }

    八、Replace Delegation with inheritance 委托替换为继承

    一个类中,引用了另一个类的实例,但是当前类中的方法,委托类里都有,这种情况应该用继承替换委托。

    重构前:

     class Employee
        {
            Person _person = new Person();
    
            public string GetName()
            {
               return  _person.GetName();
            }
    
            public void SetName(string name)
            {
                 _person.SetName(name);
            }
    
            public new string ToString()
            {
                return "my name is:"+_person.GetLastName();
            }
        }
    
        class Person
        {
            string _name;
            
            public string GetName()
            {
                return _name;
            }
    
            public void SetName(string name)
            {
                _name = name;
            }
    
            public string GetLastName()
            {
                return _name.Substring(1);
            }
        }

    重构后:

     class Employee:Person
        {
            public new string ToString()
            {
                return "my name is:" + GetLastName();
            }
        }

    代码结构清晰简洁了不少。

  • 相关阅读:
    1、购买阿里云服务器
    struts2页面乱码解决方法
    struts第一次编写怎么都无法跳转页面
    时间转换与map集合
    struts2addActionError 、addFieldError、addActionMessage方法
    struts2基本流程
    struts2自定义类型转换器
    jsp聊天窗口随笔
    conn!=null与conn.isClosed的区别
    应用表单隐藏域进行提交
  • 原文地址:https://www.cnblogs.com/czly/p/12107169.html
Copyright © 2011-2022 走看看