天天看点

HT图形组件设计之道(二)

HT图形组件设计之道(二)

记得十多年前我刚毕业的第一份工作就是负责电力SCADA的人机界面交互模块,当时大部分电力行业都是采用VC/MFC或QT来实现界面呈现,其实至今也依然如此,前端时间和老朋友聚会了解到他们还在用VC6编译系统,如今的VS20**根本跑不动他们庞大的古老系统,当然也许他们没配置好工具参数,但从一个侧面你可以感受到老系统迁移之重,大部分程序员处于为项目业务功能疲于奔命状态,上百号人这么多年在根本无力优化和重构的架子上不断堆积功能,我记得当时一个mousedown函数居然堆了六千多行代码,各种图元类型的draw代码也是长得不堪入目,这些老系统虽然不好维护但也考这么多程序员活生生的维护下来了,我们每天能正常的用水用电用气,背后都是靠着众多程序员的血汗维护着以如今眼光看完全不堪入目的烂代码,不得不承认在中国能用是第一位,其他问题只要堆人能解决的都不是问题。有点扯远了,上几张我以前电力实现的图库工具:

HT图形组件设计之道(二)

实现功能并不难,当时也实现了组合和分解图元,能进行图库管理和用户自定义,我相信全世界肯定不下几百上千套绘图软件,刚开始我还是很兴奋,每天学习不同的绘制API,就能捣鼓出新效果,我也不在乎代码架构,每天就是以学习掌握更多的庞大MFC库为荣,但当你掌握大部分绘图技巧后,我发现自己每天维护这种庞大到无法以个人力量进行大规模重构,又不得不持续维护每天堆积功能性体力活代码时,我感觉自己在浪费生命,于是跳槽到了另外一家公司打算做电子商务,结果阴差阳错又被安排到电力部门干起来绘图工具,还好这次我能换个新语言Java,没有历史包袱完全自己重头设计图形架构,于是地球上出现了第1001个绘图工具:

HT图形组件设计之道(二)

这一版设计上还是有很大的改进,图形绘制逻辑,交互代码以及界面布局等都进行了较合理的分工设计,那个Java和设计模式很火,人手一本Martin Fowler《Refactoring: Improving the Design of Existing Code》,犹如宗教信仰坚决执行一个函数不超过几十行的时代,一个mousedown几千行的代码已经绝迹了,但我还是很不满意,数据模型和界面绘制没有很好的有机结合机制,虽然电力要求界面有***的毫秒级响应,但大部分公司都是像游戏刷新机制那样不断repaint界面,是的,当时的数据模型没有任何事件派发机制,就是内存中的一堆数据,你无法知道哪个数据什么时候change了,因而只能不断的repaint界面,刷新周期太短对于大的网络拓扑图根本来不及更新,更新周期太长又达不到响应要求,至于所谓的***毫秒级响应我只能呵呵了,为了上这个系统一堆兄弟在沈阳某农村封闭了八个多月,我很好奇那个老系统现在是否健在…

HT图形组件设计之道(二)

以上是在矢量编辑器中打开的效果图,你可以清晰的看得到我们定义的几个元素的位置大小演示等,这样应用时只要构建一个Node对象,将其image设置为switch矢量,那么将来只需要调用node.setStyle(‘switch.angle’, Math.PI/6)就可以随时随地控制刀闸展开角度 。

这样封装还不够完美,对应用着来说他们只关心刀闸的打开和关闭的操作,他们并不关心旋转角度,开和关是业务角度的理解,而旋转角度是底层实现图形上的参数,并且用户还需要开关过程有动画效果,于是我们进行了进一步的封装,设计了ht.Switch的类,提供了setExpanded的函数,在函数里面操作底层绑定图形的‘switch.angle’属性,以及启动动画封装:

最后几点设计控件的建议:

切换到使用者角度,即站在上层应用者角度提供最简洁符合业务逻辑的API接口,尽量不暴露图形相关参数,图形参数对上层使用着是晦涩的,暴露了你自己也是非常难改动和维护

不要一开始设计就考虑如何操作,如何动画,操作和动画都可以在基础API基础上扩展再封装,某种程度上来说,如何操作和如何动画甚至不属于控件封装该干的,至少可再提供进一层的封装,这样可随意切换操作和动画逻辑,而不影响底层控件的数据模型和绘制逻辑

尽量让绘制代码和业务逻辑代码分离,这点如果采用最基础的绘制代码的确很难分离,这也是HT尽量采用矢量描述,不让用户控制底层绘制代码的初衷

HT图形组件设计之道(二)

继续阅读