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

重构前:
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;
        }

        
    }

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

    }
}

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

七、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方法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);
        }
    }

八、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();
        }
    }

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
特别说明 -------- 新版本请访问网站www.bluefishes.net. 考虑到稳定性,新版本不支持Visual Studio.NET 2002. 产品名称 -------- SharpRefactor(C#代码重构工具) 产品简述 -------- 本工具用于代码重构和代码自动生成。现阶段主要用于C#代码重构。 所谓重构也就是“保持软件的外在功能不变,重新调整其内部结构”。 关于每种重构模式的含义,请参见http://www.refactoring.com/ 具体功能参见具体版本的特性列表。 对重构很感兴趣或是很关注使用效率的用户,希望[使用指南]一节对你有所助益。 版本 ---- 1.0.0(BETA). 发布日期 -------- 2003/6/13 作者 ---- C# Refactor Team. 制作 ---- Blue Workshop. 环境要求 -------- Visual Studio.Net 2003 Windows 2000 + SP2 + SMTP Service 特别提示 -------------- 本插件使用了异常处理和报告机制。 一般而言,环境、代码以及其他原因都会导致程序出错。因此,在您使用本插件的过程中,可能会弹出错误报告。一部分错误不会影响使用,另一部分会影响使用。 C# Refactor Team愿意随时提供技术支持,及时为你解除问题。 版本1.0.0特性 ------------- Rename Parameter Rename Local Variable Rename Field Rename Property Rename Class Rename NameSpace Safe Delete Parameter Safe Delete Local Variable Safe Delete Field Safe Delete Property Safe Delete Method Safe Delete Class Safe Delete NameSpace Extract Interface Undo/Redo Preview usage before refactor(重构前预览) Auto build after refactor(重构后自动生成) Options(工具选项) User feedback(用户反馈) 使用指南 -------- 所有功能暂不支持静态成员。 尽量使用鼠标右键菜单。 尽量使用快捷方式,比如:单击鼠标右键,弹出菜单后再连续按‘R’键和‘C’键就可以调用[Rename]菜单下的[Rename Class]命令。 在使用Rename系列命令时,需要先转到定义代码元素的地方。此时,可以先使用右键菜单中的[转到定义]命令。 在Option中可以设置首选项。 由于Visual Studio在生成较大的解决方案时有时会不成功,所以Auto build after refactor通常用于较小的解决方案。 Rename NameSpace与Move Class不同。Move Class的焦点在Class,即改变类所在的NameSpace。而Rename NameSpace的焦点在NameSpace,即改变指定NameSpace的名字,并更新该NameSpace的所有引用(Usages)。 错误报告以及建议功能需要网络连接和Windows自带的SMTP服务。因为发送速度很快,所以不会占用您宝贵的时间。 可以使用User feedback功能提出您睿智的建议、批评、任何意见。 技术支持 -------- [email protected] 下载 ---- www.csdn.net 版本 发布日期 ----------------------------- 1.0.0(Beta) 2003/6/13

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值