アンチパターンは、合理的に見えるが設計を悪化させる反復的な「解決策」です。OOPで最も一般的なのは、God Object、深い継承階層、およびAnemic Domain Modelです。
God Object
多くのことを知り、実行しすぎるクラス — Single Responsibilityを違反します。
java
{
{} {} {}
{} {} {}
}
Entity → LivingThing → Animal → Mammal → Carnivore → Feline → Cat → HouseCat
各レベルはすべての祖先に結合されます。トップ付近の変更は至る所に波及します (fragile base class)。Fix: compositionで平坦化します。深い "is-a" チェーンより "has-a" 機能を優先します。
getters/settersの単なるバッグであるオブジェクトで、すべてのロジックは別の場所に — OOPは名前だけです。
// ANEMIC: data with no behavior; rules live in a separate "service"
class Order { List<Item> items; double total; /* only getters/setters */ }
class OrderService { double calcTotal(Order o) { ... } } // logic exiled
// RICH: behavior lives with the data it operates on
class Order {
private List<Item> items;
double total() { return items.stream().mapToDouble(Item::price).sum(); }
}
→ Yo-yo problem (jumping up/down a deep hierarchy to follow logic)
→ Circular deps (A needs B needs A)
→ Feature envy (a method that mostly uses another class's data)
アンチパターンは良い意図がどのように腐るかです: God Objectは通常小さなヘルパーとして始まり、anemicモデルは「単なるDTO」として始まり、その後固化します。
それらに名前をつけることで、チームはコードレビューで共有された初期警告ボキャブラリーを得ることができ、各アンチパターンはそれを修正する原則 (SRP、composition、encapsulation) に直接指摘します。