Bird와 Penguine을 살펴보자.
    Bird를 Penguin이 상속하게 된다.fly라는 행동을 고려한다면 Bird를 FlyingBird가 상속하고, Penguin은 Bird만을 상속하게 된다.Penguin이 나타나거나 OCP를 위반하는 코드가 나올 수밖에 없다.Monster에는 Dragon도 있고 Troll도 있고 더 추가될 것이다.public abstract Monster {
  private int health;
  // ...
  abstract public String getAttack();
}
public class Dragon extends Monster {
  public Dragon() {
    super(230);
  }
  
  @Override
  public String getAttack() {
    return "용은 불을 내뿜는다.";
  }
}
Monster 설계를 상속이 아닌 합성 관계로 가져가면 이 문제를 개선할 수 있다.public class Breed {
  private String name;
  private int health;
  private String attack;
  
  // ...
}
public class Monster {
  private Breed breed;
  // ...
  
  public String getAttack() {
    return breed.getAttac();
  }
}
Breed 인스턴스 생성과 Monster에 연결하는 작업으로 바뀐다.Monster dragon = new Monster(new Breed("용", 230, "용은 불을 내뿜는다."));
Monster troll = new Monster(new Breed("트롤", 48, "트롤은 곤봉으로 때린다."));
// 게임 도메인 모델은 아래와 같이 표현할 수도 있다.
{
  "breeds": 
  [
    { "name": "용", "health": 230, "attack": "용은 불을 내뿜는다." },
    { "name": "트롤", "health": 48, "attack": "트롤은 곤봉으로 때린다." }
  ]
}