关键词搜索

源码搜索 ×
×

C# 重构

发布2020-12-13浏览355次

详情内容

一、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
    {
         
    }
    
      10
    • 11
    • 12
    • 13
    • 14
    • 15

    二、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;
            }
        }
    
      10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    子类中的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();
    }
    
      10
    • 11
    • 12

    }

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    }

    重构后:

     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;
            }
        }
    
      10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

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

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

    重构前:
    View Code
    比如这个打印类中,根据类型,调不同的打印方法。

    重构后:
    View Code
    五、Extract Superclass 提炼父类
    几个类的字段,方法,构造函数等都有部分相同之处,可以提取到父类中。

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

    重构后:
    View Code
    六、Form Template Method 模板方法
    两个方法中的流程大致相同,我们可以提炼成模板方法。

    重构前:

       class Customer
        {
            public string Statement()
            {
                List<string> details = GetDetails();
    
                string result = "Rental Record for" + GetName() + "\n";
                details.ForEach(p=>
                {
                    result += "Details is" + p + "\n";
                });
    
                result += "Total Charge:"+GetTotalCharge();
    
                return result;
            }
    
            public string HtmlStatement()
            {
                List<string> details = GetDetails();
    
                string result = "<h1>Rental Record for<EM>" + GetName() + "</EM></h1>\n";
                details.ForEach(p =>
                {
                    result += "<p>Details is<EM>" + p + "</EM></p>\n";
                });
    
                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;
            }
    
            
        }
    
      10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    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() + "\n";
            }
            protected override string DetailString(string detailInfo)
            {
                return "Details is" + detailInfo + "\n";
            }
    
            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>\n";
            }
    
            protected override string DetailString(string detailInfo)
            {
                return "<p>Details is<EM>" + detailInfo + "</EM></p>\n";
            }
    
            protected override string FooterString(Customer customer)
            {
                return "<p>Total Charge:<EM>" + customer.GetTotalCharge() + "</EM></p>";
            }
    
        }
    }
    
      10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

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

    七、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);
            }
        }
    
      10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    Queue类继承了List类,使用了List类的Insert、Remove、FirstElement方法c#教程。但是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);
            }
        }
    
      10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    八、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();
            }
        }
    
      10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    代码结构python基础教程清晰简洁了不少。

    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载