SAP系統作為企業的資訊系統,其生命周期通常是漫長的,比單個程式員的在職時間要長得多。早期實施階段花大力氣開發的自定義程式,會傳遞給企業内部或外部的運維團隊來維護——不管怎麼樣,一般不是最初的開發者了。即便是在運維階段,程式的建立者與修改者也常常不是一個人。不同的開發者,其知識基礎、技術水準、編碼風格難免有所不同,最早建立的程式,經過若幹個獨一無二的開發者的修改,可能會變得面目全非,失去可維護性。這時的程式可以說已經接近于死亡...是以,作為程式的開發者,我們需要讓自己的程式對修改有抵抗力,進而能在後人的維護下活的更久一些。
當然,抵抗修改的意思,并不是指妨礙後人修改程式。企業的業務是多變的、人們對需求的了解是不斷加深的,因而程式的修改也是必要的。抵抗修改的目标應當是:在合理的需求變動發生時,盡量讓修改變得容易,并減小修改帶來的破壞,進而讓程式能承受更多次的修改。
我認為問題的關鍵在于減少耦合度、理清程式職責的配置設定,清晰的程式描述也很重要:
耦合度即子產品之間的關聯強度。高耦合度的程式牽一發而動全身,隻适合于需求十分穩定的程式。對于多變的ABAP程式來說,降低耦合度可以減少程式修改對其它部分的影響,是比較重要的。
單純的解耦工作有可能讓我們陷入為解耦而解耦的陷阱。了解程式的職責配置設定可以讓我們更加理性地運用技術,并且使程式對修改有更好的适應性。
程式的描述包含命名、程式結構這種“自我描述”,也包括程式注釋、技術文檔,以及需求文檔。這可能是最容易改善的一個方面。
下面結合具體的ABAP開發技術來談談我對它們的想法,因為隻是根據自己的一些經驗的來寫,可能不是系統全面的介紹。
本文連結:http://www.cnblogs.com/hhelibeb/p/7891401.html
原創内容,轉載請注明出處
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個錯誤。
- 如以文章來對比,FROM的名字即是文章的标題,我們不應該在标題中寫明标題是标題。顯然,FRM的字首是無用的,它給不了我們什麼資訊。
- “處理資料”似乎是對FORM功能的描述,這部分内容應該放在FORM的定義處,而不是調用位置。在調用位置的注釋,需要寫的是:為什麼這個FORM需要在這裡被調用?為什麼不是調用其它一個看起來相似的FROM?
- 在注釋中寫“處理資料”這種泛泛之辭通常産生不了什麼意義,更不用說FORM名已經是process data(處理資料)了。這種重複有害無益。
這樣的注釋過多,大概就是很多人反感注釋的原因吧。好的注釋需要出現在合理的位置,需要寫“為什麼”而不是“做了什麼”。這還是挺考驗寫作者對程式的了解的,需要有“同理心”,預見讀者的需求才可以。
善用編輯器為自動生成的注釋模闆,比如:

如果是函數、或者類的話,還可以寫專門的文檔:
善用異常
異常是個很有用的東西,但是我很少看到有ABAP開發者用它。我見到的大部分程式使用錯誤碼或者錯誤辨別的方式來處理錯誤。以我的經驗來看,錯誤碼在單層的調用關系中是比較好用的,但是在多層的、複雜的情況下,異常比錯誤代碼要更容易處理和維護。而且異常有着較好的自我描述能力,這在程式的維護中是很有意義的。而很多錯誤碼是單純的魔法數字,隻有開發者本人知道是什麼意思,後續維護的人在看到錯誤代碼時,隻能認識到:這裡有個錯誤...并不了解每個錯誤代碼的涵義。
避免全局變量
全局變量不好,這是所有開發者的共識。之是以專門還要拿出它來作為一個小節,是因為我覺得這個問題實在普遍且嚴重。可能因為大部分ABAP二次開發程式都是内容較少的報表,最常用的ALV報表類(函數)則要求其輸入的資料内表必須是全局變量,初入行的開發者通常是從全局變量寫起的,而較簡單的程式邏輯也讓開發者沒有承受全局變量帶來的麻煩....這種慣性使得不少開發者在日後開發相對大型的程式時也會大量使用全局變量。而程式的維護者通常沒有精力或能力來識别全局變量對程式的影響,進而在修改程式時造成了意料之外的結果。此外,不加釋放的全局變量也會帶來性能上的負擔。是以我認為開發者應該經常思考是否可以用局部變量代替全局變量、用值傳遞代替引用傳遞,時時注意避免全局變量帶來的麻煩。
開源工具
開發人員在工作中可能會需要一些類庫,有時人們會自己寫類庫。在投入時間自己寫類庫之前,可以先尋找是否存在現成的優秀開源工具。因為私有的東西可能會因為文檔不齊備或者人員變動變得無人能了解,也會給新人較大的學習成本。而好的開源工具的生命力更強一些,也有更多同行知道該怎麼用。
比如,很多人在寫使用OLE生成Excel的程式時會進行一定的封裝來處理麻煩的call method of語句。在此基礎上,人們會形成各自的封裝方式,閱讀彼此的OLE程式時,就可能要花點時間來觀察對方在封裝習慣上的細微差別。但是,如果能運用XLSX Workbench這一優秀的開源工具,大家就可以通過完全相同的方式生成Excel。它使用起來簡單、性能優秀,并且(在絕大多數情況下)可以避免寫維護起來麻煩的OLE代碼。
術語表/詞彙表
随時間和空間變化的,不僅僅是程式語言和人們的編碼技術,業務語言和日常的交流語言其實也會改變。雖然在一個特定的行業領域裡,總會有些大家都知道的名詞,然而在軟體的生産過程中,關鍵使用者、業務顧問、從前是使用者/開發者/業務顧問的上司等人群,畢竟有着不同的背景和經曆,對同一個詞的了解也許并不一樣(具體的原因可能是複雜的,這裡不展開讨論)。因為人們的交流是建立在這樣不同的基礎之上,是以有時就會難免産生誤解和低效率的交流。大量的交流時間,往往會浪費在澄清一個基礎概念上,有時甚至因為誤會造成相當的損失。這種現象在不同的團隊/部門之間的交流中尤為常見,也特别有害。
高效率的交流應該以定義作為開始,而非以定義作為結束。為了實作這一目标,引入詞彙表也許是個有益的辦法。如果需求描述、開發文檔、測試用例等都采用約定好、定義明确的業務詞彙,使用者、業務顧問、開發之間的溝通就不會有歧義,也可以避免某些人在寫代碼時胡亂命名。這樣一來,就能更好地控制詞的意義的一緻性和變化。由變化引起的維護困難,便由此減輕。
BRF+
一個SAP推出的業務規則架構,可以通過配置的方式實作自定義業務邏輯,有助于實作自定義業務邏輯的統一管理,并将其運作情況透明化。詳情可見:SAP中的BRF+。
沒有哪個單一的辦法能夠保障程式的可維護性,它需要靠各方面的努力來促進。以上是我的一些感想。也歡迎大家發表自己對可維護性的看法,或者對本文的内容進行指正。