리스코프 치환 원칙(Listkov Substitution Principle)

옹심이·2025년 1월 6일
0
post-thumbnail

파생 클래스는 기본 클래스를 대체할 수 있어야 한다.

  • 로버트 C. 마틴

바바라 리스코프에 의해 고안된 ‘기본 클래스의 계약을 파생 클래스가 제대로 치환할 수 있는지 확인하라’는 원칙이다. 리스코프 원칙을 위배하는 코드로 원칙에 대해 알아볼 것이다.

class Rectangle{
	protected long width;
	protected long height;
	
	public long culculateArea(){
		return width*height;
	}
}

class Square extends Rectangle{
	
	public Square(long length){
		super(length, length);
	}
}

Rectangle rectangle = new Square(10);
rectangle.setHeigth(5);
System.out.println(rectangle.calculateArea());

이 코드의 출력 결과는 50일 것이다. 하지만 정사각형의 높이와 길이가 다를 수 없기 때문에 의도된 결과는 아니다. 이는 대표적인 리스코브 치환 원칙의 위반 사례이며, 이 원칙에 의하면 파생 클래스가 기본 클래스의 모든 동작을 대체할 수 있어야한다. 파생 클래스가 기본 클래스의 모든 동작을 대체 가능한지 파악하기 위해서는 기본 클래스에 할당된 의도가 무엇인지 알아야한다.

기본 클래스는 set을 통해 높이와 길이에 대해 값을 할당하고, 메서드로 넓이를 계산한다. 이 동작대로 우리가 정사각형에게 기대하는 동작을 수행하도록 코드를 변경해보자

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

Setter를 통해 높이와 길이를 변경해도 같은 변의 길이를 가지도록 코드를 만들었다. 하지만 이는 기본 클래스의 의도를 위반하였다. 기본 클래스는 직사각형이기 때문에 높이를 변경 했을 때 길이가 변경되는 것은 의도가 아닐 것이다. 결국 이 코드에서 온전히 리스코프 원칙을 지키기는 어렵다.

기본 클래스의 의도를 파악하기 위해서는 초기 코드 작성자의 의도를 알아야 하는데, 코드만 보고는 의도를 파악하기란 어렵다. 이를 위한 몇 가지 방법이 있다.

  • 작성자에게 물어본다
  • 테스트 코드를 본다(초기 테스트 코드를 작성자의 의도대로 작성해야 한다)

0개의 댓글