VB.NET的旅( 7)—脆弱的基类

  “既然说是脆弱当然是指它象蛋壳样不堪击喽这个问题其实很好理解总是由人来设计和编写所以工作开始时考虑不到某些问题当然也是很正常所以可能在工作进行了段时间后发现基类需要变更你想如果我在基类中更改了成员数据类型以及那些允许重写那些思路方法和属性那派生类及其子类还能正常工作吗?尤其是当个团队(Team)中多个开发人员起来创作基类和派生类时就更是要命了很多情况下大家可能已经把基类和些派生类编译成 2进制形式进行提交了更改基类重新编译再分布会牵发而动全身导致项目崩溃所以我们把这叫做‘脆弱基类’也就是说它是整个工程中最薄弱最致命环节”大李眉头直紧锁着想必是回想起了自己受打击经历

  “这么严重呀现在软件Software工程设计思路方法会不会对这个有很好解决方案?”我努力想缓解下大李严肃神情

  “如果对项目前期设计考虑尽可能周详在工程实施中对项目代码控制和相关性分析做得踏实会起到很好效果但是不管个人如何努力有时还是无法避免对基类进行不可预见更改我们摸索过很久有了些处理手段

  “真是成事在人呀我们现在有什么解决的道?”我也下子振奋起来了

  “呵呵并不是什么完美解决方案只能在某种程度上减轻危害我们常用个思路方法最直接思想就是把有可能发生更改全都放在派生类中进行不在基类中做

  “这具体是什么意思呀我还是不太明白”我不好意思地挠挠头

  大李微笑着点点头看来是知道我不会明白“我们在基类中使用是抽象类它内含思路方法和属性只有定义没有进行实现而把实现部分都放在派生类中做这样抽象类自身是无法被例子化但是它好处不言而喻就是有可能发生实现上更改都会只涉及到它派生类了VB.NET中就提供了这样手段

  说着大李就打开VS.NET集成编译环境顺手写了小段代码:

Public MustInherit Class CBaseHenry 
 
  Public MustOverride Sub subX(ByVal x As Integer) 
 
  Public MustOverride Function fcnY(ByVal y As Integer) As Long 
 
End Class 
 
Public Class CDerivedHenry 
 
  Inherits CBaseHenry 
 
  Public Overrides Sub subX(ByVal x As Integer) 
 
    '写入实现代码 
 
  End Sub 
 
  Public Overrides Function fcnY(ByVal y As Integer) As Long 
 
    '写入实现代码 
 
  End Function 
 
End Class 


  “这里要注意两个问题个是关键字我们用MustInherit来修饰类名使类成为抽象类在它成员中把思路方法和属性前加入MustOverride修饰符表示它们必须在派生类中加以实现第 2个要注意派生类必须对所有用MustOverride标识基类思路方法和属性都进行实现只重写了subX不写fcnY编译器会报错

  “这确可以解决部分问题但好象只能解决在基类中进行实现代码有更改问题对于数据类型更改好象没有什么效果”我看了好发出了这样疑问

  “所以我刚才说是在某种程度上进行解决嘛”大李也不由笑了起来“不过你提这个问题倒不是太麻烦我们可以在派生类中用Shadows来解决呀!(详见本报上重载和隐藏)”

  这倒是个不错主意我心中暗暗评价了突然我又想到个问题:“如果基类要做功能扩展如何办呀?”

  “如果是要做扩展最安全思路方法是添加新成员而不是对基类大肆修改般是往派生类添加设计时缺失新成员最好不要使用Overloads关键字来命名和基类相同成员那样往往会带给你意想不到问题最好重新定义新成员命名上也要尽量和基类已有成员名区分开来其实也可以往抽象类基类中添加新成员定义但这样需要为基类制定版本虽然不会对应用造成毁灭性危害但是应该要能够完全地控制和管理自己代码我们般是不希望扩展基类

  我已经大意上领会了大李片苦心:“您意思是不是指基类脆弱问题实际上是客观存在我们所做就是要最大程度减小这个问题带来危害?”

  大李眼中闪过丝赞许笑意颌首道:“没错对于个应用设计者来讲想使用面向对象思路方法来开发必须要在设计时候精心策划类层次结构般来说是有这样几个准则需要把握:

  第遵循先通用再专用原则先设计好层次结构中每级别类中通用部分也就是提供给派生类继承成员和标识为Public成员;

  第 2在定义数据类型和存储区时要有预留量以避免以后更改困难例如即使当前数据可能仅需要Integer类型就够了在设计时我们使用 Long 类型变量当然最好能物尽其用也不要盲目放大;

  第 3个项目中必须统管理和分配团队(Team)中使用所有命名以减少命名冲突点其实事关重大;

  第 4要使用提供可行最低访问权限访问修饰符声明类成员内部类成员应声明为 Private;仅在类内和派生类才需要成员应标记为Protected;Friend 数据成员可以从类外部访问但仅限于该模块是定义该类项目个组成部分;使用Public标识成员只能是例子化时真正需要内容而且经常用在类层次结构底部



  “也就是说个规范标准操作标准命名体系可以决定基类强壮和否?”我不禁感触了

  “不对应该这样说可以决定是给脆弱基类穿上多厚防护衣基类始终都是脆弱”大李更正道

  我连声赞同:“对我现在是真正明白为什么总有人提编程规范标准事情直认为是增强代码可读性没想到自身还有这么大帮助

  “当然其实你认真想Overrides关键字作用不管要不要注明编译器都可以很方便地判断思路方法或属性是否在基类中签名是否匹配但是VB.NET要求我们必须标注就是强制开发人员注明重载基类思路方法或属性意图使开发过程更合理和有效此外还有更重要就是我们要在工程实战中不断地学习和磨练了解更多知识获得更多经验这样才会成长为名合格设计师就拿继承来说吧在.NET中其实支持 3种继承方式:实现继承、接口继承、可视继承我们其实只用了第种继承方式你看要学东西是不是很多?”大李友好地拍了拍我肩膀



Tags: 

延伸阅读

最新评论

发表评论