关于程序可维护性的一些想法
SAP系统作为企业的信息系统,其生命周期通常是漫长的,比单个程序员的在职时间要长得多。早期实施阶段花大力气开发的自定义程序,通常会托付给企业内部或外部的运维团队来维护——不管怎么样,一般不是最初的开发者了。即便是在运维阶段,程序的创建者与修改者也常常不是一个人。不同的开发者,其知识基础、技术水平、编码风格难免有所不同,最早创建的程序,经过若干个独一无二的开发者的修改,可能会变得面目全非,失去可维护性,这时的程序可以说接近于死亡…因此,作为程序的开发者,我们需要让自己的程序对修改有抵抗力,从而能在后人的维护下活的更久一些。
当然,抵抗修改的意思,并不是指妨碍后人修改程序。企业的业务是多变的、人们对需求的理解是不断加深的,因而程序的修改也是必要的。抵抗修改的目标应当是:在合理的需求变动发生时,尽量让修改变得容易,并减小修改带来的破坏,从而让程序能承受更多次的修改。
我认为问题的关键在于减少耦合度、理清程序职责的分配,清晰的程序描述也很重要。
耦合度即模块之间的关联强度。高耦合度的程序牵一发而动全身,只适合于需求十分稳定的程序。对于多变的ABAP程序来说,降低耦合度可以减少程序修改对其它部分的影响,是比较重要的。
单纯的解耦工作有可能让我们陷入为解耦而解耦的陷阱。了解程序的职责分配可以让我们更加理性地运用技术,并且使程序对修改有更好的适应性。
程序的描述包含命名、程序结构这种“自我描述”,也包括程序注释、技术文档,以及需求文档。这可能是最容易改善的一个方面。
下面结合具体的ABAP开发技术来谈谈我对它们的想法,因为只是根据自己的一些经验的来写,可能不是系统全面的介绍。
本文链接:http://www.cnblogs.com/hhelibeb/p/7891401.html
原创内容,转载请注明出处
CDS视图
SQL是让很多程序员的头痛的东西。过去,由于内表的存在,大家会用简单的SQL取出较多的数据,然后在内表中处理它们。但在S4之后,SAP鼓励将更多的工作交给数据库服务器来做。可见日后的SQL将变得日益复杂,在复杂的SQL上进行修改可能会耗时较多、测试困难、不小心造成性能问题。ABAP CDS视图的引入可以较好的应对这一问题。如果早期的开发者能够利用CDS抽象出稳定的数据模型,把经过若干SQL处理的数据当作已存在的数据来看,那么就能简化ABAP程序中的SQL复杂度,同时也降低后续的开发者和业务顾问的心智负担和沟通成本。
(想一想我们是不是经常说这种冗长的话:XX属性是通过关联A表和B表,使它们的公司、业务编号和移动序号相等,在取消标识不等于’X’等情况下,获取它的某一属性,再到属性对应到的分配表C,获取有效期内的记录。看完并理解这么长一段话之后,也许交流的双方已经忘记了自己在思考的其它东西。如果这种关联逻辑在公司的需求中是稳定的甚至常常出现的,我们完全可以为它造一个“新词”,即CDS视图。基于CDS视图,之后的沟通方式可以变为:到视图ZCDSXX中,根据取消标识不等于’X’,获取我们需要的XX属性)
硬编码与配置表
这二者的原理在于将对程序的修改变为“扩展”,在不干涉或较少干涉程序代码的情况,完成功能的变更。
动态技术
动态技术是双刃剑,Field Symbol和RTTS的使用可以使我们的程序变得十分灵活,但这样的程序的可读性通常不太好,而且对新手来说也绝对是很难修改的。因此,我建议尽量把它作为基础功能的实现,和配置表结合、或者是通过新建子类的方式来实现功能的扩展。尽可能避免让后人直接维护大量使用动态技术的程序。
中间层
在制作与其它系统对接的接口时,由于各方面的原因,会不时遇到对方希望变更接口的输入输出方式或者格式的情况。这时候,不是直接提供给对方包含业务处理逻辑的接口,而是建立一个外层接口,把原有的接口包装起来,专门用来应对对方的修改,是一个好办法。
写有意义的注释
据说写程序不写注释是一种很糟糕的习惯,也有开发规范约束人们:必须要写注释。注释当然是必要的,但是在实践中,大部分人的注释水平是不太好的,往往对阅读起不到什么正面作用,于是甚至催生了一种完全相反的、矫枉过正的观点:好的程序从来不需要注释。
最近见到的一个典型的不好的注释:
*处理数据 PERFORM frm_process_data.
这段代码至少犯了3个错误。
- 以文章来对比,FROM的名字即文章的标题,我们不应该在标题中写明标题是标题。显然,FRM的前缀是无用的,它给不了我们什么信息。
- “处理数据”似乎是对FORM功能的描述,这部分内容应该放在FORM的定义处,而不是调用位置。在调用位置的注释,需要写的是:为什么这个FORM需要在这里被调用?为什么不是调用其它一个看起来相似的FROM?
- 在注释中写“处理数据”这种泛泛之辞通常产生不了什么意义,更不用说FORM名已经是process date(处理数据)了。这种重复有害无益。
善用编辑器为自动生成的注释模板,比如:
如果是函数、或者类的话,还可以写专门的文档:
善用异常
异常是个很有用的东西,但是我很少看到有ABAP开发者用它。我见到的程序大部分是用错误码或者错误标识的方式来处理错误。以我的经验来看,错误码在单层的调用关系中是比较好用的,但是在多层的、复杂的情况下,异常比错误代码要更容易处理和维护。而且异常有着较好的自我描述能力,这在程序的维护中是很有意义的。而很多错误码,只有开发者本人知道是什么意思,后续维护的人,只能认识到这是个错误…并不理解每个错误代码的涵义。
避免全局变量
全局变量不好,这是所有开发者的共识。之所以专门还要拿出它来作为一个小节,是因为我觉得这个问题实在普遍且严重。可能因为大部分ABAP二次开发程序都是内容较少的报表,最常用的ALV报表类(函数)则要求其输入的数据内表必须是全局变量,初入行的开发者通常是从全局变量写起的,而较简单的程序逻辑也让开发者没有承受全局变量带来的麻烦….这种惯性使得不少开发者在日后开发相对大型的程序时也会大量使用全局变量。而程序的维护者通常没有精力或能力来识别全局变量对程序的影响,从而在修改程序时造成了意料之外的结果。此外,不加释放的全局变量也会带来性能上的负担。所以我认为开发者应该经常思考是否可以用局部变量代替全局变量、用值传递代替引用传递,时时注意避免全局变量带来的麻烦。
欢迎大家发表自己对可维护性的看法,或者对本文的内容进行指点。