Joonas' Note
Joonas' Note
SOLID 원칙 - Liskov Substitution principle (LSP; 리스코프 치환 원칙) 본문
정의
Liskov Substitution principle (LSP; 리스코프 치환 원칙)
프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
어떤 모듈 S가 모듈 T의 하위 모듈이라면, 속성의 변경없이 T를 S(상위)로 교체할 수 있어야 한다고 한다. 즉, 부모 클래스와 자식 클래스가 일관되어야 한다는 뜻이다.
위반 사례
이를 위반하는 대표적인 사례로는 원-타원 문제 (또는 사각형-정사각형 문제)가 있다.
class Rectangle {
private int width;
private int height;
public void setWidth(int width){
this.width = width;
}
public void setHeight(int height){
this.height = height;
}
public int getArea() {
return this.width * this.height;
}
}
// Test
public void testArea(Rectangle rect) {
rect.setWidth(5);
rect.setHeight(4);
System.out.println("area = " + rect.getArea()); // it must be 20.
}
사각형을 표현하는 Rectangle 라는 클래스가 있다. 그리고 두 사각형의 넓이를 구하는 테스트 함수 testArea()가 있다.
그리고 하위 클래스로 정사각형을 표현하는 Square 라는 클래스를 만들었다.
class Square extends Rectangle {
}
public void main(String[] args) {
testArea(new Rectangle());
testArea(new Square());
}
그런데 뭔가 이상하다. 두 사각형의 넓이가 모두 20이 나온다.
정사각형의 너비(width)와 높이(height)가 다르게 설정되어서이다. 그럼 정사각형이 아니지 않은가.
그럼 Square 클래스를 이렇게 수정해보자.
class Square extends Rectangle {
@Override
public void setWidth(int width) {
super.setWidth(width);
super.setHeight(width);
}
@Override
public void setHeight(int height) {
super.setWidth(height);
super.setHeight(height);
}
}
이제 정사각형의 너비나 넓이 중 무엇을 설정하여도, 두 값을 변경하여 정사각형으로 만들고 있다.
... 그런데 이럴거면 Rectangle 클래스를 왜 상속한거지?
정사각형에게 "너비 설정"과 "높이 설정"이 굳이 따로 있을 이유가 없다. 오히려 혼란스럽다.
즉, 동작에 있어서 상위 클래스인 Rectangle 과 Square 는 서로 일관되게 행동하지 않는다.
해결
위의 두 사각형 클래스는 포함 관계를 가지지 않으므로, 부모-자식이 아닌 형제(sibling)관계로 만들어 해결할 수 있다.
상위에 Shape 라는 클래스를 두어 형제 관계로 만들 수도 있다.
참고
'개발' 카테고리의 다른 글
SOLID 원칙 - Dependency Inversion Principle (DIP; 의존관계 역전 원칙) (0) | 2023.05.16 |
---|---|
SOLID 원칙 - Interface Segregation Principle (ISP; 인터페이스 분리 원칙) (0) | 2023.05.16 |
SOLID 원칙 - Open/Closed Principle (OCP; 개방-폐쇄 원칙) (0) | 2023.05.16 |
SOLID 원칙 - Single Responsibility Principle (SRP; 단일 책임 원칙) (0) | 2023.05.16 |
Android Studio 깨끗하게 정리하기 (0) | 2023.01.29 |
Comments