2019年1月6日日曜日

スパゲッティをラザニアにとらえるシステム思考①

「フォークに絡めたカルボナーラ」

はじめに


むかーしむかしのある日、
優秀な諸先輩方が0から構築したソースコードを譲り受け、
私がメンテナンスを担当することとなりました。
設計書がなかったので、スパゲティ(複雑なつくり)だ!と思ったのですが、
理解し読み解くと自分の中で整理され、ラザニア(階層化された奇麗なつくり)
のようにとらえメンテナンスができたので、その時の自分の思考をまとめます。

題して、

「スパゲティに見えた先人の食べ残しをラザニアととらえる思考法」です。


(注意)私が取り組んだ初めてみるコードの読み方と、リファクタリング時の考え方を紹介するフィクションとして読んでいただければと思います。
実際に引き継いだコード自体は、複雑ではあったものの高品質な状態だったので、複雑なコードを高品質な状態を維持してメンテナンスするコツを中心に記載します。

ほんとうにスパゲティなの?


私は、まず立ち返りました。
「渡されたコードが本当にスパゲティであるのかを確認しよう。」

まず、以下の確認をします、
・外部仕様書、詳細設計書、テスト仕様書(チェックリスト)の存在有無。

確認したところ、
最終更新日がえらく古かったが、外部仕様書は丁寧なものが発掘されました。
テスト仕様書は、品質管理部門が承認しているチェックリストが存在していました。

すなわち、
「どのように振舞うべき」は定義しているが、
「どのように実装すべき」は問われない状態です。
※少なくとも、「どのように振舞うべき」が正しく定義されていれば、スパゲティを読み解く難易度は格段に下がるので初めに確認しましょう!

次に、コードを以下のポイントで確認します。
①機能実現のための共通実装部が存在するかどうか(横観点のレイヤー確認)
②隠ぺいすべき実装があるかどうか、
 また、あった場合は隠ぺいされているかどうか。(横観点の一環)
③外部仕様書に記載される各機能がどのような単位で実装されているか
 (縦観点のレイヤー確認)

横観点のレイヤー確認とは


私は、ソフトウェアを構造的に把握するために、
まず、以下の観点でコードをとらえるようにしています。
( ①と②の横観点でのレイヤー確認)

自担当のソフトをザックリと以下の3層
(隠ぺい層は無い場合もあるので最低2層)でとらえます。

・アプリケーション層:
  ユーザーI/Fや他ソフトウェアから要求されるI/Fをまとめた層。
・ライブラリ層:
  アプリケーション層にある複数機能で同じ振舞いをする場合に共通実装層。
・隠ぺい層:
  OSや、DBエンジンなど、
  ソフト全体が別環境でも動くよう低レイヤーの処理を隠ぺいする層。 
  ※要件により、無い場合もあります。



※ちなみに、本当に難解なスパゲティコードは、この3層(ないし2層)にすることも困難なケースがありますが、その場合のコードの読み解き方は次回以降に紹介します。


縦観点のレイヤー確認とは


次に、機能に必要な実装部を縦に切り出していきます。(③の縦観点のレイヤー確認)
外部仕様書やテスト仕様書に記載されている機能単位で切り出し、くくります。
すると、階層構造の全貌が分かると思います。


レイヤー確認の具体例


たとえば、javaの場合、
コンパイルされた.jarファイルをマッピングするだけでも理解しやすいです。
.jarファイルでなく.java(クラス)ファイルでも、パッケージでも同じ粒度で
マッピング可能だと思います。


次に、各機能を切り出したとき、関係する.jarファイルがそれぞれの機能に
割り当たるよう図示してみます。

こうすると、
・機能2の隠ぺい化が不十分ではないか?
・機能3は共通化ライブラリが少ないのはなぜか?
・実は、C.jarとして切り出せる C’.jar を利用している。
などを把握するキッカケになります。

①はいったん、こんなところで、

次回は、切り出した後にコード把握するコツを説明しようと思います。

0 件のコメント:

コメントを投稿