객체지향 (OOP)/객체 지향 설계 5원칙

[LSP] 객체지향 설계 5 원칙 (3)

고인돌개발자 2021. 5. 15. 23:54

학습목표 : 리스코프 치환 원칙 (Liskov substitution principle)을 이해하고, 예제로 설명할 수 있다.

LSP[Liskov substitution principle] 리스코프 치환 원칙

  - "서브 타입은 언제나 자신의 기반 타입(base type)으로 교체할 수 있어야 한다." - 로버트 C. 마틴

  - 하위 클래스 is a kind of 상위 클래스 - 하위 분류는 상위 분류의 한 종류다.

  - 구현 클래스 is able to 인터페이스 - 구현 분류는 인터페이스할 수 있어야 한다.

 

바바라 리스코프

컴퓨터 프로그램에서 자료형 S가 자료형 T의 하위형이라면 필요한 프로그램의 속성(정확성, 수행하는 업무 등)의 변경 없이 자료형 T의 객체를 자료형 S의 객체로 교체(치환)할 수 있어야 한다

 

예를들어 설명하기 - 고전적인 사각형 과 정사각형의 예시

   정사각형을 사각형의 하위 클래스로 정의했을 경우, 정사각형의 면적을 구하는 계산식은
  상위 클래스 사각형의 면적을 구하는 계산식으로 교체가 불가한 경우가 발생한다.

그림으로 이해해보기

<사각형과 정사각형>

코드로 이해해보기 - 사각형은 정사각형의 객체로 대체할 수 없다.
package book.oopforsprings.lec05.solid;

public class LSP_Rectagle {
	
	public static void main(String[] args) {
		
		
		Rectangle_사각형 r = new Rectangle_사각형();
		r.setHeight(5);
		r.setWidth(4);
		System.out.printf("this Size is %d \n",r.area());
		
		Square_정사각형 s = new Square_정사각형();
		s.setHeight(5);
		s.setWidth(4);
		System.out.printf("this Size is %d \n",s.area());
		
		// 자료형 T(Rectangle_직사각형) 의 객체를 자료형 S(Square_정사각형)의 객체로 교체할 수 있어야 한다.
		// 아래는 계산식의 오류가 발생하는 잘못된 다형성을 가지고 있음.
		// 상위 클래스 사각형의 객체를 정사각형의 객체로 교체 시 오류가 발생하게 된다.
		// 사각형의 클래스에서는 아래의 결과값이 20이 되어야 한다.
		Rectangle_사각형 rs = new Square_정사각형();
		rs.setHeight(5);
		rs.setWidth(4);
		System.out.printf("this Size is %d \n",rs.area());
		
	}

}

// 자료형 T
class Rectangle_사각형 {
    public int width;
    public 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;
    }
}

// 자료형 S
class Square_정사각형 extends Rectangle_사각형 {
	
    @Override
    public void setHeight(int value) {
        this.width = value;
        this.height = value;
    }

    @Override
    public void setWidth(int value) {
        this.width = value;
        this.height = value;
    }
}

 

맺음말 

사실 , 이번 리스코프 치환 원칙은 대략 개념은 알겠는데 설명하기가 좀 어려운것 같다.

한가지 확실한것은 역시 객체 생성시 클래스는 추상적인 개념으로 생성되어야 한다는 것이다.

그 추상적인 부분이 실체적으로 잘 구현되도록 하는게 중요하다.

 

LSP 위반이 발생되면 OCP 원칙이 지켜지지 않는다.

  - 리스코프원칙이 무너져서, 상위 클래스의 속성에 변화가 발생하게 되면,
    해당 클래스의 개방/폐쇄의 원칙 또한 위반하게 된다. (내가 써놓고도 무슨 말인지 애매하긴 함)