이 질문 에 후속 조치를 취하고 있지만 코드에서 원칙으로 초점을 전환하고 있습니다.
의 나의 이해에서 Liskov 대체 원칙 방법은 내 기본 클래스에있는 어떤 (LSP), 그들은 내 서브 클래스에서 구현되어야하며,에 따라 이 페이지는 기본 클래스의 메소드를 오버라이드 (override)하는 경우 그것은 아무것도하지 않는다 또는를 던졌습니다 예외, 당신은 원칙을 위반합니다.
이제 내 문제는 다음과 같이 요약 될 수있다 : 나는 추상이 Weapon
class
, 2 개 개의 클래스를, Sword
하고 Reloadable
. 이라는 Reloadable
특정을 포함하는 경우 다운 캐스트하여 액세스해야 하며 이상적으로는 피하고 싶습니다.method
Reload()
method
그런 다음을 사용하는 것을 생각했습니다 Strategy Pattern
. 이런 식으로 각 무기는 자신이 수행 할 수있는 행동 만 알 수있었습니다. 예를 들어, Reloadable
무기는 분명히 재 장전 Sword
할 수는 있지만을 (를) 인식하지 못하고 심지어조차도 알지 못합니다 Reload class/method
. 스택 오버플로 게시물에서 언급했듯이 다운 캐스트 할 필요가 없으며 List<Weapon>
컬렉션을 유지할 수 있습니다 .
에 또 다른 포럼 , 첫 번째 대답은 할 수 있도록 제안 Sword
을 인식하는 Reload
단지 아무것도하지 않습니다. 위와 연결된 Stack Overflow 페이지에서도 이와 동일한 답변이 제공되었습니다.
이유를 완전히 이해하지 못합니다. 왜 원칙을 위반하고 Sword가 인식 Reload
하고 비워 두는가? 내 스택 오버플로 게시물에서 말했듯이 SP는 내 문제를 거의 해결했습니다.
실행 가능한 솔루션이 아닌 이유는 무엇입니까?
public final Weapon{
private final String name;
private final int damage;
private final List<AttackStrategy> validactions;
private final List<Actions> standardActions;
private Weapon(String name, int damage, List<AttackStrategy> standardActions, List<Actions> attacks)
{
this.name = name;
this.damage = damage;
standardActions = new ArrayList<Actions>(standardActions);
validAttacks = new ArrayList<AttackStrategy>(validActions);
}
public void standardAction(String action){} // -- Can call reload or aim here.
public int attack(String action){} // - Call any actions that are attacks.
public static Weapon Sword(String name, damage, List<AttackStrategy> standardActions, List<Actions> attacks){
return new Weapon(name, damage,standardActions, attacks) ;
}
}
공격 인터페이스 및 구현 :
public interface AttackStrategy{
void attack(Enemy enemy);
}
public class Shoot implements AttackStrategy {
public void attack(Enemy enemy){
//code to shoot
}
}
public class Strike implements AttackStrategy {
public void attack(Enemy enemy){
//code to strike
}
}
reload()
빈 여부를 standardActions
다시로드 작업을 포함하지 않는 것은 단지 다른 메커니즘입니다. 근본적인 차이는 없습니다. 둘 다 할 수 있습니다. => 귀하의 솔루션 은 실행 가능합니다 (귀하의 질문이었습니다) .; 무기에 빈 기본 구현이 포함되어 있으면 검에 재 장전을 알 필요가 없습니다.
class Weapon { bool supportsReload(); void reload(); }
. 클라이언트는 다시로드하기 전에 지원되는지 테스트합니다.reload
iff를 던지기 위해 계약 상 정의됩니다!supportsReload()
. 그것은 LSP를 준수합니다. iff 구동 클래스는 방금 설명한 프로토콜을 준수합니다.