开闭原则:“对修改封闭,对扩展开放”。在面向对象的系统中,通过类的继承实现扩展。.net中提供的partial class提供了扩展类的新思路。
一、应用场景
可以使用partial class的场景很多。这里分析一个ORM的例子。
系统中有一个Cat类,属性ID、Age、Weight都需要存储到数据库中,一个信息系统中常见的需求。通过读取数据库的结构,可以用工具生成Cat类的代码。并且ORM框架支持了从数据库信息生成Cat对象。
现在的Cat什么动作都没有,客户说,我们需要一个Miaow()的函数。这时就需要对ORM生成的Cat类进行扩展了。
可以肯定地一点是,我们不能修改自动生成的代码,因为这会牵涉到数据库结构与代码同步的问题。解决这个需求有两种方法:继承方式扩展,partial class扩展。
二、继承方式扩展
工具自动生成一个CatBase类,这个类只有属性,嵌入到ORM框架中。既然需要扩展功能,很容易想到对这个基类继承,于是有了Cat类。Cat类如愿以偿地有了Miaow()函数。
以前系统中用的是CatBase的实例,现在创建CatBase实例的地方需要改为创建Cat的实例。这个问题让ORM框架解决吧。
客户的需求实现了,我们自己的代码生成也没有遭到破坏,任务完成。
三、partial class扩展
partial class简单地说就是可以将一个类的代码写到两个或多个代码文件中。编译器在编译的过程中将这几个文件组合起来一起编译。一个很酷的技术。
工具生成的Cat类仍然不变。既然需要增加函数,那么在新建一个代码文件,将Miaow()函数写出来就可以。需要做的仅仅是将类的声明由class改为partial class,任务完成。
四、对比分析
两种思路都可以实现需求。孰优孰劣需要仔细分析一下。
实例创建:partial class更加简洁。
系统复杂度:对于系统来说,partial class方式下只存在一个类,而继承方式有两个类。
继承逻辑:从逻辑上讲,Cat并不需要一个基类CatBase,这样做仅仅是因为在代码构建过程中的一个限制。
维护性:两种方式下都会存在两个代码文件,维护成本并没有区别。
可读性:两个Cat文件确实让人费解。
整体上说,使用partial class更加优雅一些。
“继承”的这种方式比较符合传统的思维习惯,而partial class到底是不是满足开闭原则呢,这点确实不好说。不过在软件构建上,我是一个实用主义者,哪种方式好用就用哪一种。
在ORM的场景中,partial class更加好一些,但有的时候,两个类之间确实就存在继承关系,那么就必须用到继承了。虽然绝大多数情况下,都需要继承方式,但是既然有了partial class技术,我们在做设计时也需要考虑这个思路。
在VS2005中,Form、DataSet都使用了partial class方式,原理和这个一样。但是要将这个原理推广到“业务实体”中,可能在理解上需要有所突破。
使用partial class确实会带来可读性的损失,尤其是一个类分布在很多个文件中的时候,所以文件的命名最好是有一个规范来保证。
查看本文来源