一些思考

继承的缺点

最近在看项目里一些前人写的代码,其中大量的继承关系让我非常地头疼。

主要问题是,其中子类经常重写父类的方法,但是又不一定重写完全。这就导致在阅读代码的时候难度倍增。其中的一些原因包括,IDE无法每次都帮你精确定位到实际方法定义的位置。比如以下代码:

# python
class Stage():
	def Run(self):
		self.OnEnter()
	
	def OnEnter(self):
		# dosomething
		pass
	

class MainTask(Stage):
	def OnEnter(self):
		# dosomething else
		pass

maintask = MainTask()
maintask.Run()

定位maintask.Run()的定义会定位到Stage.Run()没错,因为MainTask没有重写这个方法。然后顺藤摸瓜,定位OnEnter(),会定位到Stage.OnEnter(),这是可以理解的,因为IDE无法知道具体执行的时候,是不是直接实例化Stage还是实例化MainTask,所以默认定位到最近的(如果本类也没有OnEnter定义,会继续往父类找)。显然在这个代码中,实际运行的MainTask.OnEnter()的代码。

总结就是:继承会丢失某些信息,这部分信息只有在运行的时候才能知道。一旦继承关系变得复杂,重写关系变得复杂,那么其中如果出现错误,调试起来会变得很困难。

解决办法很简单,那就是尽量保持继承关系的简单,或者使用组合代替继承。关于对继承的痛斥,和具体的解决方案,可以参考这篇文章:Inheritance Is Evil. Stop Using It.

大型源代码的阅读

通常来说,阅读源代码主要是做两件事情:1. 搞清楚调用关系,2. 搞清楚参数含义。要想弄明白这两件事情,最重要的手段的就是调试。当然,有一些工具可以静态分析代码帮你画出函数的调用关系图。但是这依然是不完全的。比如继承如果滥用,导致实际继承的对象要到运行时才能确定的话,那么静态分析工具就不能够分析出调用的是哪个类的哪个方法。

断点调试可以帮助解决问题。然而,想要成功运行一个大型项目往往是需要付出很多努力的。比如,复杂的构建环境;比如Unity的一款项目涉及到安卓的代码,比如要打包到安卓上运行安装包后才能知道结果。对于这种情况,如果能够将部分代码“拆出来”单独调试,也是可以的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值