[SOLID] LSP

miori·2022년 11월 6일
0

OOP

목록 보기
3/5
post-thumbnail

LSP (Liskov Substitution)

좋은 설계란 기본적으로 시스템에 새로운 요구사항이나 변경이 있을 때 가능한 한 영향 받는 부분을 최소화한 설계이다.
  • 리스코프 치환 원칙
  • 하위 타입의 객체는 상위 타입 객체에서 가능한 기능을 수행할수 있어야 한다.
  • OOP 에서 하나의 메서드나 클래스가 다양한 방법으로 동작하는 다형성 구현을 도와준다.
  • 또한, OCP (개방 폐쇄원칙)를 서포트 해준다.

LSP 위배 문제

가장 대표적인 예제로는 직사각형 정사각형 문제가 있다.
IS-A 관계를 따져보았을때, 정사각형은 직사각형이지만 직사각형은 정사각형이 아니다.

//MARK: LSP 위배
/*
 리스코프 위배
 부모타입인 Rectangle에서 자식인 Square로 변경시 너비 구하는 식 달라짐
 정사각형은 직사각형이다.
 직사각형은 정사각형이 아니다.
 */
class Rectangle {
    let width: Int
    let height: Int
    
    func area() -> Int {
        return width * height
    }
    
    init(width: Int, height: Int) {
        self.width = width
        self.height = height
    }
    
}

class Square: Rectangle {
    override func area() -> Int {
        return width * width
    }
}

let r = Rectangle(width: 5, height: 4) //20
r.area()

let r2 = Square(width: 5, height: 4) //25
r2.area()
//: [Next](@next)
//만약 부모클래스 기능을 재정의 하게 되면 OCP 위배될수도

해결

//MARK: LSP
protocol Shape {
    func area() -> Int
}

class LSPRectangle: Shape {
    private let width: Int
    private let height: Int
    
    func area() -> Int {
        return width * height
    }
    
    init(width: Int, height: Int) {
        self.width = width
        self.height = height
    }
}

class LSPSquare: Shape {
    private let width: Int
    
    func area() -> Int {
        return width * width
    }
    
    init(width: Int) {
        self.width = width
    }
}

위의 코드와 가이 Shpae protocol을 통해 area를 구하는 함수를 정의해줄 수 있다.
이렇게 LSP를 준수하면 추상화 된 것으로부터 상속된 다른 클래스를 공통적으로 작성해 줄 수 있다.
이렇게 되면 OCP도 자연스럽게 지켜줄수 있다.

profile
iS를 공부하는 miori 입니다.

0개의 댓글

관련 채용 정보