アンチパターン

ソフトウェア開発におけるアンチパターン () とは、必ず否定的な結果に導く、しかも一般的に良く見られる開発方式を記述する文献形式を言う。その内容は、基本的には、否定的な開発方式の一般的な形、主原因、症状、重症化した時の結果、そしてその対策の記述からなる。

デザインパターンを補完・拡張する関係にあるもので、多くの開発者が繰り返すソフトウェア開発の錯誤を明確に定義することにより、開発や導入を阻害する一般的で再発性の高い障害要因の検知と克服を支援することが目的である。

 概要 
ある問題に対する、不適切な解決策を分類したものをアンチパターンと言う。
アンチパターンという呼び方は、が1995年に作り出したもので、後に書籍The patterns handbookで再掲された。

ギャング・オブ・フォーの書籍『オブジェクト指向における再利用のためのデザインパターン』からヒントを得て、書籍AntiPatternsが出版され、3年後には「アンチパターン」という単語はソフトウェアの設計から一般的な社会の相互作用についても広く用いられるようになった。AntiPatternsの著者によれば、アンチパターンと単なる悪癖、悪習などと区別するには二つの要素があるという。

 動作やプロセス、構造についての繰り返されるパターンで、最初は有益だと思えるが、最終的に悪い結果をもたらすもので、
 リファクタリングするための方法が存在し、文書化され、実例で証明されており、再現可能であること

数多く挙げられたアンチパターンは、矛盾した言葉を侮蔑的に用いた新しい用語で呼ばれ、可能なら避けられるべき、単なる誤り、未解決の問題、悪習以上の意味を持っている。「落とし穴」や「暗黒のパターン」とも呼ばれる別の呼び方があるが、これは、悪い問題の解決策が再発明されることを指す。こうしたアンチパターンの候補は、公式にアンチパターンとは考えられない。

繰り返される間違いを記述することによって、繰り返しにつながる力学的な構造や、誤ったパターンを取り除くようリファクタリングする方法を学習することができる。

よく知られるアンチパターン

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

肥満児（The Blob）
肥大化したオブジェクト
 (poltergeist)
オブジェクトに情報を渡すことだけが目的のオブジェクト
溶岩流（lava flow）
除去することが非常に困難で、結果が予測できないために悪い(冗長で品質の低い)コードを維持する
打出の小槌（golden hammer）
気に入った方法が、あらゆるところで利用できると思い込む（銀の弾丸も参照）
スパゲッティコード (spaghetti code)
構造がほとんど理解できないようなシステム、特にコードの構造が誤っているもの
（copy and paste programming）
汎用的なコードを作らず、既存のコードをコピーし（改変して）使う

（ambiguous viewpoint）
(通例オブジェクト指向分析設計において)表現される視点を示さずに記述されたモデル
（input kludge）
正しくない入力の検出や扱いの失敗
（mushroom management）
部下に情報を伝えなかったり、誤った情報を伝える(暗所で栽培する)

 ソフトウェア基盤のアンチパターン 
（stovepipe system）
複雑に相互関連したコンポーネントからなる、メンテナンスが困難なシステム
砂上の楼閣 (vendor lock-in)
外部提供のコンポーネントに極度に依存したシステム
（design by committee）
多数の人間が設計に関与しているが、統一された考え方がないこと
車輪の再発明 (reinventing the wheel)
すでに知られている適切な解決方法を採用しない

 組織上のアンチパターン 

収益が上がっている古い製品に満足して、新しい製品に無頓着になること

後で誤っていると判っても、決定を取り消せないこと

異議を許さない、独裁的な組織管理方法
モラル・ハザード
意思決定者が、意思決定の結果から隔離されていること

上下方向の情報の流れが強く、組織間のつながりを禁じる組織構造

 プロジェクト管理上のアンチパターン 
（analysis paralysis）
プロジェクトの分析段階に、不釣合いなほどの労力を費やすこと
デスマーチ (Death March)
プロジェクトが大失敗に終わることを CEO 以外全員が気づいているが、プロジェクトはデイ・ゼロ（ビッグバン）が来るまで無理やり存続させられる。あるいは、理解できない締め切りのため、従業員が深夜や休日まで勤務するよう強要される
集団思考 (Group Think)
集団の各メンバーが、同意が得られそうな領域以外の考え方を避ける

未実装の機能を実装されているように見せる
ソフトウェアの肥大化 (Software Bloat)
システムの後続のバージョンに、より多くの人員が必要になる
スコープ・クリープ (Scope creep)
プロジェクトの開始後に、プロジェクトのスコープ（範囲）が継続的に変化または適切な管理無しで増大する

オブジェクト指向設計のアンチパターン

ビジネスロジックが欠けたドメインモデル。オブジェクトは属性と振る舞いを持たなければならないので、オブジェクト指向プログラミングではない

ユーティリティクラスに処理を委譲せず、継承して使ってしまうこと

サブクラスがスーパークラスのオーバーライドされたメソッドを呼び出さなければならないような設計

変更できない型から変更可能な派生型を作成する際の問題

オブジェクトやモジュール間の直接的・間接的な依存関係を不必要に取り込んでしまうこと

インターフェイスを定数の定義に用いること

設計の一部分（クラス）に、過剰に機能を集中させること

再利用に必要な（暗黙のうちの）規則に合致しない状態のオブジェクトを再利用する

内部へのアクセスを制限なく許し、適切なカプセル化に失敗する

メソッドが特定の順序で呼び出される必要のあるクラス
ヨーヨー問題
過剰な断片化により、理解するのが難しい構造（たとえば継承関係）

プログラミングのアンチパターン

問題の解決に不要な複雑性を導入する

システムの大きく分散した部分同士が相互作用する

バグ修正の正しさ、あるいはサブルーチンの結果を確認しないこと

もはや使用されていない部分をそのままにしておく
ビジーウェイト (Busy spin)
何らかの事象が発生するのを待つ際に、メッセージングを使わずに、繰り返し確認することでCPUを無駄に使用する

回復された後も、エラーフラグをリセットしない
カーゴ・カルト・プログラミング (Cargo cult programming)
パターンや方法論を理由を理解せずに用いる

特殊なケースが認識される度に、それに対応するコードを追加する

エラーメッセージをユーザーに通知する前に捕捉し、隠蔽したり、安全なメッセージを見せたりする

プログラミング言語のエラー捕捉機構を、正常なプログラムのロジック記述に使用する
ハードコード
システムの動作環境についての仮定を実装に埋め込む

switch文を使った順序的な処理を、ループ文の中に埋め込む
マジックナンバー (Magic numbers)
説明のない数値をアルゴリズムで使用する
マジックストリング (Magic string)
イベントの比較などのために、リテラルの文字列を用いる
ソフトコーディング (Softcoding)
ビジネスロジックをソースコードではなく設定ファイルに格納する

方法論のアンチパターン

既知のエラーを、実際に発生することはないだろうと思い込む
尚早な最適化 (Premature optimization)
初期の段階から効率を追求してコーディングし、良い設計やメンテナンス性を犠牲にしてしまう。時には現実の効率も悪化させてしまう
/偶然にもとづくプログラミング
コードを徐々に修正しながら動くかどうかを確認することで、問題を解決しようとする
銀の弾丸 (Silver bullet)
気に入った方法が、問題の大半を解決できると思い込む

新しい要求がバグ報告書で記述されるようなプロジェクト

構成管理のアンチパターン
依存関係地獄
必要とする構成要素のバージョンによる問題
DLL地獄 (DLL hell)
特にMicrosoft Windowsにおける、ダイナミックリンクライブラリ (DLL) の不適切な管理

Classic Mac OSにおいて、オペレーティングシステムの同じ箇所に異なる機能拡張を追加しようとした際に発生する問題
JAR地獄 (JAR hell)
JARファイルを使用しすぎ、Javaクラスローダーのモデルを理解しておらず、バージョンや配置場所の問題を生じる