버터플라이 아키텍처 - 김정님

rbw·2024년 2월 20일
0

TIL

목록 보기
97/99

김정님의 게시글을 보고 정리, 후기 글. 자세한 내용/사진은 아래 링크 참조 WIND
https://medium.com/@jungkim/%EB%B2%84%ED%84%B0%ED%94%8C%EB%9D%BC%EC%9D%B4-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98%EB%A5%BC-%EC%86%8C%EA%B0%9C%ED%95%A9%EB%8B%88%EB%8B%A4-9d4abd71c3c1

모든 엔지니어링의 시작은 설계입니다. 입력에 대해 기대하는 특정 동작을 처리해서 원하는 출력이 나오는 시스템을 만들어야 함니다. 요구사항에는 문장 형태로 입력부터 출력까지 흐름을 표현하고, 개발자들은 그것을 해석해서 개발해야함니다.

태초에 뷰가 있었따..!

뷰 하나만 가질 수 있는 iOS 앱도 만들 수 있다고 함니다. 만드는 방식은 진짜 뷰 하나를 window의 subView로 두셨음

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, 
               options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        self.window = UIWindow.init(windowScene: windowScene)
        self.window?.addSubview(BareView.init(frame: UIScreen.main.bounds))
        self.window?.makeKeyAndVisible()
    }
}

이렇게 구성하면 뷰 하나만 있는 앱 완성입니다. 이 BareView는 모든 동작도 다 포함할 수 있겠져

그럼 뷰 컨트롤러는 왜 필요한가

위의 BareView를 VC로 만들어보겠습니다.

self.window?.rootViewController = BareViewController()

BareViewControlelr {
	override func loadView() {
		self.view = BareView(frame: UIScreen.main.bounds)
		(self.view as! BareView).delegate = self
	}
}

뷰 컨트롤러는 말 그대로 뷰를 조작 하기 위해서 필요합니다. UIControl 계열은 입력을 받아서 IBAction을 호출하거나 타깃-액션을 호출함니다. 이 과정은 Application 객체에서 sendEvent(), sendAction()로 호출합니다.

대부분 이벤트는 UIResponder를 상속받은 뷰 객체들에게 전달됨니다. VC는 window에 뷰를 제공하고, 여러 뷰에게 전달된 액션을 받아서 처리하는 역할을 함니다.

App -> UIViewController 의 흐름이겠져

MVC는 필요악인가

iOS 플랫폼에서는 모델을 따로 제공하지 않다보니 앱을 만들다보면 VC에 기능도 많아지고 다양한 모델이 만들어진다고 함니다. 그래서 독립적인 VC가 아니라 뷰-컨트롤러가 되어버려서 아쉬운점이 생김니다.

  • 테스트하기 어려워진다
  • 유즈케이스를 찾기 어렵다
  • 동시 작업이 어렵다

어떤 회사는 뷰 컨트롤러 단위로 팀을 나누기도 한다네요.

위에서 설명한 view 하나로 앱 만들기 -> VC로 만들기 는 크게 다르지

단지 관심사를 분리하기 위한 역할과 책임을 어떤 단위로 묶어서 설계하느냐의 차이만 있습니다.

iOS에서 필요한 클린 아키텍처

개발자마다 관심사를 분리하는 시야와 기준이 다름니다. 그래서 아키텍처는 달라질 수 밖에 없슴니다.

김정님의 해석은 데이터 흐름과 의존성의 관점에서 가장 바깥쪽에 있는 APP영역부터 UI, PRESENTATION, DOMAIN 영역으로 구분합니다.

클린아키텍처는 육각형 아키텍처를 엉클밥이 정리하면서 나온 아키텍처라고 합니다. 육각형 아키텍처는 이후에 여러 포트와 어댑터로 역할과 책임을 구분하는 방식이라 포트와 어댑터 구조로 부르는편이라고 함니다.

여기서 놓치기 쉬운 부분은 설정컴포넌트입니다. 이 컴포넌트는 의존성을 관리하기 위한 구조적인 선택임니다.

버터플라이 아키텍처에서 어려운 부분은 유즈케이스라고 함니다. 어떤 앱을 기준으로 설명하느냐에 따라서 구현이 모두 달랐기 때문임니다.

유즈케이스 패턴

김정님이 생각하는 기준에서 iOS 앱 유즈케이스는 크게 다섯가지 카테고리로 나눌 수 있다고 함니다.

  1. 사용자가 입력하는 이벤트 -> 사용자에게 보여주는 출력 흐름
  2. 사용자가 입력하는 이벤트 -> 저장하거나 요청 보내기
  3. 외부에서 들어오는 이벤트 -> 저장하거나 응답 보내기
  4. 외부에서 들어오는 이벤트 -> 사용자에게 보여주는 출력 흐름
  5. 앱 수준에서 받는 이벤트 -> ?

POP가 필요해

버러플라이 아키텍처를 실제로 구현하기 위해선 다양한 프로토콜을 포트로 활용해야합니다. 응집도를 높이고 결합도를 낮춰서 영역별로 독립적으로 만들기 위해서임니다.

프로토콜을 사용해서 노출할 부분만 보여주고, 해당 타입을 사용하여 의존성을 주면 결합도가 낮아지겠져 !


클린아키텍처를 iOS에 알맞게 적용하려는 시도에서 나온 글이라 그런지 거의 유사하였따. 입/출력의 일관적인 흐름, POP를 사용하여 의존성을 낮추는 부분을 다시 한 번 보게되어 좋았던 글. 나중에 책 출판하시믄 꼭 사서 더 봐야할둣

profile
hi there 👋

0개의 댓글