代码重构~提取到类
提取到类(Extract Class) : 将多个类所公用的部分(包括方法,属性,事件等等)抽象出来,形成一个新的类型,这个类被称为它们的基类(base class)或者父类,而使用面向对象语言的特性,在基类中使用抽象对象或者虚对象,让子类可以直接使用基类的成员或者根据自己的逻辑去覆写基类的成员,提交到类经常被用到产品族的概念中,如一个数据操作基类,它的子类可能是user操作类,product操作类,order操作类等,具体看一下代码:
userRespository类型是用来对user表进行直接的单纯的数据操作的,它可以是这样的
而对于userRespository来说,它可能需要一个DB数据源对象(可能是linq to sql,ef的一种),还有一些标准的CURD操作的方法,而这些对于productRespository类型也是一样需要的,这时,我们就应该将userRepository和productRepository公用的部分提取出来,行成它们的基类,即RepositoryBase
在这个RepositoryBase基类中,还使用了接口,它实现了对所有数据基类(可能是linq to sql基类,ef基类,内存数据源基类,缓存数据源基类等)操作的统一性和一致性。
我们在进行“提取到类”时,需要注意的几个概念是:
抽象方法:abstract method,在基类去定义方法规范,由子类去实现它的逻辑
虚方法:virtual method,在基类去实现了这个方法,但子类可以根据自己的逻辑去override它
抽象类:一般基类都是不能被直接实例化的,所以一般是抽象类
如果上面的代码不容易理解,可以看一面简单的demo,一个boy类,它有一个属生name和一个方法display(),name表示为男孩的姓名,display输出男孩的姓名;而另外一个类girl,它也一样有name和display,这时,我们可以将boy和girl公有的属性和方法进行抽取,放在person类,而它应该有两个属性name和gander,代表人的姓名和性别,有一个方法是display(),用来输出人的姓名和性别,这个简单的例子很好的说明了提取到类的使用场合,它的代码如下:
1 //男孩子 2 class Boy 3 { 4 public string Name{get;set;} 5 6 public void Display() 7 { 8 Console.Write("男孩姓名是{0}",Name); 9 } 10 } 11 //女孩子 12 class Girl 13 { 14 public string Name{get;set;} 15 16 public void Display() 17 { 18 Console.Write("女孩姓名是{0}",Name); 19 } 20 } 21 //而把方法修改后变为 22 23 class Person 24 { 25 public string Name{get;set;} 26 public string Gander{get;set;} 27 public virtual void Display() 28 { 29 Console.Write("{0}姓名是{1}",Gander,Name); 30 } 31 } 32 33 //男孩根据自己的需要,去override Display()这个方法 34 class Boy 35 { 36 public string Name{get;set;} 37 38 public void Display() 39 { 40 Console.Write("性别:{0},姓名:{1}",Gander,Name); 41 } 42 }
其实,代码重构它不仅是对代码本身的重构(代码执行性能),更重要的是对面向对象的重构(代码的逻辑表现)。