상세 컨텐츠

본문 제목

[Swift] Dependency Injection 의존성 주입 비유로 쉽게 이해하기

Swift

by Mr.Garlic 2022. 5. 11. 03:19

본문

안녕하세요...

2시간 가까이 공들여 쓴 글이 날아가서... 

너무 속이 상하네요...

그런데 다시한번 잘 써볼게요 

 

의존성 주입! 오늘 면접에서 질문을 받았는데 잘 답을 하지 못했어요!

그래서 저도 공부하게 되었는데, 원리가 엄청 괴랄하게 어려운게 아닌데도

예시라던가 설명이 너무... 책처럼 되어있어서 저는 정말 정말 쉽게 설명을 해봤어요.

깊이있는 설명이라기 보다는 원리를 빠르게 감 잡고 해보고 싶으신 분들께 적합할 것 같아요!

 

 

시간을 돌리고싶군! 하지만 그럴 수 없군!

 

Dependency 의존성 이란?

친구가 

"야, 너 뭐먹을래? 니 의견을 말해줘"

라고 했는데

제가 남자친구의 의견만 전적으로 따르는 의존적인 친구라면...

 

네 의견 말해줘 -> 내 선택은 남친에게 맡길게 -> 남친 왈 : 음식은 고기가 짱이야 -> 그 의견에 의존하는 나도 고기라고 말함ㅠㅠ

 

저는 실제로 그런 사람은 아니지만 그런 상황을 코드로 한번 표현해봤어요.

class Boyfriend {
	var food: String = "meat"
}

class Me {
	var myChoice = Boyfriend()
}

let myIdea = Me()

print(myIdea.myChoice.food) // "meat"

남친이 항상 고기만 먹는다면 평생 괜찮을지도 몰라요... 

근데 갑자기 남친이 홍어애 라던가 수르스트뢰밍 같이 내가 도저히 먹을 수 없는 음식으로 food 프로퍼티를 바꿔버리면...

그때도 친구가 물어볼 때 내 의사와 상관없이 홍어애 먹겠다고 할 순 없잖아요..?

남자친구 클래스에 의존해 있다면 그로인해 나 클래스가 의도치 않은 상황을 만나게 됩니다. 이것을 의존성이라고 해요.

무조건 나쁘다기 보다 이런 부작용이 있을 수 있다는 거죠.

 

의존성 주입은 이런 의존성을 만들어주는 건데!

뭔가 장점이 있으니까 의존성을 만들어주는 거겠죠? 그럼 의존성 주입의 사례를 아래에서 보시죠!

 

 

의존성 주입이란?

바로 예를 들어서 설명해볼게요! 

//우리엄마 클래스랑 너희엄마 클래스 이렇게 두개를 정의했어요.

class MyMother {
	var name: String = "Lisa"
}

class YourMother {
	var name: String = "Mia"
}

//그리고 Child라는 클래스는 내부에 Mother 클래스를 상속받은 mother이라는 프로퍼티를 가지고 있어요.
//처음 클래스를 정의해 줄 때, 아래처럼 썼다고 할께요.

class Son {
	var mother: MyMother = MyMother()
    
    func callMother(){
    	print(self.mother.name)
    }
}

class Daughter {
	var mother: MyMother = MyMother()
    
    func callMother(){
    	print(self.mother.name)
    }
}

//이렇게 클래스를 만들어서 신나게 인스턴스 막 만들어서 쓰고 있었어요. 아래처럼!
var mySon = Son()
var myDaughter = Daughter()

 

이렇게 만들어 뒀는데... 만약에 우리 엄마를 너희 엄마로 바꿔야 하면!!! ㄷㄷ

 

클래스 하나하나 들어가서 MyMother을 Your Mother로 바꿔줘야 되겠죠?
노가다 ㄷㄷ 벌써부터 피곤하네요.

노가다를 안하려면 필요한 게 의존성 주입이예요. 


그냥 처음부터 Mother 클래스 하나만 만들어놓고
Son, Daughter 둘다 Mother 만 가져다 썼으면 애초에
Son과 Daughter가 Mother 에게 의존하니까 Mother만 고치면 되는거였잖아요?


이 경우는 '의존성이 필요한 상황' 그러니까 '의존성의 장점' 이 필요한 상황이 되겠죠
이렇게 여러 클래스들을 관리해야 하는 입장에서 하나만 관리하면 나머지가 알아서 따라오도록
의존관계를 만들어두는 것 자체를 의존성 주입이라고 보면 돼요.

 

헉헉 장황하긴 한데 정말 정말 초보자의 입장에서는 이렇게 생각의 고리가 좀 필요한 것 같아서 길게 써봤어요.

그리고 요즘 많이 쓰이는 프로그래밍 스타일은 아래의 의존관계 역전법칙을 오히려 잘 아는것이 중요해요! 

어떻게 보면 이걸 이해하기 위해 의존성 주입이라는 개념을 공부한거나 마찬가지예요! 

 

의존 관계 역전 법칙

위에서 설명한 의존성 주입은 기존에 많이 사용하던 전통적인 의존 방식이었어요.

자식이 엄마를 바라보는... 집사가 고양이를 바라보는... 그런 방식...

 

그런데! 객체지향 프로그래밍(OOP)의 원칙에 대해서 포스팅할때 정리를 할 예정이지만

OOP의 원칙중 하나가 의존 관계 역전 원칙이라고 해요. 하... 음... 이 원칙을 또 파고들고 어쩌고 저쩌고 하는 것은

오늘 포스팅에서 중요한 부분은 아닙니다. 다만 요즘 사람들은 그럼 의존관계를 어떻게 똑똑하게 만들어 쓰고 있느냐가 더 중요한거죠.

그쵸?? 아니면 댓글로 피드백 주십시오! 

 

요즘 서타일의 의존 방식은 이래요.

Swift에서는 프로토콜이라고 하고, 다른 언어에서는 컨테이너나 인터페이스 등등 다양한 용어를 쓰는 것 같은데

우리가 흔히 '청사진'의 역할을 한다고 하는 프로토콜을 활용해서 

청사진을 받아다 쓰는 의존 관계만 만드는 거예요.

 

//동물이라는 프로토콜을 만들어 줘요.

protocol Animal {
	var name: String
    var sound: String
}

//우리가 의존 관계 역전 법칙을 몰랐다며는 아마 Mammal(포유류)가 더 큰 개념이니까 
//아래의 Dog 클래스랑 Mammal 클래스만 의존관계를 만들어서 관리를 했을텐데
// 우리는 이제 의존관계 역전을 써볼거니까 
// 둘 다 의존할 수 있는 Animal 프로토콜을 써줄거예요. 

// 포유류 클래스를 정의할 때도 Animal 프로토콜을 따르게 만들어주고

class Mammal: Animal {
	var mamName = "Mammal"
    var mamSound = "woofwoof"

}

// Dog 클래스를 정의할 때도 초기화 할 당시에 꼭 Mammal(포유류)가 아니라
// Animal 프로토콜을 준수하고 있는 어떠한 타입이라도 받을 수 있게 만들어 두면
// Dog도 굳이 Mammal에 의존해 있지 않아도 되는 상태가 됩니다.

class Dog {
	var species: Animal
    init(species: Animal) {
    	self.species = species
    }
}

// 이런 상황을 의존 관게 역전이 된 상황이라고들 하고
// 코드를 잘 정리하시는 분들을 보면 이렇게 의존관계를 잘 나눠두는 것을 잘하시더라고요!

 

하, 같은걸 두 번 쓰느라 사실 더 자세히 쓸 수 있는것도 조금 축약해서 쓴 면이 없지않아 있는데요

그래도 너무너무 어려운 말로 눈알이 핑핑 돌고 계신분들께는 조금이나마 도움이 되었기를 바라면서

오늘 포스팅 마치겠습니다! 

 

혹시 오류가 있거나 궁금한 점이 있으시면 댓글을 남겨주세요~!!

감사합니다

 

관련글 더보기