2.2 소프트웨어 설계 원칙
개요와 동기
소프트웨어 설계 원칙은 시간이 지나도 코드를 이해하고, 바꾸고, 확장할 수 있도록 배열하기 위한 휴리스틱입니다. 이름 붙은 약어(객체 지향 설계 원칙 다섯 가지인 SOLID, 반복하지 마라는 DRY, 단순하게 유지하라는 KISS, 그것은 필요 없을 것이라는 YAGNI), 구조적 개념(결합도, 응집도, 관심사 분리), 목록화된 디자인 패턴, 도메인 주도 설계(비즈니스 도메인의 언어로 소프트웨어를 모델링)와 같은 상위 수준의 모델링 접근, 그리고 객체 지향, 함수형, 데이터 지향 스타일 사이의 선택을 포함합니다. 이 중 법칙은 없습니다. 압축된 경험이며, 판단력을 가지고 적용해야 합니다.
큰 팀에서 공유된 원칙의 가치는 조율입니다. 수백 명의 엔지니어가 같은 시스템에서 일할 때, 설계 논의를 위한 공통의 어휘와, 독립적으로 쓴 모듈이 서로 맞물리도록 하는 공통의 기본값이 필요합니다. 좋은 설계는 많은 사람이 끊임없는 충돌 없이 시스템을 병렬로 바꿀 수 있게 하는 것입니다. 또한 기업과 정부 시스템의 통상적 수명인 10년 뒤에도, 원 작성자의 재직 기간을 한참 지나서도 시스템을 변경 가능하게 유지하는 것이기도 합니다.
핵심 기술은 원칙을 암기하는 것이 아니라 각각이 언제 오도하는지 아는 것입니다. 모든 원칙에는 실패 양상이 있습니다. DRY는 잘못된 추상화를 낳을 수 있고, SOLID는 불필요한 간접화를 낳을 수 있고, YAGNI는 정말 필요한 확장성을 굶길 수 있습니다. 이 장은 원칙을 적용 영역이 있는 도구로 다루며, 약어가 섬기려 하는 더 깊은 속성으로서 결합도와 응집도를 강조합니다.
핵심 원칙
- 결합도와 응집도를 먼저 관리하십시오. 이름 붙은 원칙 대부분은 이 두 속성을 개선하는 간접적 방법입니다.
- 변경에 최적화하십시오. 좋은 설계는 실제로 해야 할 변경의 비용을 최소화합니다.
- 지금 동작하는 가장 단순한 설계를 선호하되, 변경이 일어날 법한 곳에는 경계를 유지하십시오.
- 중복이 잘못된 추상화보다 쌉니다. 패턴이 분명해질 때까지 기다리십시오.
- 의존성을 명시적으로 만들고 안정적인 것을 향하게 하십시오.
- 도메인을 도메인의 언어로 모델링하십시오. 소프트웨어 경계를 비즈니스 경계와 정렬하십시오.
- 이념이 아니라 문제에 맞춰 패러다임을 선택하십시오. 대부분의 큰 시스템은 실용적으로 혼합되어 있습니다.
권장 사항
SOLID를 체크리스트가 아닌 렌즈로 쓴다
모듈을 응집력 있게 유지하려고 단일 책임을, 경계가 정말 존재하는 곳에서 의존성을 추상화로 향하게 하려고 의존성 역전을, 확장 지점이 실제인 곳에 개방-폐쇄를 적용하십시오. 구현이 하나뿐이고 두 번째가 보이지 않는데 약어를 만족시키려고 인터페이스, 팩토리, 계층을 만들어 내지 마십시오. 간접화에는 비용이 있으며, 모든 읽기에서 치릅니다.
DRY를 텍스트가 아닌 지식에 적용한다
DRY는 하나의 권위 있는 지식을 중복하지 않는 것에 관한 것입니다. 그저 비슷해 보이는 줄을 없애는 것에 관한 것이 아닙니다. 비슷해 보이지만 서로 다른 이유로 바뀌는 두 코드 조각은 분리된 채로 두어야 합니다. 관련 없는 것들을 결합시키는 성급한 공유 추상화보다 약간의 중복을 선호하십시오. 진짜 패턴이 두세 번 나타난 뒤에 추상화를 추출하십시오.
KISS와 YAGNI로 추측에 저항한다
상상하는 요구사항이 아니라 가진 요구사항을 위해 구축하십시오. 설정 가능한 프레임워크, 플러그인 시스템, 아무도 요청하지 않은 확장 지점 같은 추측성 일반화를 피하십시오. 균형추는 어떤 유연성은 정말로 일찍 넣는 편이 싸다는 것입니다. 안정적인 인터페이스나 깔끔한 이음매 같은 것입니다. YAGNI는 추측성 구현에 반대하는 것이지 신중한 경계에 반대하는 것이 아닙니다.
낮은 결합도와 높은 응집도를 명시적으로 설계한다
각 모듈이 잘 정의된 한 가지를 하게 하고(응집도), 좁은 인터페이스를 통해 가능한 한 적은 다른 모듈에 의존하게 하십시오(낮은 결합도). 설계를 리뷰할 때 어떤 변경이 모듈 경계를 넘어 파급되는지 물으십시오. 그 파급이 결합도의 진짜 척도입니다. 관심사 분리는 계층과 횡단 관심사에 적용된 같은 생각입니다.
디자인 패턴은 어휘로, 안티패턴은 경고로 쓴다
패턴은 반복되는 해법에 대한 유용한 공유 이름입니다. 문제가 실제로 맞을 때 꺼내 쓰십시오. 세련돼 보이려고 패턴을 부과하지 마십시오. 패턴이 많은 코드는 과설계의 신호인 경우가 많습니다. 일반적인 안티패턴(갓 오브젝트, 부적절한 빈약한 모델, 진흙 덩어리, 분산 모놀리스)을 진단용 이름표로 익히십시오.
도메인이 복잡한 곳에 도메인 주도 설계를 채택한다
풍부한 비즈니스 규칙이 있는 시스템에는 DDD의 전술 및 전략 도구를 쓰십시오. 도메인 전문가와 공유하는 유비쿼터스 언어, 시스템을 독립적으로 모델링되는 조각으로 나누는 경계 컨텍스트, 그 조각들이 서로 어떻게 관련되는지 기술하는 컨텍스트 맵입니다. 경계 컨텍스트는 팀 소유권을 모델 경계와 맞춰 주기 때문에 기업 규모에서 특히 값집니다. DDD는 단순한 CRUD(생성, 조회, 수정, 삭제) 시스템에는 과합니다.
적합성으로 패러다임을 고른다
상태가 있는 동작을 캡슐화하고 도메인을 모델링하는 데 객체 지향을 쓰십시오. 변환, 동시성, 불변성을 통한 예측 가능성에는 함수형 스타일을 쓰십시오. 성능과 캐시 동작이 지배적인 곳에는 데이터 지향 설계를 쓰십시오. 큰 시스템은 셋을 모두 섞습니다. 구성 요소별로 선택하고 스타일 사이의 경계를 깨끗하게 유지하십시오.
장단점
| 원칙 / 접근 방식 | 잘 적용했을 때 | 실패 양상 |
|---|---|---|
| SOLID | 변경이 일어나는 곳의 분명한 이음매. 테스트 가능한 단위 | 인터페이스와 계층의 증식. 보람 없는 간접화 |
| DRY | 진짜 지식의 단일 진실 원천 | 관련 없는 코드를 결합하는 잘못된 추상화 |
| KISS / YAGNI | 군더더기 없고 이해 가능한 시스템 | 설계가 부족한 이음매. 필요한 유연성을 나중에 덧붙이는 비싼 비용 |
| 디자인 패턴 | 공유 어휘. 검증된 구조 | 패턴 화물 숭배. 우발적 복잡성 |
| 도메인 주도 설계 | 정렬된 모델과 팀. 길들여진 복잡성 | 단순한 도메인에서의 무거운 의식. 잘못 놓인 컨텍스트 경계 |
| 함수형 / 불변 | 예측 가능성. 더 안전한 동시성 | 본질적으로 상태가 있는 문제에는 어색함. 성능의 놀라움 |
반복되는 긴장은 설계 부족과 과설계 사이에 있습니다. 설계가 부족한 시스템은 결합이 쌓여 경직됩니다. 과설계된 시스템은 누군가 이해하고 유지해야 하는 추상화에 빠져 허우적댑니다. 답은 고정된 점이 아니라 규율입니다. 충분한 정보가 생길 때까지 결정을 미루되, 마음을 바꿀 수 있게 하는 이음매는 유지하는 것입니다.
팀과 논의할 질문
공유 추상화를 추출하는 구체적인 임계값은 무엇이며, DRY가 잘못된 추상화를 낳지 않게 어떻게 막습니까? 이 장은 중복이 잘못된 추상화보다 싸며, 추출하기 전에 패턴이 두세 번 나타나기를 기다려야 한다고 단호히 말합니다. 큰 팀에서 위험은 누군가 비슷해 보이는 두 조각을 팀 경계를 넘는 공유 모듈로 합쳐서, 이후 한 호출자에 대한 모든 변경이 다른 쪽으로 파급되는 것입니다. 가져올 신호는 중복이 같은 이유로 바뀌는지 아니면 지금 그저 비슷해 보이는지입니다. 세 번의 규칙에 합의하고, 호출자를 결합하기 전에 후보 추상화가 실제로 함께 바뀐 적이 있음을 요구하십시오. 그 하나의 합의가 많은 팀이 의존하게 된 뒤에는 풀기 비싼 한 부류의 결합을 막습니다.
결합도와 응집도를 직감에 맡기지 않고 설계 리뷰에서 어떻게 가시화합니까? 핵심 원칙은 결합도와 응집도를 모든 약어 위에 두며, 결합도를 모듈 경계를 넘어 파급되는 변경으로 정의합니다. 직관은 시스템의 자기 구석만 보는 수백 명의 엔지니어에 걸쳐서는 확장되지 않습니다. 기계가 만들 수 있는 증거를 가져오십시오. 의존성 그래프, 어느 모듈이 같은 커밋에서 함께 편집되는지 보여 주는 동시 변경 데이터입니다. 변경이 어떤 모듈 경계를 넘도록 강제하는지 묻는 명시적 리뷰 질문을 더하십시오. 두 모듈이 항상 함께 바뀐다면, 합치거나 둘 사이의 경계를 고치라는 신호입니다.
시스템에서 도메인 주도 설계를 정당화할 만큼 풍부한 도메인과 DDD가 과한 단순한 CRUD 앱 사이의 선은 어디에 있습니까? 이 장은 DDD의 경계 컨텍스트가 팀 소유권을 모델 경계와 정렬하기 때문에 바로 그 점에서 권하고, DDD가 단순한 생성-조회-수정-삭제 시스템에는 과하며 실제 모델링 없이는 의식으로 퇴화한다고 경고합니다. 어느 방향으로든 이를 잘못하면 비쌉니다. 얇은 도메인에 대한 무거운 DDD는 단순한 앱을 의식 속에 묻고, 많은 팀에 걸친 널리 퍼진 공유 모델은 끊임없는 팀 간 조율을 강요합니다. 실제로 결정하는 신호를 가져오십시오. 비즈니스 규칙의 밀도, 몇 개의 팀이 조각을 독립적으로 소유해야 하는지입니다. 전략적 장치는 복잡한 핵심에 남겨 두고, 단순한 가장자리는 단순하게 두십시오. 그러면 DDD 연극과 진흙 덩어리 모두를 피할 수 있습니다.
추상화, 인터페이스, 디자인 패턴이 더하는 간접화를 감수할 가치가 있는 때는 언제이며, 설계가 과설계라고 부를 권한은 누구에게 있습니까? 이 장은 간접화에는 모든 읽기에서 치르는 비용이 있으며, SOLID를 만족시키거나 세련돼 보이려고 인터페이스, 팩토리, 계층을 만드는 것이 실패 양상이라고 분명히 합니다. 큰 팀에서는 압력이 반대로 작용합니다. 리뷰어가 규율 있어 보여서 추가 추상화를 통과시키고, 아무도 구조를 줄이자고 주장하는 사람이 되고 싶어 하지 않습니다. 상충하는 고려는 실제입니다. 어떤 이음매는 정말로 값을 하고 나중에 제거하는 데는 비용이 들기 때문입니다. 구체적 증거를 논의에 가져오십시오. 인터페이스가 오늘 실제로 몇 개의 구현을 갖는지, 확장 지점이 실제로 쓰인 적이 몇 번인지, 한 코드 경로를 따라가려면 독자가 몇 개의 파일을 열어야 하는지입니다. 두 번째가 보이지 않는 단일 구현은 인라인하는 것이 기본 이유라는 데 합의하고, 모욕으로 읽히지 않고 설계를 과설계라고 부를 수 있는 사람이 누구인지 정하십시오. 작성자보다 10년 이상 오래 사는 기업과 정부 시스템에서 불필요한 간접화는 앞으로의 모든 유지보수자가 치르는 세금이므로, “이 추상화가 우리에게 무엇을 사 주는가”를 개인적 도전이 아닌 상시 리뷰 질문으로 다루십시오.
각 구성 요소가 객체 지향, 함수형, 데이터 지향 중 어느 패러다임을 쓸지 어떻게 결정하며, 그 사이의 경계를 어떻게 깨끗하게 유지합니까? 이 장은 큰 시스템이 실용적으로 혼합되어 있고, 상태가 있는 도메인에는 객체 지향, 변환과 동시성에는 함수형, 성능과 캐시 동작이 지배적인 곳에는 데이터 지향 설계를 써서 적합성에 따라 구성 요소별로 선택해야 한다고 주장합니다. 관리하지 않으면 패러다임 선택은 누가 모듈을 먼저 썼는가의 문제가 되고, 가변 상태가 순수해야 할 변환으로 새거나, 함수형 순수주의가 본질적으로 상태가 있는 문제와 싸웁니다. 가져올 만한 증거는 실제 고통이 어디에 있는지입니다. 숨은 상태 때문에 테스트하기 어려운 구성 요소, 캐시에 묶인 핫 경로, 현재 스타일이 어색한 우회를 강제하는 곳입니다. 각 계층의 기본 패러다임을 의도적으로 정하고 스타일 사이의 이음매가 어디에 놓이는지 적어 두어, 함수형 핵심과 명령형 가장자리가 서로 번지지 않게 하십시오. 어떤 기간에 대해 계산이 감사 가능하고 재현 가능해야 하는 규제 또는 정부 시스템에서, 불변의 함수형 핵심은 취향이 아니라 컴플라이언스 요건인 경우가 많으며, 그 제약이 경계를 뒤따르지 않고 이끌어야 합니다.
이 원칙들이 교조로 굳는 것을 어떻게 막으며, 미래의 팀이 다시 살필 수 있도록 설계 결정 뒤의 이유를 어디에 기록합니까? 이 장의 모든 원칙에는 적용 영역과 실패 양상이 있으며, 전체 프레임은 그것들을 시행할 법칙이 아니라 판단력을 가지고 적용할 도구로 다룹니다. 큰 팀에서 원칙은 조용히 규칙이 됩니다. DRY가 모든 중복을 금하고, SOLID가 클래스마다 인터페이스를 의무화하고, 실용적인 예외는 결과가 아니라 약어를 인용하는 사람들에 의해 리뷰에서 막힙니다. 긴장은 어떤 일관성은 수백 명의 엔지니어가 조율하는 데 정말 도움이 되므로 모든 원칙을 선택 사항으로 선언할 수는 없다는 점입니다. 원칙을 글자 그대로 따르다 더 나쁜 설계가 나온 사례와, 있다면 어떤 경계나 추상화가 왜 존재하는지 설명하는 결정 기록을 가져오십시오. 원칙은 기록된 이유와 함께 엔지니어가 벗어날 수 있는 기본값이라는 데 합의하고, 중대한 설계 선택을 짧은 아키텍처 결정 기록에 담아 다음 팀이 코드만이 아니라 이유를 물려받게 하십시오. 원 작성자가 오래전에 떠나고 감사가 시스템이 왜 이런 모양인지 묻는 기업과 공공 부문 시스템에서, 그 서면 흔적은 미래의 팀이 안전하게 바꿀 수 있는 설계와 건드리기 두려운 설계의 차이입니다.
분야별 관점
스타트업. 출시하는 가장 단순한 설계를 선호하고, 진짜 두 번째 사용 사례가 이음매를 강제할 때까지 잘 분해된 하나의 모듈을 유지하십시오. 가장 희소한 자원은 엔지니어링 주의이니, 성급한 인터페이스, 계층, 추측성 프레임워크는 순수한 비용입니다. 공유 추상화를 추출하기 전에 세 번의 규칙을 따르고, 아직 아무도 요청하지 않은 확장 지점은 YAGNI가 죽이게 하십시오.
소기업. 상주 아키텍트도 없고 예산도 빠듯하니, 자체 패턴을 발명하기보다 구매하는 프레임워크와 라이브러리에 이미 구워진 설계에 의지하십시오. 맞춤 설계 노력은 진정으로 비즈니스인 소수의 규칙에 남겨 두고, 나머지는 모두 관례적으로 유지하여 계약자나 신규 입사자가 읽을 수 있게 하십시오. 이해하는 약간의 중복이 작성자만 유지할 수 있는 영리한 추상화보다 낫습니다.
대기업. 공유된 원칙의 수익은 많은 팀에 걸친 조율입니다. 설계 리뷰를 위한 공통 어휘, 그리고 모델 경계를 팀 소유권과 맞춰 그룹이 독립적으로 진화하게 하는 경계 컨텍스트입니다. 의존성과 동시 변경 데이터로 결합도와 응집도를 명시적으로 관리하고, 중대한 설계 결정을 기록하여 작성자가 떠난 뒤에도 시스템이 변경 가능하게 유지되도록 하십시오. 팀을 결합시키는 잘못된 추상화와 모든 독자에게 세금을 매기는 과설계를 똑같이 경계하십시오.
정부. 감사 가능성과 재현 가능성이 설계를 좌우하는 경우가 많습니다. 불변의 함수형 핵심은 어떤 기간에 대한 과거 계산을 정확히 재현하게 해 주지만, 숨은 가변 상태가 있는 뒤엉킨 객체 그래프는 그것을 보장할 수 없습니다. 컨텍스트 경계에서는 공유 테이블보다 명시적으로 공개된 계약을 선호하고, 설계와 그 결정 기록을 감사자와 10년 뒤 시스템을 물려받을 어느 팀이든 읽을 수 있게 유지하십시오.
사례
스타트업. 첫 제품을 만드는 세 명 규모의 스타트업은 모든 기능을 인터페이스와 팩토리의 계층으로 쪼개려는 충동에 저항하고, 진짜 두 번째 사용 사례가 나타날 때까지 잘 분해된 하나의 모듈을 유지합니다. 같은 로직이 가입과 청구 흐름에서 세 번째로 나타나자 추측성 프레임워크가 아니라 작은 공유 함수 하나를 추출합니다. 이는 코드베이스를 누구든 머릿속에 담을 수 있을 만큼 작게 유지하고, 그들이 긋는 소수의 이음매는 제품이 가장 바뀔 법한 곳에 놓입니다.
대기업. 대형 보험 플랫폼이 정책, 청구, 결제를 각각 전담 팀이 소유하는 별개의 경계 컨텍스트로 모델링하며, 각 컨텍스트에는 고유한 데이터 모델과 서비스 경계가 있습니다. 청구가 정책을 참조하는 것처럼 컨텍스트가 만나는 곳에서는 공유 데이터베이스 테이블이 아니라 명시적으로 공개된 계약을 통해 대화합니다. 덕분에 세 팀이 독립적으로 진화할 수 있고, 유비쿼터스 언어는 보험 인수 담당자 및 계리사와의 대화를 정확하게 유지합니다. 이전 버전은 널리 퍼진 단일 모델을 공유했고, 모든 변경이 팀 간 조율을 필요로 했습니다.
정부. 국가 세금 처리 시스템은 계산 엔진에 대해 데이터 지향의 함수형 핵심을 의도적으로 선호합니다. 세금 규칙은 불변의 입력 레코드에 대한 순수 변환으로 표현되어, 감사 가능하고, 테스트 가능하고, 주어진 과세 연도에 재현 가능합니다. 명령형이고 상태가 있는 부분(워크플로, 알림)은 가장자리에 둡니다. 감사자는 특정 규칙 버전을 가리키고 과거의 어떤 계산이든 정확히 재현할 수 있으며, 이는 숨은 가변 상태가 있는 뒤엉킨 객체 그래프가 보장할 수 없는 법적 요건입니다.
비즈니스 사례: 동기, ROI, TCO
설계 품질은 시스템의 변경 가능성에 대한 투자이며, 변경 가능성이 총소유비용을 지배합니다. 시스템 비용의 대부분은 첫 릴리스 이후 수정과 확장에서 발생합니다. 잘 설계된 시스템은 변경 비용을 시간이 지나도 대략 일정하게 유지합니다. 잘못 설계된 시스템은 시스템이 사실상 수정 불가능해져 재작성해야 할 때까지 각 변경의 비용이 오르며, 이는 모든 것 중 가장 비싼 결과입니다.
도입 비용은 주로 기술과 리뷰 규율입니다. 원칙을 가르치고 설계 시간을 앞서 쓰는 것입니다. 도입하지 않는 비용은 기술 부채의 느린 축적, 떨어지는 전달 속도, 오르는 결함률, 결국의 값비싼 재작성입니다. 리더십을 설득하려면 설계 규율을 전달 예측 가능성과 재작성 프로그램 회피에 연결하고, 변경 실패율과 비슷한 기능을 구현하는 시간 같은 선행 지표를 시간에 따라 추적하십시오. 반대 실패도 경계하십시오. 불확실한 미래를 위해 설계에 과투자하는 것도 가치를 파괴합니다. 그러니 논거는 미래 변경이 얼마나 일어날 법하고 얼마나 비싼지에 맞춘 적절한 설계에 있습니다.
안티패턴과 함정
- 추측성 일반화: 오지 않을 상상의 요구사항을 위한 확장성을 구축하는 것.
- 잘못된 추상화: DRY를 만족시키려고 관련 없는 코드를 억지로 합쳐 중복보다 나쁜 결합을 만드는 것.
- 패턴 화물 숭배: 이득 없는 간접화를 더하며 디자인 패턴을 그 자체로 적용하는 것.
- 빈약한 또는 갓 오브젝트: 동작이 없는 모델이나 모든 것을 하는 객체. 둘 다 잘못 놓인 책임을 알립니다.
- 분산 모놀리스: 물리적으로 쪼개졌지만 여전히 긴밀히 결합된 서비스로, 두 접근의 비용을 모두 겹친 것.
- 진흙 덩어리: 식별 가능한 구조가 없어 모든 변경이 모든 것을 위험에 빠뜨립니다.
- DDD 연극: 가치를 주는 도메인 모델링 없이 어휘와 폴더 구조만 채택하는 것.
성숙도 모델
- 1단계, 시작: 설계가 그때그때 이루어지고 반응적입니다. 결합이 통제 없이 쌓이고, 원칙은 알려지지 않았거나 구호로 인용되며, 추상화는 개인의 습관에 따라 나타났다 사라집니다.
- 2단계, 발전: 팀이 원칙을 알고 적용하지만 일관되지 않고 흔히 교조적입니다. 일부 그룹은 결합도와 응집도를 의도적으로 관리하고 다른 그룹은 그렇지 않으며, 조직 전체에 공유 어휘가 없습니다.
- 3단계, 표준화: 공유된 설계 어휘, 추상화 추출을 위한 세 번의 규칙, 결합도와 응집도 분석, 팀에 정렬된 경계 컨텍스트가 문서화되어 조직 전체에서 기대되며, 개인의 취향에 맡기지 않고 설계 리뷰에서 일관되게 적용됩니다.
- 4단계, 관리: 설계 건강이 기준선에 대해 측정됩니다. 결합도와 동시 변경 데이터, 변경 실패율, 비슷한 기능을 구현하는 시간이 시간에 따라 추적되어, 추상화와 경계가 증거에 따라 추가되고, 유지되고, 제거되며, 과설계와 잘못된 추상화는 의견이 아니라 데이터로 포착됩니다.
- 5단계, 오케스트레이션: 설계 규율이 조직 전반에서 전달 및 위험 계획과 통합됩니다. 원칙은 뉘앙스와 알려진 실패 양상과 함께 적용되고, 패러다임과 경계 선택은 의도적이며 지속적으로 다시 살펴지고, 조직은 도메인과 증거가 변함에 따라 추상화를 일상적으로 리팩터링하고, 범위를 다시 정하고, 폐기합니다.
논의를 위한 아이디어
- 미래의 요구사항을 갖기 전에 필요한 이음매와 추측성 일반화를 어떻게 구분합니까?
- DRY가 팀을 잘못된 추상화로 이끈 것은 언제였으며, 어떻게 알아챘습니까?
- 경계 컨텍스트 경계는 어디에 놓여야 하며, 조직도를 얼마나 가깝게 본떠야 합니까?
- 여러분의 맥락에서 코드에 앞서 설계는 얼마나 있어야 하며, 결정은 어떻게 기록합니까?
- 시스템의 어느 부분이 더 함수형이거나 데이터 지향적인 스타일의 덕을 보겠습니까?
- 설계 원칙이 실용적 예외에 저항하는 교조로 굳는 것을 어떻게 막습니까?
핵심 요점
- 중요한 속성은 결합도와 응집도입니다. 약어는 그 목적을 위한 수단입니다.
- 모든 원칙에는 실패 양상이 있습니다. 각각이 언제 오도하는지 아십시오.
- 성급하거나 잘못된 추상화보다 약간의 중복을 선호하십시오.
- 복잡한 도메인을 팀 소유권과 정렬하려면 DDD와 경계 컨텍스트를 쓰십시오.
- 적합성으로 패러다임을 고르십시오. 큰 시스템은 실용적으로 혼합되어 있습니다.
- 실제로 필요한 변경을 위해 설계하고, 설계 부족과 과설계를 모두 피하십시오.
참고 문헌과 더 읽을거리
- Robert C. Martin, Clean Architecture and Agile Software Development, Principles, Patterns, and Practices
- Eric Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software
- Vaughn Vernon, Implementing Domain-Driven Design
- Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software
- Martin Fowler, Refactoring: Improving the Design of Existing Code and Patterns of Enterprise Application Architecture
- David L. Parnas, On the Criteria to Be Used in Decomposing Systems into Modules
- Sandi Metz, Practical Object-Oriented Design