C# 谈谈代码重构
代码重构
重构(Refactoring)就是在不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高 软件的扩展性和维护性。
一、为什么要重构(Refactoring)
1、·持续偏纠和改进软件设计。
2、·使代码更易为人所理解。
3、·帮助发现隐藏的代码缺陷。
4、·从长远来看,有助于提高编程效率。
二、何时着手重构(Refactoring)
1、·代码中存在重复的代码。
2、·过大的类和过长的方法。
3、·牵一毛而需要动全身的修改。
4、·类之间需要过多的通讯。
5、·过度耦合的信息链。
6、·不完美的设计。
7、·缺少必要的注释。
三、如何来重构(Refactoring)
所谓重构也就是“保持软件的外在功能不变,重新调整其内部结构”。
Rename: 改名了,类、函数、成员等名字都可以改。
改成大家容易理解其功能用途的名字:
/// <summary> /// /// </summary> /// <param name="ID"></param> /// <param name="numlist"></param> /// <returns></returns> protected int hename(string ID, Dictionary<int, string> numlist) { int i = numlist.Count(); List<string> onelist = (from entity in numlist where entity.Value == ID select entity.Value).ToList(); numlist.Add(i + 1, ID); return onelist.Count(); } //修改为 /// <summary> /// /// </summary> /// <param name="ID"></param> /// <param name="numlist"></param> /// <returns></returns> protected int GetSameNameCount(string ID, Dictionary<int, string> numlist) { int i = numlist.Count(); List<string> samelist = (from entity in numlist where entity.Value == ID select entity.Value).ToList(); numlist.Add(i + 1, ID); return samelist.Count(); }
Extract Method: 将某段代码封到一个新函数里。
如果在某个方法里有一段代码是可以重新用一个方法来封装的,如下:
/// <summary> /// /// </summary> /// <param name="dtFormatedData"></param> /// <param name="ReplaceColumn"></param> /// <returns></returns> private DataTable ReplaceCloumnString(DataTable dtFormatedData, List<string> ReplaceColumn) { Dictionary<string, string> newfirstReplaces = new Dictionary<string, string>(); newfirstReplaces = needfirstReplaces; foreach (KeyValuePair<string, string> newitem in firstReplaces) { if (!newfirstReplaces.ContainsKey(newitem.Key)) { newfirstReplaces.Add(newitem.Key, newitem.Value); } } DataTable dtFormatedDataCopy = dtFormatedData.Clone(); foreach (DataRow dr in dtFormatedData.Rows) { foreach (KeyValuePair<string, string> item in newfirstReplaces) { foreach (string needColumn in ReplaceColumn) { if (dr[needColumn].ToString().Contains(item.Key)) { string ContentStr = dr[needColumn].ToString(); dr[needColumn] = ReplaceStr(ContentStr, item.Key, item.Value); } } } DataRow drNewRow = dtFormatedDataCopy.NewRow(); drNewRow.ItemArray = dr.ItemArray; dtFormatedDataCopy.Rows.Add(drNewRow); } return dtFormatedDataCopy; } ///修改为 /// <summary> /// /// </summary> /// <param name="dtFormatedData"></param> /// <param name="ReplaceColumn"></param> /// <returns></returns> private DataTable ReplaceCloumnString(DataTable dtFormatedData, List<string> ReplaceColumn) { Dictionary<string, string> newfirstReplaces = GetReplaceDictionary(); DataTable dtFormatedDataCopy = dtFormatedData.Clone(); foreach (DataRow dr in dtFormatedData.Rows) { foreach (KeyValuePair<string, string> item in newfirstReplaces) { foreach (string needColumn in ReplaceColumn) { if (dr[needColumn].ToString().Contains(item.Key)) { string ContentStr = dr[needColumn].ToString(); dr[needColumn] = ReplaceStr(ContentStr, item.Key, item.Value); } } } DataRow drNewRow = dtFormatedDataCopy.NewRow(); drNewRow.ItemArray = dr.ItemArray; dtFormatedDataCopy.Rows.Add(drNewRow); } return dtFormatedDataCopy; } private Dictionary<string, string> GetReplaceDictionary() { Dictionary<string, string> newfirstReplaces = new Dictionary<string, string>(); newfirstReplaces = needfirstReplaces; foreach (KeyValuePair<string, string> newitem in firstReplaces) { if (!newfirstReplaces.ContainsKey(newitem.Key)) { newfirstReplaces.Add(newitem.Key, newitem.Value); } } return newfirstReplaces; }
------------------------------
Encapsulate Field: 将某个字段转成属性
如下:
public string =null; ///转换为 public string FieldName { get; set; }
Extract Interface: 将某个属性或函数转成一个接口,从而是当前的这个属性或函数成为接口实现。
public class FolderBE { public string FolderOne { get; set; } public DateTime? CreateFolderOne { get; set; } public string FolderTwo { get; set; } public DateTime? CreateFolderTwo { get; set; } public string FolderThree { get; set; } public DateTime? CreateFolderThree { get; set; } public string FolderFour { get; set; } public DateTime? CreateFolderFour { get; set; } public string FolderFive { get; set; } public DateTime? CreateFolderFive { get; set; } } public List<SingleResultBE> HavelistResult = new List<SingleResultBE>(); private bool CheckFolderExist(FolderBE folder, int item) { List<FolderBE> HavelistFolder = new List<FolderBE>(); if (item == 1) { HavelistFolder = (from entity in listFolder where entity.FolderOne == folder.FolderOne && string.IsNullOrEmpty(entity.FolderTwo) select entity).ToList(); } else if (item == 2) { HavelistFolder = (from entity in listFolder where entity.FolderOne == folder.FolderOne && entity.FolderTwo == folder.FolderTwo && string.IsNullOrEmpty(entity.FolderThree) select entity).ToList(); } else if (item == 3) { HavelistFolder = (from entity in listFolder where entity.FolderOne == folder.FolderOne && entity.FolderTwo == folder.FolderTwo && entity.FolderThree == folder.FolderThree select entity).ToList(); } else if (item == 4) { HavelistFolder = (from entity in listFolder where entity.FolderOne == folder.FolderOne && entity.FolderTwo == folder.FolderTwo && entity.FolderThree == folder.FolderThree && entity.FolderFour == folder.FolderFour select entity).ToList(); } else if (item == 5) { HavelistFolder = (from entity in listFolder where entity.FolderOne == folder.FolderOne && entity.FolderTwo == folder.FolderTwo && entity.FolderThree == folder.FolderThree && entity.FolderFour == folder.FolderFour && entity.FolderFive == folder.FolderFive select entity).ToList(); } return HavelistFolder.Count == 0; }
Promote Local Variable to Parameter: 将某个局部变量提升为函数参数
如上
Reorder Parameters: 对函数参数排序
略
Remove Parameters: 删除某个函数参数,但函数内对这个参数的使用不会删除。
如上,作为全局变量来用
重构函数(CHAPTER6)
Extract Method
前提:已经通过其他重构方法处理了间接变量。
目的:缩小函数的粒度以增加复用;强化代码的清晰度。
目标:函数的名称能够很好的表达函数要实现的“功能”。而不是要怎样做。
Inline Method
是Extract Method 的逆过程。正是因为有了这些逆过程,你才可以放心大胆的进行重构。
前提:被Inline的函数不能是多态的。Inline后无法表达多态的情况。
目的:去掉非必要的间接性。或者用于重组的一组组织不合理的函数的前提。
目标:去掉不必要的函数或者过多的委托。
提取方法是最常用的重构之一。当一个方法看起来太长或者方法中一些代码需要注释才能明白它的目的时,可以考虑把它们提取出来作为一个独立的方法。