Notice
Recent Posts
Recent Comments
Link
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Archives
Today
Total
관리 메뉴

코딩로그

[SOLID] LSP_리스코프 치환 원칙 본문

YJ/관련 이론

[SOLID] LSP_리스코프 치환 원칙

Team DAON 2022. 9. 25. 00:27

[LSP]

  • 리스코프 치환 원칙
  • Liskov Substitution Principle
  • OCP를 가능하게 해주는 원칙
  • 부모 객체와 이를 상속한 자식 객체가 있을 때 부모 객체를 호출하는 동작에서 자식 객체가 부모 객체를 완전히 대체할 수 있어야 함
    • 자식 클래스는 부모 클래스처럼 똑같은 요청에 대해 똑같은 응답을 할 수 있어야 하고, 이때 응답의 타입 또한 같아야 함
    • 자식 클래스에서 overriding 해 부모 클래스에서 구현된 method를 재정의하는 행위 == 부모 클래스의 책임 무시
      • 일관성 위반
  • 자식 클래스는 부모 클래스가 따르던 계약 사항을 따라야 함
    • 선행 조건 == 모듈을 호출하기 위해 참이어야 하는 조건
    • 후행 조건 == 모듈이 동작한 뒤 참이어야 하는 조건
    • 자식 클래스에서 선행 조건은 강화될 수 없다
    • 자식 클래스에서 후행 조건은 약화될 수 없다
    • 자식 클래스에서 부모 클래스의 불변 조건은 반드시 유지되어야 한다
  • 자식 클래스를 구현하는 개발자가 기존 프로그램이 문제없이 안정적으로 작동할 수 있도록 가이드라인을 알려주는 원칙
  • ex) 문서 작성 프로그램 → 구버전에서 작업한 내용, 신버전에서 계속 사용할 수 있어야 함
  • 해결 방법
    • 상속 관계 제거
    • @Override 재정의 X → 많은 고려 필요

[Example]

  • Bad Example
    • Square class가 Rectangle class 대체 불가능
    • 같은 명령에 대해 다른 결과 출력
// LSP Bad Example

// Square class가 Rectangle class 대체 불가능

class Rectangle {
    int width;
    int height;

    public void setHeight(int height) {
        this.height = height;
    }

    public int getHeight() {
        return this.height;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getWidth() {
        return this.width;
    }

    public int area() {
        return this.width * this.height;
    }
}

class Square extends Rectangle {
    @Override
    public void setWidth(int length){
        this.width = length;
        this.height = length;
    }
    
    @Override
    public void setHeight(int length){
        this.width = length;
        this.height = length;
    }
}

public class MyClass {
    public static void main(String args[]) {
        Rectangle rectangle = new Rectangle();
        Square square = new Square();
        
        rectangle.setHeight(3);
        rectangle.setWidth(2);
        
        square.setHeight(3);
        square.setWidth(2);
        
        System.out.println("rectangle area : " + rectangle.area()); // 6
        System.out.println("square area : " + square.area()); // 4
        
    }
}

 

  • Good Example
    • Rectangle과 Square class 사이의 상속 관계 해제 방식 사용
// LSP Good Example

// Rectangle과 Square class 사이의 상속 관계 해제
abstract class Shape{
    abstract int area();
}

class Rectangle extends Shape{
    int width;
    int height;

    public void setHeight(int height) {
        this.height = height;
    }

    public int getHeight() {
        return this.height;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getWidth() {
        return this.width;
    }

    public int area() {
        return this.width * this.height;
    }
}

class Square extends Shape {
    int length;

    public void setLength(int length) {
        this.length = length;
    }

    public int getLength() {
        return this.length;
    }

    public int area() {
        return this.length * this.length;
    }
}

public class MyClass {
    public static void main(String args[]) {
        Rectangle rectangle = new Rectangle();
        Square square = new Square();
        
        rectangle.setHeight(3);
        rectangle.setWidth(2);
        
        square.setLength(3);
        
        System.out.println("rectangle area : " + rectangle.area()); // 6
        System.out.println("square area : " + square.area()); // 9
        
    }
}

 

'YJ > 관련 이론' 카테고리의 다른 글

[SOLID] DIP_의존 역전 원칙  (0) 2022.09.25
[SOLID] ISP_인터페이스 분리 원칙  (0) 2022.09.25
[SOLID] OCP_개방 폐쇄 원칙  (0) 2022.09.24
[SOLID] SRP_단일 책임 원칙  (0) 2022.09.24