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

[7차 세미나] 리펙토링 #8

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

[7차 세미나] 리펙토링 #8

wants to merge 10 commits into from

Conversation

kim-seonwoo
Copy link
Collaborator

@kim-seonwoo kim-seonwoo commented Jun 7, 2024

👾 작업 내용

  • MVC 패턴을 적용하니까 ViewController에 많은 코드가 작성되어 있었고 부담이 되었어요!
  • 또 많은 기능과 함수가 들어가다보니까 어떤 파일에서 어떤 기능 까지 담당하는지 찾기가 힘들었어요
  • MVVM 을 도입하여 해결하고자 했습니다!
  • 또한 의존 관계가 복잡한 부분들을 클린 아키텍처 구조를 가져와 보기로 했습니다!
  • Main 관련 화면 한에서 구현해봤어요!

Domain

  • Entities: Content와 ContentDetail이 주 기능이어서 여기에 대한 구조체를 만들어 줬어요!
    → 프로젝트가 무엇으로 바뀌든, 이 부분이 존재함은 절대 변함이 없기 때문에 이렇게 정의 했어요!
  • UseCases: Content 관련한 부분에서 주요한 ContentData와 DetailData를 가져오는 동작에 대한 정의를 해주었어요! 또한 repository 프로토콜로 호출을 정의해주어요!
  • Repository Interface:
    Domain은 Data 영역에 의존관계를 가지면 안됩니다.
    Repository에 대한의존을 가지면 안됩니다!
    따라서 protocol로 선언하여 의존성을 역전시켜줍니다.
protocol ContentRepository {
    func getMovieInfo(completion: @escaping (Result<[Content], Error>) -> Void)
    func getDetailInfo(code: String, completion: @escaping (Result<ContentDetail, Error>) -> Void)
}

Data

  • DataSource: API 통신에 대한 동작을 정의하였습니다. 또한 DTO로 받아온 데이터를 Entity로 변환하는 역할을 추가하였습니다.
  • Repository: 데이터계층에서 통신과 관련된 동작을 정의하였어요.

Presentation

  • ViewModel: UseCase를 의존하여 UseCase의 동작들을 정의 하였어요.
  • ViewController: ViewModel에 대한 Observe 변수의 변화와 fetchData함수들의 선언으로 ViewModel의 비즈니스 로직이 UI를 그리도록 하였어요

SceneDelegate

        let contentSceneDIContainer = appDIContainer.makeContentSceneDIContainer()
        let tabBarController = contentSceneDIContainer.makeTabBarController()

        window = UIWindow(windowScene: windowScene)
        window?.rootViewController = UINavigationController(rootViewController: tabBarController)
  • 다음과 같이 SceneDelegate에서 appDIContainer를 불러옵니다.
  • appDIContainer는 데이터 소스를 정의하고, ContentDIContainer에서 의존성 주입을 기술하였어요

🚀 PR Point

  • 어렵네요.. 알려주세요,,!

🔗 Issue

Resolved #7

@kim-seonwoo kim-seonwoo self-assigned this Jun 7, 2024
@kim-seonwoo kim-seonwoo linked an issue Jun 7, 2024 that may be closed by this pull request
Copy link

@hooni0918 hooni0918 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

역시 오비는 다르다..!!!! 의존성 분리를 너무 잘해놓으셔서 눈호강 하고 갑니다
오늘도 행복하세요 :)


import Foundation

final class AppDIContainer {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와! 의존성분리를 하시다니 진짜 본격적으로 하셧군요! 역시 빡고수,,

Comment on lines +24 to +27
init(viewModel: MainContentViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

의존성 주입에 기립박수치고갑니다

requestDetailInfo(code: code) { [weak self] detailData in
let detailViewController = DetailViewController()
detailViewController.detailView.configure(with: detailData)
private func bindViewModel() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

의존성을 잘 분리하셧는데 이부분도 분리한김에 Coordinator 패턴을 적용해서 화면 리로드를 가져가봐도 좋을것같아요..! 츄라이츄라이

Copy link

@SeoyoungOhMe SeoyoungOhMe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MVVM도 적용하고 과제 하시느라 고생하셨어요!! PR도 자세히 적으셔서 이해하기 수월했습니다!! 쵝오 💪

@@ -10,16 +10,19 @@ import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

let appDIContainer = AppDIContainer()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

의존성 분리 수고하셨습니다!!

Comment on lines +8 to +13
import Foundation

protocol ContentRepository {
func getMovieInfo(completion: @escaping (Result<[Content], Error>) -> Void)
func getDetailInfo(code: String, completion: @escaping (Result<ContentDetail, Error>) -> Void)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프로토콜 선언은 이렇게 하는거군요! 잘 보고 갑니다 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Refactor] 7차 세미나 리펙토링
3 participants