상속 계층에서 Liskov 대체 원칙을 확인하는 방법은 무엇입니까?


14

답변에서 영감을 얻었습니다 .

리스 코프 치환 원칙은 필요 있음

  • 하위 유형에서는 전제 조건을 강화할 수 없습니다.
  • 하위 유형에서는 사후 조건을 약화시킬 수 없습니다.
  • 상위 유형의 변형은 하위 유형으로 유지되어야합니다.
  • 히스토리 제한 사항 ( "히스토리 규칙"). 객체는 그 방법 (캡슐화)을 통해서만 수정 가능한 것으로 간주됩니다. 서브 타입은 수퍼 타입에 존재하지 않는 메소드를 도입 할 수 있기 때문에, 이러한 메소드의 도입은 수퍼 타입에 허용되지 않는 서브 타입의 상태 변경을 허용 할 수 있습니다. 히스토리 제한은이를 금지합니다.

누군가 가이 4 가지 포인트를 위반하는 클래스 계층 구조를 게시하고 그에 따라 해결하는 방법을 바라고있었습니다.
계층 구조에서 4 개 지점 각각을 식별하는 방법과이를 해결하는 가장 좋은 방법에 대한 교육 목적에 대한 자세한 설명을 찾고 있습니다.

참고 :
사람들이 작업 할 수있는 코드 샘플을 게시하고 싶었지만 문제 자체는 잘못된 계층을 식별하는 방법에 관한 것입니다. :)


답변:


17

그 말보다 소리가 정확하고 정확합니다.

상속 계층을 볼 때 기본 클래스의 객체를받는 메소드를 상상해보십시오. 이제이 방법을 편집하는 사람이 해당 클래스에 적합하지 않은 것으로 가정 할 수있는 가정이 있습니까?

예를 들어 ( 원래 밥 삼촌 사이트에서 볼 수 있음 ) :

public class Square : Rectangle
{
    public Square(double width) : base(width, width)
    {
    }

    public override double Width
    {
        set
        {
            base.Width = value;
            base.Height = value;
        }
        get
        {
            return base.Width;
        }
    }

    public override double Height
    {
        set
        {
            base.Width = value;
            base.Height = value;
        }
        get
        {
            return base.Height;
        }
    }
}

충분히 공평 해 보이죠? 나는 Square라는 특수한 종류의 사각형을 만들었습니다. 이는 너비가 항상 높이와 같아야합니다. 사각형은 사각형이므로 OO 원칙에 맞지 않습니까?

그러나 누군가가 지금이 방법을 작성한다면 어떨까요?

public void Enlarge(Rectangle rect, double factor)
{
    rect.Width *= factor;
    rect.Height *= factor;
}

쿨하지 않아. 그러나이 방법의 저자가 잠재적 인 문제가 있음을 알고 있어야 할 이유는 없습니다.

한 클래스에서 다른 클래스를 파생시킬 때마다 기본 클래스와 사람들이 클래스에 대해 가정 할 수있는 사항 (예 : "너비와 높이가 있고 둘 다 독립적 임")에 대해 생각하십시오. 그런 다음 "그러한 가정이 내 서브 클래스에서도 유효합니까?"라고 생각하십시오. 그렇지 않은 경우 디자인을 다시 생각하십시오.


아주 좋고 미묘한 예입니다. +1. 할 수있는 일은 Rectangle 클래스의 메서드를 확대하고 Square 클래스에서 재정의하는 것입니다.
marco-fiset

@ marco-fiset : 정사각형과 직사각형이 분리 된 것을 보았습니다. 하나의 치수 만 사용하지만 정사각형은 IResizable을 구현합니다. Draw 메서드가 있으면 비슷하지만 공통 코드를 포함하는 RectangleDrawer 클래스를 캡슐화하는 것이 좋습니다.
pdr

1
나는 이것이 좋은 예라고 생각하지 않습니다. 문제는 사각형에 너비 나 높이가 없다는 것입니다. 그것은 단지 길이의 측면을 가지고 있습니다. 너비와 높이를 읽을 수만 있으면 문제가 발생하지 않지만이 경우에는 쓰기 가능합니다. 수정 가능한 상태를 도입 할 때는 항상 LSP를 유지 관리하기가 훨씬 더 어렵습니다.
SpaceTrucker

@ pdr 예를 들어 주셔서 감사하지만 Square수업에서 어떤 부분을 위반하는 게시물에서 언급 한 4 가지 조건에 관한 것입니까?
Songo

1
@ Songo : 그것은 역사 제약입니다. 여기에 더 잘 설명되어 있습니다 : blackwasp.co.uk/LSP.aspx "서브 클래스는 서브 클래스의 특성상 수퍼 클래스의 모든 메소드와 속성을 포함합니다. 멤버를 추가 할 수도 있습니다. 히스토리 제약 조건에 따르면 새 멤버수정 된 멤버는 기본 클래스에 의해 허용되지 않는 방식으로 대상물의 상태가 기본 클래스는 고정 된 크기를 갖는 물체를 나타내는 경우. 예를 들어, 서브 클래스는 수정이 크기를 허용해서는 안된다. "
pdr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.