■ 1. プログラミングにおける2つの本質的な力
- 冗長性の最小化:
- 全ての知識を一度だけ定義することが理想
- 依存関係の最小化:
- AがBに依存するのは絶対に必要な場合のみに限定すべき
- 優れたプログラマの特徴:
- 冗長性と依存関係を嫌悪する
- 劣ったプログラマはこれらを気にしない
■ 2. 冗長性と依存関係の衝突
- モジュール境界を越えたコード再利用の問題:
- モジュールAとBが共通モジュールCを使うか各自で実装するかの選択
- モジュール内部での再利用:
- 議論の余地なく再利用すべき
- モジュール間での再利用:
- 第三のモジュールを作成するか「ユーティリティ」モジュールに追加する必要がある
- ユーティリティモジュールの問題点:
- 外部ライブラリへの依存
- 設定の誤り
- 初期化タイミングの問題
■ 3. 経験がもたらすもの
- 経験は知識の蓄積より性格の形成または破壊に寄与する
- 若いプログラマ:
- インフラ構築に積極的
- 第三のモジュール作成を喜ぶ
- ベテランプログラマ:
- インフラ活動に対して否定的反応を示す傾向
■ 4. コマンドライン解析の例
- 機能拡張の誘惑:
- オプション構文の統一
- 値の型対応(文字列/真偽値/整数/16進数/ユーザー定義型)
- ヘルプ文字列
- ヘルプ画面の自動生成
- GUIプロパティページ
- 設定ファイルからの読み込み
- フラグの妥当性チェック
- 過剰設計の実例:
- XParam: 1万行以上のコードと独自シリアライゼーションフレームワーク
- ホストプロジェクトでは機能の5%未満しか使用されない
- 著者自身もXLogという1万行以上のログライブラリを作成し機能の0%しか使用されなかった経験を持つ
- 著者の現在のアプローチ:
- 5行のCコードで単純に解析
- ヘルプ画面やバリデーションは不要と割り切る
- 1万行のパッケージへの依存を回避
■ 5. モジュールの定義と要件
- コンパクトで安定したインターフェース:
- OOの訓練がコンパクトさの軽視を招いている
- 数十のクラスや複雑なデータ構造を公開することが許容されている
- ドキュメント:
- セマンティクスの記述
- サンプルコードの提供が理想
- テスト:
- 各クラスや関数の単体テストではなく公式インターフェースのテストが重要
- 適切なサイズ:
- 1K〜30K LOC(C++換算)が目安
- 大きすぎても小さすぎても泥の塊になる
- オーナー:
- 変更はオーナーを説得して行う
- 一貫したメンタルモデルを維持できる人数は1人
- ライフサイクル:
- 変更はバージョンにまとめて頻繁すぎないリリース
■ 6. 他者のモジュールへの依存の問題
- オーナーシップの問題:
- 作成者が継続的なサポートを認識していない
- 他者による不適切な変更が発生
- 循環依存の発生
- コマンドラインパーサーの潜在的依存先:
- シリアライゼーションパッケージ
- パースパッケージ
- カラーターミナルI/Oパッケージ
- プラットフォーム固有パッケージ
- シングルトン初期化管理パッケージ
- ライフサイクルの問題:
- バージョン互換性の確認
- テストのコンパイルに他者のコードが必要
- 新バージョンが追加の依存関係を引き込む
- インターフェース安定性の問題:
- 破壊的変更によるテストスクリプトの破損
- 予期しない動作変更
■ 7. 生物学的アナロジー
- 生物における冗長性の例:
- 人間とタコは盲目の祖先から独立して類似の眼を進化させた
- 眼全体という複雑な器官が独立して開発される
- 冗長性は進化において機能している:
- 全員の努力を調整するより効果的
■ 8. 結論
- 冗長性の欠点:
- 努力の重複
- 相互運用性の問題
- 依存関係はより深刻:
- 依存すべきは本格的なモジュールのみ
- 無定形なコードの塊には依存すべきでない
- モジュール化の成功可能性の評価基準:
- 実際のオーナーの存在
- 安定したインターフェース
- 全ユーザーを満足させる見込み
- 著者の主張:
- 成功の見込みが低ければ冗長性を選択すべき
- 見積もりは保守的に行うべき
- 冗長性は悪だが依存関係は麻痺を引き起こす
- 依存関係を先に排除すべき