본문 바로가기

Design Pattern

SOLID Principles Series 2 : Open-Closed (개방 폐쇄 원칙)

 

 

SOLID Principles - Open-Closed

소프트웨어 개발에서 SOLID 원칙 중 두 번째인 Open-Closed(개방 폐쇄) 원칙은 코드는 확장에는 열려있고 수정에는 닫혀있어야 한다는 원칙입니다.

이는 새로운 기능이 추가되거나 변경이 필요할 때 코드를 수정하지 않고 확장할 수 있어야 한다는 의미입니다.

아래의 예시 코드를 살펴보면, EPL 클래스는 팀 이름을 가지고 있는 클래스입니다. whoAreYou 함수는 EPL 인스턴스의 팀에 따라 다른 출력을 하도록 구현되어 있습니다.

그러나 새로운 팀(Tottenham, Arsenal)을 추가하려면 whoAreYou 함수를 수정해야 하는 문제가 발생합니다. 이는 Open-Closed 원칙을 위반하는 것입니다.


class EPL {
    let team: String

    init(team: String){
        self.team = team
    }
}

func whoAreYou(epl: EPL){
    if epl.team == "Liverpool"{
        print("Reds!")
    } else if epl.team == "Chelsea" {
        print("Blues!")
    } else {
        print("I don't know")
    }
}

let liverpool = EPL(team: "Liverpool")
let chelsea = EPL(team: "Chelsea")

whoAreYou(epl: liverpool) // Reds!
whoAreYou(epl: chelsea) // Blues!

// 만약 Tottenham과 Arsenal을 추가하면 whoAreYou 함수를 수정해야 한다. (open-closed 원칙 위배)
  

이를 해결하기 위해 인터페이스를 사용하여 코드를 확장 가능하고 수정이 필요 없도록 만들 수 있습니다.

예시에서는 EPL 프로토콜을 정의하고, 각 팀별로 해당 프로토콜을 채택하여 scream() 메서드를 구현하였습니다.

whoAreYou 함수는 EPL 인스턴스를 인자로 받아서 scream() 메서드를 호출하도록 변경되었습니다.

이렇게 하면 새로운 팀을 추가할 때는 수정 없이 확장만으로 처리할 수 있게 됩니다.


protocol EPL {
    func scream()
}

class Liverpool: EPL {
    func scream() {
        print("Reds!")
    }
}

class Chelsea: EPL {
    func scream() {
        print("Blue!")
    }
}

func whoAreYou(team: EPL) {
    team.scream()
}

let liverpool = Liverpool()
let chelsea = Chelsea()

whoAreYou(team: liverpool) // Reds!
whoAreYou(team: chelsea) // Blue!

// Tottenham과 Arsenal을 추가한다면?
class Tottenham: EPL {
    func scream() {
        print("꼬끼오~!")
    }
}

class Arsenal: EPL {
    func scream() {
        print("444444!")
    }
}

let tottenham = Tottenham()
let arsenal = Arsenal()

// 코드의 수정(modification)은 없고 확장(추가, extension)만 필요하다. Open-Closed 원칙 준수
whoAreYou(team: tottenham) // 꼬끼오~!
whoAreYou(team: arsenal) // 444444!