에서 블로그 게시물이 시리즈 , 에릭 Lippert의이 마법사와 예제로 전사를 사용하여 객체 지향 설계에서 문제를 설명 :
abstract class Weapon { }
sealed class Staff : Weapon { }
sealed class Sword : Weapon { }
abstract class Player
{
public Weapon Weapon { get; set; }
}
sealed class Wizard : Player { }
sealed class Warrior : Player { }
그런 다음 몇 가지 규칙을 추가합니다.
- 전사는 칼만 사용할 수 있습니다.
- 마법사는 직원 만 사용할 수 있습니다.
그런 다음 C # 유형 시스템을 사용하여 이러한 규칙을 적용하려고하면 (예 : Wizard
마법사가 직원 만 사용할 수 있도록 클래스를 책임지게 함) 계속해서 발생하는 문제를 보여줍니다 . Liskov 대체 원칙을 위반하거나 런타임 예외 위험이 발생하거나 확장하기 어려운 코드가 생길 수 있습니다.
그가 생각해 낸 해결책은 Player 클래스가 유효성을 검사하지 않는다는 것입니다. 상태를 추적하는 데만 사용됩니다. 그런 다음 플레이어에게 무기를주는 대신 :
player.Weapon = new Sword();
상태는 Command
s에 의해 s에 따라 수정됩니다 Rule
.
... 우리 는 두 개의 게임 상태 객체 a 와 a 를 취하는
Command
객체 를 만듭니다 . 사용자가 시스템에 "이 마법사는 그 검을 휘 두어야합니다"명령을 발행하면 해당 명령은 일련의 의 컨텍스트에서 평가되어 일련의 s를 생성합니다 . 우리는 하나가 플레이어 시도가 무기를 휘두를 때, 효과가 기존의 무기가 존재하는 경우, 삭제하고 새로운 무기가 플레이어의 무기가되고 있다는 것을 말한다. 첫 번째 규칙을 강화하는 또 다른 규칙이 있는데, 이는 마법사가 검을 휘두를 때 첫 번째 규칙의 효과가 적용되지 않는다는 것입니다.Wield
Player
Weapon
Rule
Effect
Rule
저는이 아이디어가 원칙적으로 마음에 들지만 실제로 어떻게 사용되는지에 대해 우려하고 있습니다.
아무것도를 우회하는 개발자를 방지하기 위해 보인다 Commands
과 Rule
간단하게 설정하여이야 Weapon
켜짐 Player
. Weapon
속성은 액세스 할 수 필요 Wield
가 할 수 없도록 명령 private set
.
그럼, 수행 이 일에서 개발자를 방지? 그들은 단지 기억하지 않아야합니까?