클린코드

LSP: 리스코프 치환 원칙

RE.YEOL 2023. 4. 15. 10:00
Single Responsibility principle : 단일 책임 원칙
Open Close Principle : 개방 폐쇄 원칙
Liscov Substitution Principle : 리스코프 치환 원칙
Interface Sergregation Principle: 인터페이스 분리 원칙
Dependency Inversion Principle : 의존성 역전 원칙

좋은 객체 지향 설계의 5가지 원칙 중 리스코프 치환 원칙(LSP)에 대해 알아보겠습니다.

 


Liskov Substitution Principle : 리스코프 치환 원칙
프로그램의 객체는 프로그램의 정확성을 깨트리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.

가장 많은 예시인 직사각형과 정사각형 관계가 있습니다.

 

public class Rectangle
{
    private int width;
    private int height;
    
    // 너비 반환
    public int getWidth()
    {
        return width;
    }
    
    // 높이 반환
    public int getHeight()
    {
        return height;
    }
    
    // 너비 할당
    public void setWidth(int width)
    {
        this.width = width;
    }
    
    // 높이 할당
    public void setHeight(int height)
    {
        this.height = height;
    }
    
    // 넓이 반환
    public int getArea()
    {
        return width * height;
    }

}

Rectangle은 직사각형을 구현한 클래스입니다.

정사각형, 직사각형 모두 사각형이므로 직사각형을 상속받아 정사각형을 구현해 보겠습니다.

public class Square extends Rectangle{
    
    @Override
    public void setWidth(int Width) {
        super.setWidth(width);
        super.setHeight(getWidth());
    }
    
    @Override
    public void setHeight(int height) {
        super.setHeight(height);
        super.setWidth(getHeight());
    }
    
}

이렇게 정사각형과, 직사각형을 구현한 클래스의 결과를 해보겠습니다.

 

public class Main {

    public static void main(String[] args) {

        Rectangle rectangle = new Rectangle();
        rectangle.setWidth(10);
        rectangle.setHeight(5);

        System.out.println(rectangle.getArea());

    }

}
결과 : 50

Rectangle 클래스는 직사각형 공식인 넓이 계산 공식 10(가로) x 5(세로)의 결과가 정상적으로 나왔습니다.

 

public class Main {
    public static void main(String[] args) {

        Rectangle square = new Square();
        
        square.setWidth(10);
        square.setHeight(5);

        System.out.println(square.getArea());
        
    }
    
}
결과 : 25

Square 클래스는 넓이 계산 공식 10(가로) x 5(세로)의 결과 50이 아닌 25가 나왔습니다.

 

위의 코드를 확인해보니 Square에서 height 값을 width에 넣어 주고 있기 때문에 5 x 5가 나오게 되었습니다.

우선 수학적으로 접근하면 정사각형은 가로 세로 길이가 같아야 합니다.

개발적으로 접근한다고 하면, Square 클래스는 가로 세로를 set 할 수 있도록 구성되어 있기 때문에 개발자의 실수가 발생되었습니다.

즉,  리스코프 치환 원칙을 위배한 상황입니다.

public class Shape {

    public int width;
    public int height;

    // 너비 반환
    public int getWidth() {
        return width;
    }
    // 너비 할당
    public void setWidth(int width) {
        this.width = width;
    }

    // 높이 반환
    public int getHeight() {
        return height;
    }
    // 높이 할당
    public void setHeight(int height) {
        this.height = height;
    }

    // 사각형 넓이 반환
    public int getArea() {
        return width * height;
    }
}
//직사각형 클래스
public class Rectangle extends Shape {

    public Rectangle(int width, int height) {
        setWidth(width);
        setHeight(height);
    }

}

//정사각형 클래스
public class Square extends Shape{
    
    public Square(int length) {
        setWidth(length);
        setHeight(length);
    }
    
}

이렇게 코드를 수정하여 리스코프 치환 원칙을 준수하게 되었습니다.