Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REFACTOR] Factory Pattern도입(#149) #150

Merged
merged 3 commits into from
Oct 16, 2023

Conversation

kimscastle
Copy link
Contributor

@kimscastle kimscastle commented Oct 15, 2023

[#149] REFACTOR : Factory Pattern도입

🌱 작업한 내용

  • Coordinator pattern을 도입한 후 객체 생성에 대한 고민을 팀 내부에서 진행해왔습니다

  • DI적용으로 인한 객체생성의 불편함을 해결하기 위해서 Custom DI Container, Swinject, Factory Pattern중에 한가지 방식을 채택하기 위한 고민을 했고 결론적으로는 객체생성의 역할 factory에게 위임해주는 Factory pattern을 도입하기로 결정했습니다

  • coordinator pattern은 화면전환로직을 담당해주는 객체이기에 객체생성은 책임에서 벗어난 역할이라고 생각했습니다

  • [REFACTOR]전체 DI적용(#131) #132 이 pr에서 각 방식에 관한 의견을 남겨놨습니다

🌱 PR Point

Factory Pattern의 방법에 대한 고민

방법 1. 간단한 팩토리

image

protocol AuthFactory: AnyObject {
    func makeLoginVC() -> LoginViewController
    func makeRegisterVC() -> RegisterViewController
}

final class AuthFactoryImpl: AuthFactory {  
    func makeLoginVC() -> LoginViewController {
        let loginVC = LoginViewController()
        return loginVC
    }
}

실제 객체 타입을 return하게끔 하는 제일 간단한 형태의 Factory입니다.
하지만 이렇게 구현했을 때 AuthFactory에서의 return값이 concrete type이기 때문에 해당 Factory를 주입받는 Coordinator가 실제 객체를 바라보게 되고 해당 객체에 매우 의존적이게 됩니다.

따라서 ViewControllerable과 같은 interface를 바라보게 함으로써 DIP를 시켜줘야할 필요가 있습니다. 또한 이렇게 구현함으로써 온전한 캡슐화를 할 수 있습니다.

방법 2. 팩토리 메서드 패턴

image

두번째 방법인 팩토리 메서드 패턴입니다.

protocol Factory {
    func makeViewController() -> ViewControllerable
}

final class AuthFactoryImpl: Factory {
    func makeViewController() -> ViewControllerable {}
}

final class OnboardingFactoryImpl: Factory {
    func makeViewController() -> ViewControllerable {}
}

ViewController에서는 Factory 프로토콜 타입의 객체를 주입받고. 어떤 객체를 주입받느냐에 따라 생성되는 ViewController가 달라지는 매우 유연한 방법입니다.
하지만 이렇게 했을 때 아래와 같은 문제점들이 있었습니다.

문제점 1.

한 Coordinator에서 필요한 여러개의 VC를 만들기 위한 Factory protocol을 구성하기가 까다롭습니다.
(어떤 Coordinator는 단 하나의 객체만 만들면 되지만 어떤 Coordinator는 2~3개의 객체를 생성해야합니다.)

문제점 2.

Coordinator에서 바라보고 있는 타입이 ViewControllerable 프로토콜이기 때문에 기존의 ViewController에서 config를 해주고 싶을 때에 프로토콜에는 해당 값이 없기 때문에 문제가 있었습니다.

따라서 위 문제점들을 해결하기 위해 각각의 ViewController에 필요한 데이터와 coordinator를 추상화한 interface를 1:1로 가지고 있게 만들어 위의 구조를 유지한채 문제를 해결했습니다.
image

현재 LionHeart의 Factory pattern 구조

  1. viewcontroller는 각각의 unique한 viewcontrollerable을 가지고 있고 해당interface는 coordinator(각각의 navigation interface type)와 데이터전달이 필요한 경우엔 해당 데이터를 추상화하고 있습니다
protocol BookmarkViewControllerable where Self: UIViewController {
    var coordinator: BookmarkNavigation? { get set }
}
  1. 각각의 coordinator는 unique한 factory interface를 가지고 있고 각각 필요한 viewcontrollerable타입을 return해줍니다
    • coordinator의 init에 factory의 구현체를 외부 주입해줍니다
protocol BookmarkFactory {
    func makeBookmarkViewController() -> BookmarkViewControllerable
}
  1. 구현체(impl)는 저장속성이 없고 메서드만 호출하면되기때문에 struct로 구현햇습니다
struct BookmarkFactoryImpl: BookmarkFactory {
    func makeBookmarkViewController() -> BookmarkViewControllerable {
        return BookmarkViewController(manager: BookmarkMangerImpl(bookmarkService: BookmarkServiceImpl(apiService: APIService())))
    }
}

✨실제 factory pattern 적용 pull request

의성(아티클카테고리, 챌린지, 북마크)

민재(커리큘럼, 마이메이지, 아티클상세)

찬미(인증, 스플래시, 오늘의아티클)

📮 관련 이슈

@kimscastle kimscastle added 🦁민재 민재's 🦁의성 의성's 🦁찬미 찬미's ✨Feat 새로운 기능 구현 ♻️Refactoring 리펙터링 labels Oct 15, 2023
@kimscastle kimscastle added this to the 🦁1차 Refactor🦁 milestone Oct 15, 2023
@ffalswo2
Copy link
Contributor

ffalswo2 commented Oct 16, 2023

Factory Pattern의 방법에 대한 고민 내용 추가 완.

@cchanmi
Copy link
Member

cchanmi commented Oct 16, 2023

고생하셧숩니다

@kimscastle kimscastle merged commit 0959b31 into main Oct 16, 2023
@kimscastle kimscastle deleted the refactor/#149-factorypatter-foldering branch October 17, 2023 01:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨Feat 새로운 기능 구현 ♻️Refactoring 리펙터링 🦁민재 민재's 🦁의성 의성's 🦁찬미 찬미's
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[REFACTOR] Factory Pattern도입
3 participants