基于开源项目进行开发已经越来越普遍,WebKit和Android都有很多的深度定制的版本。
对这样庞大工程修改的逻辑越来越多,日后想要同步升级就要面对更大的复杂性和风险。跟随开源项目同步升级,寻求上层的创新和优化才比较适合未来的产品开发策略。深度定制的方式会遭遇越来越多的尴尬。
修改是必要的,但如何最大化地降低耦合和隔离对原生代码逻辑的修改?逻辑碎片的风险也许大家都体会过。以下是我对一个问题的思考,与大家分享,抛砖引玉。
1. 问题定义
首先交待一下当前的状况。
1.有对WebKit原生内核中HTMLMediaElement修改的需求。
由于实现的限制,导致了必须对HTMLMediaElement进行修改。
2. 不同平台的修改逻辑混杂在一起。
在不同平台上的适配内容也不尽相同,所以其中有许多使用宏来区分系统的修改。
问题就是有没有可能将这些修改的实现放到独立的文件中去,在HTMLMediaElement中只做少量的修改,最大化的减少对原生代码的修改?或者是有规则的修改。总之要便于和最新的WebKit代码同步。
2. 问题分析
首先从设计上来看这个问题,可以将WebKit的实现视为核心逻辑,将我们的修改视为一个辅助逻辑或特殊逻辑。
这样就可以有一个设计上问题定义:把这部分逻辑从主逻辑中抽离的设计方法,但不改变原来的类的层次架构。
继承并不合适。因为一部分HTMLMediaElement中的成员定义为protected,它本身已经被HTMLAudioElement和HTMLVideoElement所继承。还有对应的Render、JS Binding与它的对应问题。远不是在parser位置将video和audio对应的类改成新类就可以的, 而是需要更改到HTMLMediaElement的定义。
解决方案就是提供一个Helper类,如MediaElementHelper来处理特殊逻辑。
2. 实现说明
2.1 建构
在HTMLMediaElement的建构函数中加入:
m_helper = MediaElementHelper::create(this);
不同平台可以使用相同的类定义,但实现不同。
2.2 相互调用
helper又为HTMLMediaElement的友类,就可以访问HTMLMediaElement的私有变量,或者执行私有成员函数。如果认为这样风险高,也可以像下面这样专为helper增加一些访问私有成员的接口。
这样在需要进行特殊逻辑判断和处理的地方,就使用m_helper来调用执行。具体的行为则在不同的helper类中实现。
3. 评估
关于helper的使用一直是有争议,网上也有很多避免使用helperclass的讨论。主要论调在于认为helper class是过程化的产物,思考时是考虑的是流程上的逻辑补充。虽然在目前场景下,这也算是一个解决方案,但不是最佳方案,因为这些做同样增加了设计的复杂性。