Chapter 06

【アンチパターン】ソフトウェア開発

たなかなた
たなかなた
2022.12.12に更新

肥満児(The Blob)

  • 発生
    • 一つのクラスが処理を独占し、その他のクラスがもっぱらデータのカプセル化を担当している(そもそもオブジェクト指向にもなっておらず、手続き型になっている)
  • 回避
    • 責任分解してリエンジニアリングし、オブジェクトの動作を肥満児の外に移し、肥満児をダイエットさせる
  • 参考文献

絶え間なき陳腐化(Continuous Obsolescence)

  • 発生
    • 急速な技術変化に律儀に付き合って、バージョンアップ対応を行うも、バージョンアップした時には既に新しい技術が生まれており、イタチごっこが続く
  • 回避
    • 安定的なインターフェースや自分たちで自由に制御できるインターフェースを採用する
  • 参考文献

溶岩の流れ(Lava Flow)

  • 発生
    • プロジェクト発足時に噴火したプログラムが溶岩として流れ出し、後続対応による更なる噴火でその上にプログラムが積み重なり、古いプログラムが取り除けなくなってしまう
  • 回避
    • 製品版のコード開発は、良質なアーキテクチャを先行させる(実験的や試行的なコードは製品版では取り除く事を徹底する)
  • 参考文献

曖昧な視点(Ambiguous Viewpoint)

機能的分解(Functional Decomposition)

  • 発生
    • オブジェクト指向なプロジェクトにおいて、オブジェクト無指向な設計および実装を行う
  • 回避
    • ユーザの視点から見た重要な機能を説明するドキュメントを作成し、機能を組み直した新たな設計形式を作る
  • 参考文献

お邪魔妖怪(Poltergeist)

  • 発生
    • 不要な抽象クラスをいくつも作り出し、幽霊のように儚いクラスにより、ソフトウェア設計を乱雑にする(例:他クラスのメソッドを呼び出すだけのコントローラクラスなど)
  • 回避
    • ゴーストバスターズ!
    • クラス階層から不要なクラスを取り除き、妖怪たちが担当していた機能性を適切なクラスに移す
  • 参考文献

蛇足(Boat Anchor)

打ち出の小槌(Golden Hammer)

  • 発生
    • 特定ベンダの特定製品・技術(=打ち出の小槌)を、開発チームが使い倒していて、その製品や技術を使うのがベストだと思い込んでいる
  • 回避
    • 日常亭な業務に取り組むだけでなく、新技術のキャッチアップに努める(そのための管理者による奮起も必要)
  • 参考文献

梯子外し(Dead End)

  • 発生
    • 再利用コンポーネントの部分変更をしたが、そのコンポーネントがサポート終了しており、十分なドキュメントも存在していない
  • 回避
    • 商用製品のカスタマイズは避ける。再利用ソフトウェアの変更は避ける。
  • 参考文献

スパゲッティコード(Spaghetti Code)

  • 発生
    • 初期コードからの拡張によって構造が無視され、再利用性が欠如し、オブジェクト間の関係性も希薄なプログラムやシステムとして出現する
  • 回避
    • リファクタリング(コードのクリーニング)を行う
  • 参考文献

入力クラッジ(Input Kludge)

  • 発生
    • 簡単な動作確認で不合格になるようなプログラム。その場しのぎの即席アルゴリズムを適用している。
  • 回避
    • デモ版ではない製品版では、語彙分析や構文解析などの品質担保されているアルゴリズムを用いる
  • 参考文献

地雷原(Walking through a Minefield)

  • 発生
    • 発売/納品されたソフトウェアにも往々にして数多くのバグが潜んでいるが、自組織のソフトウェアもバグを潜んだままリリースしてしまう
  • 回避
    • ソフトウェアの試験に対して適切な投資を行いリソースを割く。テストスイーツを作成して、自動テストを行う。
  • 参考文献

切り貼りプログラミング(Cut-and-Paste Programming)

  • 発生
    • ソフトウェアの再利用の退化した形式。同じようなコードがソフトウェアプロジェクトの全体に渡って何箇所も存在する
  • 回避
    • ホワイトボックス的な再利用ではなく、ブラックボックス的な再利用を推奨する
  • 参考文献

暗室栽培(Mushroom Management)

リーダブルパスワード(読み取り可能パスワード)

  • やりたい事
    • パスワードのリカバリやリセットをしたい
  • アンチパターン
    • 暗号化して保存する。平文でクエリを生成する。
  • 解法
    • ハッシュ関数とソルトを用いる(アプリ側でハッシュ化する事で、クエリはハッシュ後の値で生成される。)
  • 参考文献

SQLインジェクション

  • やりたい事
    • 動的SQLを記述したい
  • アンチパターン
    • リクエストパラメータを検証せずそのままSQLに用いる
  • 解法
    • エスケープやサニタイズを行う。プリペアードステートメントを用いる。引用符で囲む。不正な場合は定義済みの値を使用する。など。
    • 積極的にコードレビューを行い、徹底的に脆弱性を駆逐する。
  • 参考文献

シュードキー・ニートフリーク(疑似キー潔癖症)

  • やりたい事
    • 欠番の扱いを考えたい
  • アンチパターン
    • 採番し直して欠番を埋める(自然キーならまだしも、疑似キーは詰めるべきではない。行のスキップやロールバックや削除などにより正当に欠落するのであり、詰めてしまうと不整合が発生する。)
  • 解法
    • 疑似キーにGUIDを使用する。欠番は埋めるべきではないと主張する。埋めたいなら疑似キーではなく自然キーを用いる。
  • 参考文献

シー・ノー・エビル(臭いものに蓋)

  • やりたい事
    • クールでエレガントなコードを書きたい
  • アンチパターン
    • 簡潔に書き過ぎたり、診断を怠ったり、エラーログを見ずにコードでしか原因調査をしない。
  • 解法
    • アプリ内に書かれたSQLではなく、実際に生成されるSQLを使う。戻り値や例外をチェックするコードを書く。
  • 参考文献

ディプロマティック・イミュニティ(外交特権)

  • やりたい事
    • ソフトウェア開発のベストプラクティスを適用したい
  • アンチパターン
    • ソフトウェア開発とデータベース開発は別物と捉え、データベース開発を悪い意味で特別視する(独自対応が多く属人化も発生するため、技術的負債になりがち)
  • 解法
    • ソフトウェア開発のベストプラクティスに従い、QA(品質保証)を行う
  • 参考文献

マジックビーンズ(魔法の豆)

  • やりたい事
    • MVCアーキテクチャを使いたい
  • アンチパターン
    • モデルに全てを詰め込む(基底クラスを継承すると『黄金のハンマーアンチパターン』が発生しがち)
  • 解法
    • 「アクティブレコード(=DAO)」「モデル(=DTO)」「ビジネスロジック(=Service)」を分離する(魔法の豆も銀の弾丸も存在しない)
  • 参考文献

砂の城

  • やりたい事
    • サービスを安定稼働させたい
  • アンチパターン
    • すべき対策を講じておらず、砂上の楼閣状態となっている(対策を講じないのはシステムエラーではなくヒューマンエラー)
  • 解法
    • あらゆるパターンを想定し、ベンチマークの取得やバックアップ、冗長化などを行う。ディザスタリカバリや運用ポリシーを策定する。
  • 参考文献