본문 바로가기

Design Pattern

SOLID Principles Series 5 : Dependency Inversion (의존성 역전 원칙)

SOLID Principles - Dependency Inversion

의존성 역전(Dependency Inversion) 원칙은 구체적인 개념보다는 추상적인 개념에 의존해야 한다는 원칙입니다. 구체적인 객체는 추상화된 객체(프로토콜)에 의존해야 한다는 의미입니다.

아래의 예시 코드를 살펴보면, EPL 클래스는 Liverpool과 Chelsea에 직접 의존하고 있습니다.

이는 유지보수를 어렵게 만들며, 강등 및 승격 시 매번 코드를 수정해야 하는 문제가 있습니다.

이는 의존성 역전 원칙을 위배하는 것입니다.

class Liverpool {
    func whoAreYou() -> String {
        return "We are Liverpool!"
    }
}

class Chelsea {
    func whoAreYou() -> String {
        return "We are Chelsea!"
    }
}

class EPL {
    let liverpool = Liverpool()
    let chelsea = Chelsea()
    // 추가로 Arsenal, Tottenham 등을 추가하면 EPL은 의존성이 더 커집니다.
    // 유지보수가 어려워지는 문제가 발생합니다.
}
  

의존성 역전 원칙을 준수하기 위해 EnglandTeam이라는 프로토콜을 정의하고, Liverpool과 Chelsea는 이 프로토콜을 채택하여 whoAreYou() 메서드를 구현합니다.

EPL 클래스는 더 이상 Liverpool, Chelsea에 직접 의존하지 않고, EnglandTeam 프로토콜에 의존합니다.

승격, 강등 등의 메서드도 EnglandTeam 프로토콜을 사용하여 처리됩니다.

Before : EPL -> Liverpool, Chelsea ...
After : EPL -> EnglandTeam <- Liverpool, Chelsea.. (의존 관계의 역전)

protocol EnglandTeam {
    func whoAreYou() -> String
}

class Liverpool: EnglandTeam {
    func whoAreYou() -> String {
        return "We are Liverpool!"
    }
}

class Chelsea: EnglandTeam {
    func whoAreYou() -> String {
        return "We are Chelsea!"
    }
}

class EPL {
    var teams: [EnglandTeam] = []
    
    func addTeam(team: EnglandTeam) {
        teams.append(team)
    }
    
    func relegateTeam(relegated: EnglandTeam) {
        for (idx, team) in teams.enumerated() {
            if team.whoAreYou() == relegated.whoAreYou() {
                teams.remove(at: idx)
            }
        }
    }
    
    func whoAreThey() {
        teams.forEach { print($0.whoAreYou()) }
    }
}