2021-08-01

"レガシーコード改善ガイド" Michael C. Feathers 著

P. F. ドラッカーは、こんな言葉を遺してくれた...


"If you can't measure it, you can't manage it."
「測定できないものは管理出来ない。」


"measure" を "test" に置き換えれば、まさに本書が意図するところ...
尚、平澤章、越智典子、稲葉信之、田村友彦、小堀真義訳版(ウルシステムズ株式会社)を手に取る。


モノづくりの現場には、科学同様、観察の哲学がある。まずは観ること、そして状態を知ること。状態を正しく見極めなければ、間違った方策を施し、さらに状態を悪化させる。設計開発で身を立てるなら、この状態を知るという検証プロセスからは逃れられない。そして、検証作業の効率化を図り、実績ある資産を蓄積していく。
では、これらの資産を再利用するためには、どのような状態にしておくべきか。ずっと悩まされてきた課題である。本書は、ソフトウェアの視点から大きなヒントを与えてくれる。
ちなみに、おいらはソフトウェア設計者ではない。ハードウェア設計者だ。それでも、アルゴリズムの検証に C 言語系や数値演算言語などを用い、実行コマンドにスクリプト言語を組み合わせ、アーキテクチャをハードウェア記述言語で実装する。設計開発において、プログラミングと無縁でいられる現場を、おいらは知らない。
そして、流用モジュールを政治的に押し付けられることも...


お偉いさんは、神話に取り憑かれる。過去のモジュールを流用すれば、開発期間が大幅に短縮できる... と。しかも、バグリスト付きときた。バグの所在が分かっているのなら、修正してからもってこい!っちゅうの。いや、修正できない!手に負えない!ってことだ。
政治的に押し付けられる流用モジュールは、たいていレガシーコードだ。モジュールが放つ異臭は、人間関係までも胡散臭くさせる。プロジェクトの健全性を保つなら、すぐにポイ!
しかしながら、現場では、簡単にポイ!できないケースが多い。理解不能コードの変更を外部に依頼すれば、責任の外注となる。


ソフトウェア業界には、もっと悲惨な事例で溢れているようで、本書に励まされる。マイケル・C・フェザーズは、何年もの間、様々なチームで深刻なコードを克服する手伝いをしているうちに、ある定義にたどり着いたという。
「レガシーコードとは、単にテストのないコードです!」
なかなか挑発的な定義だ。ソースコードがきれいで、きちんと構造化されているだけでは不十分... オブジェクト指向が採用され、きちんとカプセル化しているなんてことは核心ではない... というのである。
まず、メソッドにテストがなければ、テストを書く。これを習慣づけると、テストがコミュニケーション手段になり、テストを見るだけで、メソッドに何が期待できるかを感じ取れようになる。クラスをテスト可能にするだけでコード品質が向上する。ライブラリを過信して乱用するのは危険である。そして、コード改善の中心は依存関係の排除にある... と。


おいらは、長い間、ドキュメント化が重要な要素だと考えてきた。その考えが変わったわけではないが、きちんとドキュメント化されていたとしても、ソースコードと完全に対応している保証はどこにもない。変更作業でコードとドキュメントで二度手間になるのでは、何をやっているのやら。
コードが美しいに越したことはない。が、それでバグがないという保証にはならない。何事も整理整頓、環境美化が作業効率を上げ、合理性を高めることは確かだが、何か足りない。
それは、「より現実に...」という観点か。
力学では物体が運動している状態こそが現実であり、ソフトウェアでは振る舞いこそが現実となる。モジュール設計の現場で最もプリミティブな現実は、テストぐるみの動作状態ということになろうか。なるほど、テストが書けるか書けないかが、ポイ!するかどうかの判断基準になりそうだ。
システム設計へのアプローチにおいて、「ドメイン駆動設計」という考え方にも共感できるが、本書が提唱する「テスト駆動設計」という考え方もなかなか。そして、設計の核心をつく、このフレーズとともに...
「ネーミングは設計の中心である。優れたネーミングはシステムの理解を助け、作業を容易にする。しかし、貧弱なネーミングはシステムの理解を妨げ、後でシステムを扱うプログラマに辛い日々を送らせる。」


プログラムの基本構造は、順次処理、分岐処理、反復処理に、あとは、call ぐらいでだいたい説明がつく。
但し、構造化の掟では、goto 文のような、どこへでも飛べる裏技は御法度!
つまり、プリミティブなレベルでは、すこぶる単純な構造で、関数の呼び出しでほぼ抽象化できる。この構成単位となる関数を一つの機能モジュールとして眺めれば、ハードウェアでも同じこと。
となれば、関数レベルで機械的にテストルーチンを組み込むことは可能かもしれない。本書の事例で見る、関数単位でラップしてコードを保護しながらテストを埋め込んでいくといった具合に。ここでは、「テストハーネス」と呼んでいる。
機械的にテストを埋め込む法則が編み出せれば... いや、コーディングルールをテスト仕様にするか... いやいや、言語仕様そのものがそうなっていくのか...
それにしても、ソフトウェア業界の商売戦略は、お見事!一番コストのかかるテストを、一般ユーザにやらせているのだから。β版などと称して。オタクの姑チェックで成り立っている業界というわけか...


おいらは検証環境に対して、それなりに思い入れがある。というのも、設計開発の現場で検証環境を構築をすることが多い。設計作業は若手に任せて。検証プロセスは、経験や勘所も重要で、マネジメントと直結するところもある。つまり、歳のせいか...
よく耳にするのは、プロマネなんだから、コーディングは部下にやらせろ!というお偉いさんの声。しかし、おいらは現場から離れたくないので、強く反発する。ただ、検証環境の構築はおもろいが、検証作業そのものは大っ嫌い!だから、よく自動化に突っ走って地雷を踏む...
実際にテストコードを埋め込もうとすると、モジュールの内部と外部のどちらに持たせるか、いつも悩ましい。余計なモジュールを作りたくないので、なるべく内部に持たせたいが、助長したモジュールはハードウェアの実装では躊躇する。
ただ、リソースの贅沢な昨今、そんな配慮からも解放されつつある。昔は、故障検出率を考慮してモジュールの作り込みにも気を配ったものだが、いまや自動化されて。その分、要求仕様が膨れ上がって仕事量は減らないけど。いや、増えたか...
カバレッジの自動化にも助けられている。カバレッジそのものは非常に有効で、予期しないバグを発見することもあるが、自動化を鵜呑みにするのは危険か。ハードウェア的な機能検証とソフトウェア的なカバレッジでは、目的が少し違うし...
それにしても、人間社会とは奇妙なものである。自動化して便利になると、なぜか?仕事量が増えやがる。人間ってやつは、生まれつき仕事の奴隷ってか...

0 コメント:

コメントを投稿