프로젝트의 규모가 너무 크고 복잡하여 Module을 분해하고, 일정 수준의 디스틸레이션을 거치는 것만으로 복잡성을 줄일 수 없다면 어떻게 해야 할까?
나무보다 숲.
대부분의 대규모 구조는 UML로 표현할 수도 없고 그럴 필요도 없다.
대부분의 대규모 구조는 모델과 설계의 형태를 만들고 설명하지만 UML에 나타나지는 않는다.
대규모 구조는 설계에 관한 또 다른 수준의 의사소통을 제공한다.
문제는 참고할 규칙이 얼마나 엄격하고 어디에서 유래했느냐다. 설계를 관장하는 규칙이 정말로 상황에 맞아떨어진다면 방해가 되지 않고 실질적으로 도움이 되는 방향으로 개발을 이끌 뿐 아니라 일관성도 제공할 것이다.
CONTEXT MAP과 달리 대규모 구조는 선택사항이다.
사실 MODULE로 분해했을 때 충분히 이해할 수 있는 정도로 시스템이 간단하다면
대규모 구조가 필요하다지 않다.
대규모 구조는 어떤 구조를 개발하는 데
부자연스러운 제약조건을 강제하지 않고도
시스템을 명확하게 만드는 것으로 판명될 때 적용해야 한다.
맞지 않는 구조는 차라리 없느니만 못하므로
종합적인 구조를 얻으려 애쓰기보다는
발생한 문제를 해결하는 최소한의 집합을 찾는 편이 가장 낫다.
적을수록 더 많은 법이다.
객체 패러다임과 조화를 이루는, 느슨하고 쉽게 이해할 수 있는 대규모 구조
eg. 방화벽, 계층, 중앙, 커널, 부모/자식, 마스터/슬레이브 등등
XP의 핵심 실천사항 가운데 하나라서 유명한 접근법으로 자리잡았다.
XP 커뮤니티 일각에서는 도메인 모델 자체를 “미숙한 은유”라고 이야기해오고 있으나
성숙한 도메인 모델은 결코 미숙하지 않다.
MODEL-DRIVEN DESIGN을 만들고 CORE DOMAIN을 정제하는 데 성공했지만, 설계가 구체화되면서 조율에 어려움을 겪고 있을 때 사용한다.
이를 책임별 계층으로 나눈다.
이는 UML로 표현이 되지 않는다.
RESPONSIBILITY LAYER에 가장 잘 부합하는 계층화 패턴은 RELAXED LAYERED SYSTEM1)이라고 하는 계층화의 일종인데,
이것은 한 계층의 구성요소가 바로 아래에 있는 것만이 아니라 모든 하위 계층에 접근하는 것을 허용한다.
알맞은 RESPONSIBILITY LAYER나 대규모 구조를 찾을 때는 문제 도메인을 이해하고 실험하는 것이 중요하다.
(실험 과정에서) 계층이 바뀌고 병합되고 나뉘고 재정의될 때 찾아서 지켜야 할 몇 가지 유용한 특징은 다음과 같다.
새로운 모델을 위한 걔층을 정의할 때마다
꼭 처음부터 다시 시작해야 하는 건 아니다.
어떤 계층은 관련 도메인군 전체에 나타나기도 한다.
계층화 시스템은 단순하게 유지하는 것이 가장 좋다.
계층이 4~5개를 넘어가면 다루기가 힘들어진다.
계층이 너무 많으면 이야기할 때만큼 호과적이지 않고
대규모 구조가 풀어야 할 복잡성의 문제가 새로운 형태로 다시 나타날 것이다.
대규모 구조는 반드시 철저하게 정제되어야 한다.
다른 객체 집단이 어떻게 행동해야 하는지를 기술하는 객체의 그룹2)
사용자가 개발 과정에서 의도하지 않은 시나리오대로 소프트웨어를 사용할 때, 포용할 수 있는 설계 기법
더 넓은 범위의 규칙으로 제약되기 전까지
모델의 특정 부분을 사용자의 손에 맡겨야 할 때 생기는 문제를 해결한다.
KNOWLEDGE LEVEL은 구성 가능한3) 행위를 갖춘 소프트웨어의 요구사항을 다룬다.
(다른 분석 패턴이 그러하듯) KNOWLEDGE LEVEL은 도메인을 모델링하기보다 모델을 구조화한다.
KNOWLEDGE LEVEL은 REFLECTION 패턴의 도메인 계층을 (개념적으로) 응용한 것. (REFLECTION 패턴은 POSA 참고)
어떤 사물에 대해서 유형(Type)에 따라 행위가 부과되는가?
Folower 용어 | POSA 용어 | 설명 |
---|---|---|
Knowledge Level | Meta Level | 소프트웨어의 구조와 행위에 대한 지식 |
Operational Level | Base Level | 소프트웨어를 애플리케이션의 운영적 책임을 수행 |
KNOWLEDGE LEVEL이 복잡해지면 사용자와 마찬가지로
개발자들도 시스템의 행위를 이해하기가 힘들어진다.
시스템을 구성하는 사용자(또는 관리자)에게는 결국 프로그래머 수준의(그것도 메타 수준의 프로그래머 수준으로) 기량이 필요해질 것이다.
사용자가 실수라도 한다면 애플리케이션은 올바르게 동작하지 않을 것이다.
KNOWLEDGE LEVEL 내의 구조가 바뀌면
기존 운영 수준에 위치한 객체도 그에 맞게 다뤄야 한다.
기존 객체와 신규 객체가 공존하는 것도 가능할지 모르지만 어떻게든 신중하게 분석할 필요가 있다.
Liskov Substitution Principle과 연관.
“Domain-Specific Application Frameworks (Wiley, 2000)“에서 이 패턴을 의욕적으로 시도한 사례를 자세히 살펴보고 있다.
가장 성공적인 사례는 다수의 전문적인 애플리케이션이 완전히 개발되고 난 후에 나타났다.
제약은 양날의 검. 단일 규칙으로 쉽게 해석할 수 있게 만드는 반면, 개발자가 필요로 하는 유연함을 앗아갈 수 있다.
그러므로 (제약성을 가진) 프레임워크를 만들고 대규모 구조의 구현을 엄격히 통제하고자 하는 유혹을 이겨내야 한다.
대규모 구조가 공헌하는 가장 중요한 바는
개념적 응집성과 도메인에 대한 통찰력을 주는 것이다.,
각 구조적 규칙은 개발을 용이하게 해야 한다.
EVOLVING ORDER에 전념하는 팀은
프로젝트 생명주기 내내 대규모 구조를 과감히 재고(fearlessly rethink)해야 한다.
그 팀은 도메인이나 요구사항을 매우 잘 이해하는 사람이 아무도 없었을 때인 초기에 구상한 구조에 안주해서는 안된다.
아쉽게도 그러한 발전이 의미하는 바는
최종 구조가 처음에는 사용할 수 없는 것을 의미하며, 진행하면서 이를 적용하기 위해 리팩터링을 해야하는 것을 의미한다.
비용을 통제하고 이익을 극대화하는 방법들은 다음과 같다.
구조를 간단하고 가볍게 유지하는 것이다..
포괄적인 구조로 만들려고 하지 마라.
가장 중요한 관심사만 다루고 나머지는 사례별로 처리하게 한다.
UBIQUITOUS LANGUAGE의 사용과 팀의 해당 언어 연습.
Restructuring Yields Supple Design
새 가죽 재킷은 뻣뻣하고 입기가 불편하지만 처음 입고 난 후로는 팔꿈치 부분이 몇 차례 구부러져 접힌다.
안정적인 측면은 단순화되는 반면
계속 늘어나는 지식은 모델에 녹아들고 변화의 중심축이 식별되어 유연해진다.
지속적인 디스틸레이션은 다양한 방식으로 구조 변경의 어려움을 덜어준다.