제어 역전(Inversion of Control, IoC)
은 소프트웨어 설계에서 사용되는 패턴으로, 프로그램의 제어 흐름을 사용자 정의 코드가 아닌 프레임워크나 라이브러리에 위임하는 것을 말합니다.
- 동일한 비즈니스 로직이나 컴포넌트를 다양한 컨텍스트에서 재사용할 수 있습니다.
- 컴포넌트 간의 느슨한 결합을 통해 코드의 유지보수가 용이해집니다.
- 의존성을 외부에서 주입할 수 있어, 단위 테스트가 더 용이해집니다.
- 새로운 기능이나 컴포넌트를 쉽게 추가할 수 있습니다.
App
의 내부에서 User
를 생성하고 start
메서드를 통해 user
의 add
메서드를 호출하며, 이때 Server
을 무엇을 사용할지를 결정합니다. User
클래스를 확인해보면, Server
클래스를 만들고 User
를 Database
에 저장합니다.// Inversion of Control
class App {
let user = User()
func start() {
user.add()
}
}
class User {
let database = Server1()
var isValid = true
func add() {
if isValid {
database.add(self)
}
}
}
class Server1 {
func add(_ user: User) {
print("Server1")
}
}
let app = App()
app.start()
// Inversion of Control
class App {
let user = User(2)
func start() {
user.add()
}
}
class User {
var database: ServerProtocol!
var isValid = true
init(_ serverType: Int) {
if serverType == 1 {
database = Server1()
} else {
database = Server2()
}
}
func add() {
if isValid {
database.add(self)
}
}
}
protocol ServerProtocol {
func add(_ user: User)
}
class Server1: ServerProtocol {
func add(_ user: User) {
print("Server1")
}
}
class Server2: ServerProtocol {
func add(_ user: User) {
print("Server2")
}
}
let app = App()
app.start()
User
클래스에 진행되고 있다는 것을 확인할 수 있습니다.// Inversion of Control
class App {
let user = User(database: Server1())
func start() {
user.add()
}
}
class User {
var database: ServerProtocol!
var isValid = true
init(database: ServerProtocol) {
self.database = database
}
func add() {
if isValid {
database.add(self)
}
}
}
protocol ServerProtocol {
func add(_ user: User)
}
class Server1: ServerProtocol {
func add(_ user: User) {
print("Server1")
}
}
class Server2: ServerProtocol {
func add(_ user: User) {
print("Server2")
}
}
let app = App()
app.start()
User
클래스는 클래스 내부에서 database
에 대해 설정해줬다면, 해당 부분을 역전시켜서 User
클래스에게 어떤 database
를 사용할것인지 알려주는 방식으로 변경해서 의존성을 역전해줬습니다. User
클래스는 더이상 database
에 대해 생성할 필요가 없어집니다.제가 학습한 내용을 요약하여 정리한 것입니다. 내용에 오류가 있을 수 있으며, 어떠한 피드백도 감사히 받겠습니다.
감사합니다.