아키텍쳐 Architecture UseCase
개발 순서
- 정적 모델링 : 클래스를 찾고 클래스들의 속성을 찾고 클래스들의 관계를 찾는다.
- 동적 모델링 : 도메인 모델에 행위 추가
- 요구사항 식별
- 메서드 식별
- TDD로 메서드 구현
1. 클래스, 속성, 관계 식별
2. 도메인 모델에 행위 추가하기
- 도메인 모델에 행위 추가
- 도메인 모델의 행위를 결정하기 위해 도메인 모델의 책임(Responsibility)과 상호작용(Collaboration)을 식별
- 책임 : 클래스가 아는 것(속성, 관계), 하는 것, 결정하는 것
- 책임 수행을 위해 다른 클래스를 호출하는 것
- 책임과 상호작용을 식별하는 절차
- 요구사항(유즈케이스, 유저스토리, UI) 분석을 통해 어플리케이션이 처리해야하는 요구사항 식별
- 도메인 모델의 클라이언트(presentation)에게 도메인 모델을 노출하기 위한 도메인 모델의 인터페이스(타입, 메서드) 결정
- 해당 인터페이스를 각각의 요구사항을 고려하여 TDD로 구현
2.1 요구사항 식별하기
- 처리할 요구사항 식별/어떻게 응답할 지 결정
- UI, 유즈케이스, 유저스토리 등 분석
- 요구사항은 사용자 행위, 사용자 행위 요청에 대한 앱의 응답(책임)으로 구성
- 앱의 책임은 2가지로 그룹화
- 사용자 입력 검증, 값 계산, DB 갱신
- 값 출력
2.2 메서드 식별하기
- 서비스 메서드
- 레포지토리 메서드
- 도메인 모델의 클라이언트는 도메인 티어를 2번 호출
2.3 TDD로 메서드 구현
- 서비스 메서드에 대해 다양한 인수를 넣어 하나 이상의 테스트 케이스를 작성
- mock 객체 이용
- service 메서드 -> repository 메서드 순, top down 방식으로 구현
- 구현하다 발견되는 클래스나 메서드를 구현하지 않고 mocking
UseCase
Architecture
- web 기반 accounting 시스템의 아키텍처에서 주목할 부분?
- web 시스템이 아닌 accounting 시스템
- SW 아키텍쳐는 accounting issue를 드러내야 함
usecase
- 앱 개발은 독립적인 use case에 의해 주도되어야 한다
- use case가 시스템에서 가장 중요
- 사용자가 특정 목적을 이루기 위해 시스템과 어떻게 상호작용하는지에 대한 형식적 기술
- 사용자가 ~하면 시스템은 ~한다로 기술
- 주요 흐름이 있고 예외가 발생하면 다른 흐름을 나타내야 한다
- screen, button 등과 같은 웹은 언급하지 않음
- 시스템에 들어가는 데이터, 커맨드와 시스템이 응답하는 것만 언급
- 입력 데이터를 해석하여 출력 데이터를 생성하는 필수 알고리즘
use case driven architecture
- 아키텍쳐는 시스템의 의도인 use case를 나타낸다
use case algorithm
- 다른 비즈니스 객체들을 use case에 위치시킴
- 어떻게 시스템을 파티셔닝해서 use case가 핵심 구성 원리가 되게 할 것인가?
partitioning
- 아키텍쳐는 3개의 기본적인 객체를 갖는다
- business objects : entities
- UI objects : boundaries(dto)
- use case objects : controller(interactors) MVC의 C 아님
- entities have:
- 앱 독립적인 비지니스 로직
- 다른 앱에서도 entity들은 사용됨
- 특정 앱에 특화된 메서드를 가지면 안됨
- interactors have:
- 앱 종속적인 비지니스 로직
- 특정 앱에 특화된 메서드는 interactor 객체에 구현
- interactor는 앱에 특화된 로직을 통해 목적 달성
- use case의 목적 달성을 위해 앱과 무관한 entity로직을 어떻게 호출할지 아는 것이 interactor의 책임이다
- use case의 책임 중 하나는 사용자로부터 입력을 받고 결과를 사용자에게 반환하는 것이다
- 이를 위한 객체는 boundary object
- boundary object
- use case를 delivery 메커니즘으로부터 격리
- use case를 delivery 메커니즘 간 통신 수단 제공
- use case는 delivery 메커니즘에 대해 모른체 boundary의 반대편에 존재
partitioning - flow
- delivery 메커니즘
- 사용자 요청 수집
- 요청을 표준적인 형식(RequestModel)로 표현
- boundary를 통해 RequestModel을 interactor에 전달
- interactors
- RequestModel을 받음
- 앱에 특화된 비지니스 로직 수행
- entity 조작하여 앱 독립적인 비지니스 로직 수행
- ResultModel 생성
- boundary를 통해 다시 delevery 메커니즘으로 전달
isolation
- 소스 코드 의존성은 delivery 메커니즘과 decouple하기 위해 하나의 방향만 유지해야 한다
database
- 비지니스 객체가 아니라 data structure에 포함
- DB와 entity 간 boundary layer 제공해야 함 - Dependency Inversion Principle
conclusion
- 아키텍쳐는 툴이나 프레임워크에 기반하지 않는다
- 좋은 아키텍쳐
- 툴, 프레임워크에 대한 결정을 아주 오랫동안 미룸
- 이행되지 않은 결정의 개수 최대화
- delivery 메커니즘에 의존하지 않고 노출시키지 않고 숨김
- 시스템의 모양을 보면 웹 시스템인지 여부를 알 수 없어야 함
- use case는 주요한 추상화이고 아키텍쳐를 구성하는 핵심적 원칙
- 아키텍쳐를 보면 시스템의 의도를 볼 수 있어야 함
- interactor는 use case 캡슐화, entity는 비지니스 객체 캡슐화, boundary는 UI와 격리 제공
- 격리를 얻기 위해 앱을 delivery 측과 분리하는 boundary 인터페이스 생성
아키텍트는 누구인가?
- 코딩하지 않는 아키텍트는 무능해진다
- 코딩 잘 못하는 아키텍트의 설계는 무용지물
- 코드를 작성해야 한다
- 프로그래머와 함께 일해야 한다
- 코딩을 해야할 때가 있다면 반드시 코드를 잘 짜야한다