티스토리 뷰

SOLID 중 D(DIP) -> Dependency Inversion priciple.

의존성 주입을 공부하였습니다.

의존성 주입 방법! 의존성 역전이 있고, 의존성을 당겨오는 방식도 있었습니다. 

이를 도와주는 라이브러리는 스위프트에서 Swinject, Pure등이 있었습니다.

 

의존성 주입의 장점!

  1. 유지보수가 좋아진다.
  2. 테스트 하기 좋아진다.

"이런 이유가 있으니 나는 의존성 주입을 공부하는거야~" 라고 생각 했는 데..

??? : 의존성 주입 왜해?

나 : 결합도를 낮추고 응집도를 높여야 되니까!

??? : 왜?

나 : 결합도가 높다면, 한 곳에 변화가 생겼을 때, 해당 부분과 결합도가 높은곳에서 또 수정을 해야 할 수 있어.

??? : 그래? 잘 모르겠는 데? 그게 어떤 경우길래?

나 : ....

??? : 테스트는 어떻게 하기 좋아지는데? 테스트가 좋아지는걸 어떻게 체감하는데?

나 : ....

 

남들이 얘기하는 장점이 아닌 내가 직접 장점을 체감하는 게, 다른 누군가를 설득하거나, 얘기할 때 더 도움이 되겠구나!

또 이거에 대한 장점은 내가 직접 사용해보고 느껴보기 전 까지는 나의 지식이 아닌 느낌이야..

 

1. 유지보수가 어떻게 좋아질까?

아래 예시 코드입니다.

class BookStorage{
    private let bookFactory = BookFactory()
    func readBook(){
        print(bookFactory.makeRandomBook())
    }
}

class BookStorage2{
    private let bookFactory = BookFactory()
    func readBook(){
        print(bookFactory.makeRandomBook())
    }
}

class BookFactory{
    func makeRandomBook() -> Book{
        //some logic
        return Book(page: 100, title: "this is oop", writer: "ebony", publisher: "ebonyBrain")
    }
}
BookStorage().readBook()
BookStorage2().readBook()

책창고(BookStorage)는 BookFactory를 구체타입으로 직접 갖고 있으므로 둘은 매우 의존적인 관계(결합도가 높은 상태)입니다.

BookFactory를 BookStorage 뿐 아닌 BookStorage2에서도 이와 같이 사용중이라 가정하겠습니다.

(BookFactory의 변화) : 여기서 "makeRandomBook() -> Book"코드가 BookFactory에서 사라진다면!?

(위의 단점) : BookFactory의 makeRandomBook메소드를 직접적으로 사용중인 BookStorage, BookStorage2에서 오류가 나게 됩니다.

 

-> 여기서 의존성 주입을 하게 된다면?

 

먼저 BookFactory에 대한 코드입니다.

class BookFactory{
    func makeRandomBook() -> Book{
        //some logic
        return Book(page: 100, title: "this is oop", writer: "ebony", publisher: "ebonyBrain")
    }
}
extension BookFactory: BookMakeable{
    func makeBook() -> Book{
        return makeRandomBook()
    }
}

protocol BookMakeable{
    func makeBook() -> Book
}

위와 같이 BookMakeable이라는 프로토콜을 생성하여 "책을 만드는 동작"을 추상화하였습니다.

 

또 BookStorage들은 의존성을 주입받는 방식으로 코드를 수정하고, BookFactory의 의존성을 줄였습니다.

class BookStorage{
    private let bookFactory: BookMakeable
    init(bookFactory: BookMakeable){
        self.bookFactory = bookFactory
    }
    func readBook(){
        print(bookFactory.makeBook())
    }
}

class BookStorage2{
    private let bookFactory: BookMakeable
    init(bookFactory: BookMakeable){
        self.bookFactory = bookFactory
    }
    func readBook(){
        print(bookFactory.makeBook())
    }
}

bookFacotory의 프로토콜타입을 상위에서 주입받는 형식으로 말이죠.

이렇게 된다면, BookFactory내부에서 어떤 변화가 일어나더라도, 이를 소유하고 있는 곳에서만 수정해주면 끝납니다! ( BookFactory를 구체타입으로 소유하고 있는 곳 )

 

바로 요부분!

BookStorage().readBook()
BookStorage2().readBook()

오류가 나고 있습니다. BookFactory에 대한 주입을 해주지 않고 있어!

let bookFactory = BookFactory()
BookStorage(bookFactory: bookFactory).readBook()
BookStorage2(bookFactory: bookFactory).readBook()

요렇게 수정해주면 해결!

 

이전 : BookFactory의 어떤 기능이 수정되면, 이를 구체타입으로 갖고 사용하는 모든곳에서 코드를 수정해줘야 함

이후 : BookFactory의 어떤 기능이 수정되면, 이를 주입해주는 곳에서만 수정해주면 끝!

 

그럼.. 테스트하기 좋아진다는건 뭔소리야..

테스트에 대한 개념이 아직 익숙치 않아 충분히 공부한 후 테스트편을 포스트하도록 하겠습니다.

(읽어주시고 태클걸어주시면 감사하겠습니다!)

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함