반응형
해당 게시글은 Robert C. Martin님의 Clean Architecture and Design 강의를 보고 내용을 정리한 게시글입니다.
다만 개인적인 정리 및 확인의 용도로 작성한 게시글이기 때문에 가독성이 떨어집니다.
관심 있는 분들은 직접 영상을 감상하시는 것을 추천드립니다.
한글자막도 있고 길이도 1시간 정도밖에 되지 않아요. 아직 안 보신 분은 꼭 보세요!!!
https://amara.org/ko/videos/0AtjY87egE3m/url/1216370/
아키텍처는 의도를 가진다
- 아키텍처는 의도를 표현하는 것이다. (도서관 교회건물의 구조도를 보면 그 건물이 무엇을 하는지 알 수 있듯이)
- Interactor : 비즈니스 룰에 따라 유즈케이스를 구현하고 입력값을 받아 처리한 뒤 출력 값을 출력한다.
- Entity : 어플리케이션 비종속적인 비즈니스 룰들이 담겨있다.
- Interactor는 입력 인터페이스와 출력 인터페이스가 존재하는데 (화살표) 입력 인터페이스는 직접 구현하고 있고 출력 인터페이스는 다른 곳에서 구현된 것을 사용하고 있다.
- 두 인터페이스와 Interactor의 화살표 방향이 같은데, 이는 중요한 포인트이다. (추후 언급되지만 이렇게 해야 애플리케이션의 독립성이 생기기 때문)
- 사용자가 입력을 통해 Request Model이라는 순수한 데이터구조를 Interactor에게 보내면 Interactor는 이를 해석한다.
- 그리고 이를 Entity에 보내서 적절한 처리를 하도록 한다.
- 그 후 Interactor는 다시 Entity를 조회해서 변경사항을 확인하고 Result Model이라는 또 다른 순수한 데이터 구조를 만들어 출력 인터페이스를 통해 유저에게 전달된다.
- Interactor에 대한 테스트를 수행하고 싶다면, 임의의 입력 데이터자료를 생성해서 Interactor를 호출하고 출력 데이터를 확인하기만 하면 된다. 다른 부분은 안 봐도 된다. 웹서버고 뭐고 그냥 필요 없는 것이다.
MVC
- Controller는 특정한 방법으로 사용자의 입력을 전달한다.
- Model은 비즈니스 룰을 담당한다. Model은 자신이 어떻게 보여질지 모르고 입력이 어디서 오는지도 모른다.
- View는 Model을 관찰하다가 변경되면 View가 변경되도록하는 역할을 담당한다. Model의 콘텐츠를 표시하거나 전달하는 것이다.
- MVC는 GUI 환경에 적합하며, 원래는 작은 것에 사용하는게 목적이었다. (버튼, 체크박스, 텍스트 필드 등)
- 스크린 같은 큰 장치에는 사용하지 않았다.
- 하지만 세월이 흐르면서 MVC는 비틀어지고 변형되었다. 모방되면서 완전히 다른 것에 같은 이름을 붙이고 그 역시 좋을 것이라고 주장했다. (객체지향, 구조, 애자일 등도 다 그랬다)
- 요즘 MVC 프레임워크가 많은데 초기에 제시된 트릭 뷔 린 스카욱의 MVC랑은 다른 것이다.
- 요즘엔 이런식으로 생겼다.
- WEB(Rails, Spring or Anything)은 복잡하고 끔찍한 URL을 어떻게든 Controller에게 전달한다.
- Controller는 비즈니스 오브젝트들에게 일을 하라고 소리를 친다. (...)
- 그리고 비즈니스 오브젝트들로부터 데이터를 모아서 View에게 알려주면 View는 비즈니스 오브젝트들에게서 데이터를 조회하고 표시한다.
- 이때 여러 function들이 필요해지는데 적절한 위치를 찾지 못해 결국 비즈니스 오브젝트 자체에 function들이 생기면서 오염된다
Presenter
- Interactor는 내재된 유즈케이스를 마치고 entity의 데이터를 조회한 상황이다.
- 이제 Response Model을 생성해 출력 인터페이스를 통해 전달해야 한다.
- 출력 인페이스를 사용하는 것은 Interactor지만 구현하는 것은 Presenter이다.
- Presenter는 순수데이터 구조인 Response Model을 받아서 ViewModel이라는 또 다른 순수 데이터 구조로 변형시킨다.
- ViewModel은 출력값을 표현하는 순수한 데이터 구조이다.
- 화면에 텍스트 필드가 있으면 ViewModel도 텍스트필드가 있고, 소수점 이하 두 자리만 표현하겠다면 TrimToTwoDecimalPlaces와 ConvertIntToString과 같은 메서드가 존재함. 음수를 괄호로 표현하고 있다면 Presenter가 데이터에 괄호를 붙여서 ViewModel에 저장한 것이다. 비활성화된 메뉴 아이템은 회색으로 보여야 한다면 불린 값이 존재할 것이다.
- 화면에 표시되는 모든 것이 ViewModel에 저장된다. (물론 추상화된 방식으로)
- View는 그냥 ViewModel로부터 데이터를 가져올 뿐이고 아무것도 처리하지 않는다. 일반적으로는 테스트도 잘하지 않는다. (어차피 보이기 때문에)
- Presenter는 테스트할까? 가능하다. 그저 데이터를 받아서 처리하는 게 다이기 때문이다.
- 우리의 목표가 이것이다. 다른 것을 실행하지 않고도 가능한 많은 것이 독립적으로 테스트 가능하도록 하는 것.
- 이게 전체적인 그림이다.
- Interactor는 입력 인터페이스를 통해 들어온 Request Model에서 데이터를 읽은 다음, Response Model에 데이터를 저장하고 출력 인터페이스를 통해 Presenter에게 전달한다.
- 검은색은 애플리케이션과 전달 메커니즘을 구분하는 선이다.
- 검은색을 지나는 모든 화살표가 애플리케이션을 향한다. 이를 통해 어플케이션은 Controller나 Presenter에 대한 정보가 하나도 없음을 알 수 있다.
- 외부의 세계는 그냥 플러그인 정도로 생각하면 된다.
- 플러그인 개발자는 IDE 개발자를 알지만, IDE 개발자는 플러그인 개발자에 대해 모른다.
- 누가 상대방에 피해를 줄 수 있을까? 플러그인(JetBrain) 개발자가 아무리 IDE(Visual Studio)를 해치려고 해도 IDE 개발자는 그것을 신경 쓸 필요도 없다.
- 다른 무엇보다 비즈니스 룰을 바깥쪽으로부터 보호하는 게 중요한 것이다. I/O 메커니즘이 비즈니스 룰에는 관여할 수 없도록 해야 한다.
About Database
- 이게 올바른 형태일까? 데이터베이스가 서비스의 중심이고 애플리케이션은 곁가지일까?
- 아니다. 데이터베이스는 디테일이고 아키텍처적으로는 큰 의미가 없다.
- 데이터베이스는 그냥 저장소이다. 아키텍처와도 비즈니스 룰과도 연관이 전혀 없다.
- Stored Procedure에 비즈니스 룰이 존재하는 것은 잘못된 것이다. 그곳에는 쿼리, 무결성 검증 같은 것을 넣어야 한다.
- 앞서 말한 방식과 똑같은 방식으로 애플리케이션을 데이터베이스로부터 보호할 수 있음
- 중간에 존재하는 검은 선을 보면 해당 선을 지나는 모든 선이 애플리케이션 쪽을 향하고 있다
- 데이터베이스를 애플리케이션의 플러그인처럼 만든 것이다.
- 이제 데이터베이스를 오라클, MySQL, CouchDB 등등 맘대로 교체할 수 있다. (실제로 안 바꿔도 바꿀 수 있다는 게 좋은 거임)
- Entity Gateway라는 인터페이스를 두었다. Entity Gateway의 메서드는 쿼리 메서드이다.
- Entity Gateway의 구현부는 검은 선 아래에 위치한다.
- Entity Gateway는 데이터를 모아 엔티티 오브젝트 형태로 저장한다. 검은 선을 넘어오면서 애플리케이션 입장에서 엔티티 오브젝트가 되는 것이다.
- ORM 툴이 있다면 어디 있을까? 검은선 아래에 있다.
- 절대 애플리케이션 영역이 데이터베이스들과 연관되어선 안된다.
- 오브젝트란 퍼블릭 메서드의 집합이다. 그 외에는 알려져선 안된다. 그 안에 데이터가 있을 수도 있지만 모두 private이고 외부에선 알 필요가 없다.
- 우리 관점에서는 오브젝트는 그냥 메서드 덩어리이다. 데이터 덩어리가 아니다.
- 오브젝트는 행위에 대한 내용 정도로 보아야 한다. 오브젝트는 비즈니스 룰에 대한 내용이어야 한다. 데이터가 아니다.
- Data Structure란 잘 알려진 데이터 요소고 누구에게나 공개된다. 메서드가 없다.
- 오브젝트와 데이터 구조체는 완전 다른 것이다. 데이터 구조체는 공개된 데이터를 가지고 메서드가 없지만, 오브젝트는 메서드를 가지고 공개된 데이터가 없다.
- ORM은 틀린 말이다. 오브젝트와 관계형 데이터는 매칭 할 수 없다. 왜냐면 데이터베이스에서 나온 것은 데이터 구조체이기 떄문이다. 데이터 구조체는 오브젝트에 매칭할 수가 없다. 정말 다른 것이기 때문이다.
- 엔티티에 저장되는 데이터는 어딘가 알 수 없는 곳에서 제공되어야 한다. 어떻게 전달되는지도 중요하지 않다.
About Framework
- 프레임워크는 물론 좋다. 특히 개발 시간을 크게 줄여준다.
- 하지만 프레임워크는 우리가 프레임워크에 종속되도록 만듦. 베이스 클래스를 만들어서 이것을 사용하도록 만든다. 이것을 사용하면 프레임워크 자체에 강하게 엮인다. 상속 자체가 매우 강한 종속성을 생성하는 작업이기 때문이다.
- 현명한 아키텍트는 그런 관계를 만들지 않는다. 프레임워크가 일을 더 어렵게 만들고 애플리케이션을 단단히 엮어버린다며 보수적이고 비판적으로 바라본다. 무엇보다 프레임워크 제작자는 내가 가장 중요하게 생각하는 것이 무엇인지 모르기 때문이다.
Fitnesse
- 예전에 엉클 밥님이 아들과 함께 만든 툴
- 위키 텍스트를 HTML로 저장하기 위한 WikiPage라는 오브젝트를 만들었다.
- 추상 클래스인 WikiPage를 MockWikiPage가 구현하고 있다.
- WikiPage는 Load나 Save 같은 function을 가지고 있다.
- 하지만 MockWikiPage에서는 이를 구현하고 있지는 않고 그냥 빈 껍데기이다.
- 이 상태로 그냥 서비스의 핵심 비즈니스 룰을 구현하는 데에 집중했다.
- 어느 정도 구현이 마무리된 후, 이제 데이터베이스 만들까에 대한 논의가 있었다.
- 그냥 변환된 페이지를 메모리에 저장하고 나머지 기능을 보완하자!
- 더 구현이 마무리된 후, 또 데이터베이스 도입에 대한 논의가 있었다.
- 그냥 파일에 저장하자!
- 결국엔 MySQL과의 연동 기능을 플러그인으로 배포했었다.
- 이처럼 좋은 아키텍처는 중요한 의사결정을 뒤로 미룰 수 있게 한다.
- 아키텍처의 목표는 결정을 안 할 수 있도록 하는 것이다. 가능한 많은 정보를 가지고 결정할 수 있게 미루고 미루는 것이 가능해야 한다.
- 상위 레벨의 결정을 미룰 수 있도록 아키텍처나 코드 구조를 설계하자.
- 아키텍처에 대해 얘기할 때 프레임워크 이야기하지 마라. (우린 SQL 서버를 가지고 있으며 MVVM 어쩌고 저쩌고...)
- 아키텍처는 유즈 케이스이며 유즈 케이스는 툴에 대해 전혀 몰라야 한다.
- 웹이나 데이터베이스 등 애플리케이션 없이 돌아가야 함
- 다음에 애플리케이션 개발할 때 어떤 결정을 미룰 수 있을지 생각해보아라.
- 애플리케이션은 위와 같은 플러그인 구조여야 한다.
- GUI, 데이터베이스, 프레임워크 같은 디테일은 모두 유즈 케이스의 플러그인이 되어야 한다.
반응형
'🍎 Apple > Patterns' 카테고리의 다른 글
[iOS Design Pattern] Decorator (0) | 2022.05.18 |
---|---|
[iOS Design Pattern] Factory Method (0) | 2022.04.26 |
[iOS Design Pattern] Coordinator (3) | 2022.04.12 |
[iOS Architecture] VIPER (0) | 2022.04.11 |
[iOS Architecture] MVC, MVP, MVVM (feat. Clean Architecture) (4) | 2022.01.30 |