[SOLID] OCP

miori·2022년 11월 6일
0

OOP

목록 보기
2/5
post-thumbnail

OCP (Open-Closed)

좋은 설계란 기본적으로 시스템에 새로운 요구사항이나 변경이 있을 때 가능한 한 영향 받는 부분을 최소화한 설계이다.
  • 개방 폐쇄 원칙
  • 확장에는 열려있고 변경에는 닫혀있어야한다.
    즉, 쉽게 확장이 되어야하고, 확장시 기존 코드의 수정은 하지 않는 방향으로 설계해야한다.
    더쉽게 말하자면, 기존 코드의 변경 없이 기능을 추가/수정할 수 있도록 설계해야한다.

OCP 위배 코드

//MARK: enum
/*
 만약, 더블치즈 버거를 추가하고 싶다면?
 */
enum Hamburger {
    case cheese
    case avocado
    case doubleCheese
}

class OrderHamburger {
    let hamburger: Hamburger
    init(hamburger: Hamburger) {
        self.hamburger = hamburger
    }
    
    func order() {
        switch hamburger {
        case .cheese:
            print("치즈버거 주세요")
        case .avocado:
            print("아보카도버거 주세요")
        }
    }
}

먼저 enum 으로 설계를 한 코드이다.
enum도 구체적인 햄버거 종류를 case 로 설정을 해줄수 있다.
하지만 만약 doubleCheese 처럼 햄버거 종류가 추가된다면 어떻게 될까?

위와 같은 오류를 만나게 된다😁
enum으로 구현한 case를 구현해줘야하기 때문이다.
추가를 하게 되면, order 메서드에 case 를 추가하면서 기존 코드를 수정하게 된다.

이러면에서 유연성이 낮은 것을 알수 있다.

해결

추상화와 상속을 통해 해결할 수 있다.
swift 에서는 protocol을 사용할 수 있다.

OCP 지킨 코드

//MARK: OCP ; Protocol 활용하여 확장은 쉽게 (확장은 열려있고), 그리고 확장시 기존 코드 수정하지 않게끔 (변경은 닫혀있고)
/*
 - 추상화와 상속 통해 구현 가능
 - 유연함 증가
 */
protocol HamburgerProtocol {
    func order()
}

struct Cheese: HamburgerProtocol {
    func order() {
        print("치즈버거 나왔어요")
    }
}

struct Avocado: HamburgerProtocol {
    func order() {
        print("아보카도버거 나왔어요")
    }
}

//더블치즈 추가하면?
struct DoubleCheese: HamburgerProtocol {
    func order() {
        print("더블치즈버거 나왔어요")
    }
}

class OrderHamburger2 {
    let hamburger: HamburgerProtocol
    init(hamburger: HamburgerProtocol) {
        self.hamburger = hamburger
    }
    func orderHamburger() {
        hamburger.order()
    }
}

OrderHamburger2(hamburger: DoubleCheese()).orderHamburger() //더블치즈버거 나왔어요

OCP를 적용하기 위해 HamburgerProtocol를 프로토콜로 둠으로써, 햄버거 종류가 많아진다해도 생긴다고 해도 HamburgerProtocol를 채택하기만 하면 OrderHamburger2 클래스에서는 변경해야할 코드가 없다.
즉, 결합도가 낮아져 유지보수가 쉬워졌다.

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

0개의 댓글