永利网址 2

至于程序可维护性的片段设法

SAP系统作为企业的信息系统,其生命周期通常是漫长的,比单个程序员的在职时间要长得多。早期实施阶段花大力气开发的自定义程序,会交付给企业内部或外部的运维团队来维护——不管怎么样,一般不是最初的开发者了。即便是在运维阶段,程序的创建者与修改者也常常不是一个人。不同的开发者,其知识基础、技术水平、编码风格难免有所不同,最早创建的程序,经过若干个独一无二的开发者的修改,可能会变得面目全非,失去可维护性。这时的程序可以说已经接近于死亡…因此,作为程序的开发者,我们需要让自己的程序对修改有抵抗力,从而能在后人的维护下活的更久一些。

当然,抵抗修改的意思,并不是指妨碍后人修改程序。企业的业务是多变的、人们对需求的理解是不断加深的,因而程序的修改也是必要的。抵抗修改的目标应当是:在合理的需求变动发生时,尽量让修改变得容易,并减小修改带来的破坏,从而让程序能承受更多次的修改。

我认为问题的关键在于减少耦合度、理清程序职责的分配,清晰的程序描述也很重要:

耦合度即模块之间的关联强度。高耦合度的程序牵一发而动全身,只适合于需求十分稳定的程序。对于多变的ABAP程序来说,降低耦合度可以减少程序修改对其它部分的影响,是比较重要的。

单纯的解耦工作有可能让我们陷入为解耦而解耦的陷阱。了解程序的职责分配可以让我们更加理性地运用技术,并且使程序对修改有更好的适应性。

程序的描述包含命名、程序结构这种“自我描述”,也包括程序注释、技术文档,以及需求文档。这可能是最容易改善的一个方面。

下面结合具体的ABAP开发技术来谈谈我对它们的想法,因为只是根据自己的一些经验的来写,可能不是系统全面的介绍。

 

本文链接:

原创内容,转载请注明出处

CDS视图

SQL是让很多程序员感到头痛的东西。过去,由于内表的存在,大家会用简单的SQL取出较多的数据,然后在内表中处理它们,计算主要在应用服务器中进行。但在HANA推出之后,SAP提出了code
pushdown模式,鼓励将更多的工作交给数据库服务器来做,也为ABAP的Open
SQL提供了更强大的功能。可见日后的SQL将变得日益复杂。在复杂的SQL上进行修改可能会耗时较多、测试困难,有时也会不小心造成性能问题。ABAP
CDS视图的引入可以较好的应对这些问题。如果早期的开发者能够利用CDS抽象出稳定的数据模型,把经过若干SQL处理的数据当作已存在的数据来看,那么就能简化ABAP程序中的SQL复杂度,同时也降低后续的开发者和业务顾问的心智负担和沟通成本。

(想一想我们是不是经常说这种冗长的话:XX属性是通过关联A表和B表,使它们的公司、业务编号和移动序号相等,在取消标识不等于’X’等情况下,获取它的某一属性,再到属性对应到的分配表C,获取有效期内的记录——看完并理解这么长一段话之后,也许交流的双方已经只顾着理解XX属性究竟怎样获取,忘记了自己在思考的其它东西。如果这种关联逻辑在公司的需求中是稳定的甚至常常出现的,我们完全可以为它造一个“新词”,即CDS视图。基于CDS视图,之后的沟通方式可以变为:到视图ZCDSXX中,根据取消标识不等于’X’,获取我们需要的XX属性)

硬编码与配置表

这二者的原理在于将对程序的修改变为“扩展”,在不干涉或较少干涉程序代码的情况,完成功能的变更。如果程序的读者看到了程序中的枚举或者常量,那么他就会理解这些东西的修改会造成什么样的影响。一个好的命名可以帮助读者理解它们的作用。

ABAP
7.51中引入了枚举对象,它对于实现程序中的数据的一致性有很好的帮助,相比常量而言强大许多。在相同的场合,可以考虑是否可以用枚举来提高可维护性。

动态技术

动态技术是双刃剑,Field
Symbol和RTTS的使用可以使我们的程序变得十分灵活,但后果是程序的可读性通常不太好,而且对新手来说也绝对是很难修改的。因此,我建议尽量把它作为基础功能的实现,和程序中的硬编码、配置表相结合,或者是通过新建子类的方式来实现功能的扩展,并且附以文档,说明程序的扩展方法。尽可能避免让后人直接修改大量使用动态技术的程序。

中间层

在制作与其它系统对接的接口时,由于各方面的原因,会不时遇到对方希望变更接口的输入输出方式或者格式的情况。这时候,不是直接提供给对方包含业务处理逻辑的接口,而是建立一个外层接口,把原有的接口包装起来,专门用来应对对方的修改,是一个好办法。相似的思路也可以用在其它经常变动的地方。

写有意义的注释

据说写程序不写注释是一种很糟糕的习惯,也有开发规范约束人们:必须要写注释。注释当然是必要的,但是在实践中,大部分人的注释水平是不太好的,往往对阅读起不到什么正面作用,于是甚至催生了一种反叛的、矫枉过正的观点:好的程序从来不需要注释。

最近见到的一个典型的不好的注释:

*处理数据
PERFORM frm_process_data.

这段代码至少犯了3个错误。

  1. 如以文章来对比,FROM的名字即是文章的标题,我们不应该在标题中写明标题是标题。显然,FRM的前缀是无用的,它给不了我们什么信息。
  2. “处理数据”似乎是对FORM功能的描述,这部分内容应该放在FORM的定义处,而不是调用位置。在调用位置的注释,需要写的是:为什么这个FORM需要在这里被调用?为什么不是调用其它一个看起来相似的FROM?
  3. 在注释中写“处理数据”这种泛泛之辞通常产生不了什么意义,更不用说FORM名已经是process
    data(处理数据)了。这种重复有害无益。

这样的注释过多,大概就是很多人反感注释的原因吧。好的注释需要出现在合理的位置,需要写“为什么”而不是“做了什么”。这还是挺考验写作者对程序的理解的,需要有“同理心”,预见读者的需求才可以。

永利网址,善用编辑器为自动生成的注释模板,比如:

 永利网址 1

如果是函数、或者类的话,还可以写专门的文档:

永利网址 2

善用异常

异常是个很有用的东西,但是我很少看到有ABAP开发者用它。我见到的大部分程序使用错误码或者错误标识的方式来处理错误。以我的经验来看,错误码在单层的调用关系中是比较好用的,但是在多层的、复杂的情况下,异常比错误代码要更容易处理和维护。而且异常有着较好的自我描述能力,这在程序的维护中是很有意义的。而很多错误码是单纯的魔法数字,只有开发者本人知道是什么意思,后续维护的人在看到错误代码时,只能认识到:这里有个错误…并不理解每个错误代码的涵义。

避免全局变量

全局变量不好,这是所有开发者的共识。之所以专门还要拿出它来作为一个小节,是因为我觉得这个问题实在普遍且严重。可能因为大部分ABAP二次开发程序都是内容较少的报表,最常用的ALV报表类(函数)则要求其输入的数据内表必须是全局变量,初入行的开发者通常是从全局变量写起的,而较简单的程序逻辑也让开发者没有承受全局变量带来的麻烦….这种惯性使得不少开发者在日后开发相对大型的程序时也会大量使用全局变量。而程序的维护者通常没有精力或能力来识别全局变量对程序的影响,从而在修改程序时造成了意料之外的结果。此外,不加释放的全局变量也会带来性能上的负担。所以我认为开发者应该经常思考是否可以用局部变量代替全局变量、用值传递代替引用传递,时时注意避免全局变量带来的麻烦。 

开源工具

开发人员在工作中可能会需要一些类库,有时人们会自己写类库。在投入时间自己写类库之前,可以先寻找是否存在现成的优秀开源工具。因为私有的东西可能会因为文档不齐备或者人员变动变得无人能理解,也会给新人较大的学习成本。而好的开源工具的生命力更强一些,也有更多同行知道该怎么用。

比如,很多人在写使用OLE生成Excel的程序时会进行一定的封装来处理麻烦的call
method
of语句。在此基础上,人们会形成各自的封装方式,阅读彼此的OLE程序时,就可能要花点时间来观察对方在封装习惯上的细微区别。但是,如果能运用XLSX
Workbench这一优秀的开源工具,大家就可以通过完全相同的方式生成Excel。它使用起来简单、性能优秀,并且(在绝大多数情况下)可以避免写维护起来麻烦的OLE代码。

术语表/词汇表

随时间和空间变化的,不仅仅是程序语言和人们的编码技术,业务语言和日常的交流语言其实也会改变。虽然在一个特定的行业领域里,总会有些大家都知道的名词,然而在软件的生产过程中,关键用户、业务顾问、从前是用户/开发者/业务顾问的领导等人群,毕竟有着不同的背景和经历,对同一个词的理解也许并不一样(具体的原因可能是复杂的,这里不展开讨论)。因为人们的交流是建立在这样不同的基础之上,所以有时就会难免产生误解和低效率的交流。大量的交流时间,往往会浪费在澄清一个基础概念上,有时甚至因为误会造成相当的损失。这种现象在不同的团队/部门之间的交流中尤为常见,也特别有害。

高效率的交流应该以定义作为开始,而非以定义作为结束。为了实现这一目标,引入词汇表也许是个有益的办法。如果需求描述、开发文档、测试用例等都采用约定好、定义明确的业务词汇,用户、业务顾问、开发之间的沟通就不会有歧义,也可以避免某些人在写代码时胡乱命名。这样一来,就能更好地控制词的意义的一致性和变化。由变化引起的维护困难,便由此减轻。

 

没有哪个单一的办法能够保障程序的可维护性,它需要靠各方面的努力来促进。以上是我的一些感想。也欢迎大家发表自己对可维护性的看法,或者对本文的内容进行指正。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

标签:, , , , , , ,
网站地图xml地图