소프트웨어 설계 원칙 (Design Principles)
소프트웨어 설계 원칙 (Design Principles) 은 소프트웨어 및 시스템 설계의 근간이 되는 원칙으로, 시스템의 구조와 품질을 결정하는 데 중요한 역할을 한다. 이러한 원칙들은 유지보수성, 확장성, 성능, 보안 등을 향상시키기 위해 설계 단계에서부터 고려되어야 하며, SOLID, DRY, KISS, YAGNI 등의 원칙들이 포함된다. 이러한 원칙들을 이해하고 적용함으로써 고품질의 소프트웨어를 개발할 수 있다.
핵심 개념
소프트웨어 설계 원칙은 소프트웨어 시스템을 설계할 때 따라야 하는 지침과 규칙의 집합으로, 시스템의 품질과 유지보수성을 향상시키는 데 목적이 있다.
기본 개념:
- 설계 원칙 (Design Principles): 소프트웨어 품질 향상을 위한 검증된 가이드라인
- 느슨한 결합 (Loose Coupling): 모듈 간 의존성을 최소화하는 설계 방식
- 높은 응집도 (High Cohesion): 모듈 내부 요소들이 밀접하게 관련된 설계
- 관심사의 분리 (Separation of Concerns): 서로 다른 기능을 별도 모듈로 분리
심화 개념 - 추상화 (Abstraction): 복잡성을 숨기고 필수 요소만 노출
- 캡슐화 (Encapsulation): 데이터와 메서드를 하나의 단위로 묶어 정보 은닉
- 다형성 (Polymorphism): 같은 인터페이스로 다양한 구현체 사용
- 의존성 주입 (Dependency Injection): 외부에서 의존성을 주입하여 결합도 감소
이러한 개념들을 바탕으로 주요 원칙들은 아래와 같다:
- SOLID 원칙:
- 단일 책임 원칙 (Single Responsibility Principle): 클래스는 하나의 책임만 가져야 한다.
- 개방 - 폐쇄 원칙 (Open/Closed Principle): 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 한다.
- 리스코프 치환 원칙 (Liskov Substitution Principle): 하위 클래스는 상위 클래스의 기능을 대체할 수 있어야 한다.
- 인터페이스 분리 원칙 (Interface Segregation Principle): 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하지 않아야 한다.
- 의존 역전 원칙 (Dependency Inversion Principle): 고수준 모듈은 저수준 모듈에 의존해서는 안 되며, 추상화에 의존해야 한다.
- DRY(Don’t Repeat Yourself): 중복을 피하고, 재사용 가능한 코드를 작성해야 한다.
- KISS(Keep It Simple, Stupid): 설계를 단순하게 유지해야 한다.
- YAGNI(You Aren’t Gonna Need It): 현재 필요하지 않은 기능은 구현하지 않아야 한다.
배경
Design Principles 는 소프트웨어 개발 과정에서 반복적으로 발생하는 문제들을 해결하기 위해 개발된 원칙들이다. 1970 년대부터 시작된 구조적 프로그래밍, 1980 년대의 객체지향 프로그래밍 등의 발전과 함께 형성되었으며, 특히 1990 년대 Robert Martin(Uncle Bob) 의 SOLID 원칙과 Gang of Four 의 디자인 패턴이 현대적 형태의 기초를 확립했다.
목적 및 필요성
소프트웨어 설계 원칙의 목적은 다음과 같다:
- 유지보수성 향상: 코드의 가독성과 이해도를 높여 유지보수를 용이하게 한다.
- 확장성 확보: 변화하는 요구사항에 유연하게 대응할 수 있도록 한다.
- 재사용성 증대: 모듈화된 설계를 통해 코드의 재사용성을 높인다.
- 품질 향상: 버그를 줄이고, 안정적인 소프트웨어를 개발할 수 있다.
주요 기능 및 역할
설계 원칙은 다음과 같은 역할을 한다:
- 구조화: 시스템을 명확한 구조로 설계하여 이해도를 높인다.
- 표준화: 개발 팀 내에서 일관된 설계 방식을 유지한다.
- 의사소통: 설계에 대한 명확한 기준을 제공하여 팀원 간의 의사소통을 원활하게 한다.
특징
- 보편성: 프로그래밍 언어와 플랫폼에 독립적
- 상호보완성: 여러 원칙들이 함께 적용될 때 시너지 효과
- 점진적 적용: 프로젝트 규모와 복잡도에 따른 단계적 적용 가능
- 경험 기반: 수십 년간의 개발 경험에서 도출된 실용적 지침
핵심 원칙
SOLID 원칙
원칙 | 설명 | 목적 및 효과 | 관련 개념/패턴 |
---|---|---|---|
SRP(Single Responsibility Principle) | 클래스나 모듈은 단 하나의 책임만 가져야 한다. | 응집도 향상, 변경 용이성 증가 | 응집도, 모듈화, 리팩토링 |
OCP(Open/Closed Principle) | 확장에는 열려 있고, 변경에는 닫혀 있어야 한다. | 기존 코드를 수정하지 않고 새로운 기능 추가 가능 | 상속, 전략 패턴, 템플릿 메서드 |
LSP(Liskov Substitution Principle) | 자식 클래스는 부모 클래스의 기능을 대체할 수 있어야 한다. | 다형성 보장, 신뢰할 수 있는 상속 구조 | 인터페이스, 추상 클래스 |
ISP(Interface Segregation Principle) | 클라이언트가 사용하지 않는 인터페이스에 의존하지 않아야 한다. | 불필요한 결합 방지, 인터페이스 최소화 | 인터페이스 설계, 분리 |
DIP(Dependency Inversion Principle) | 고수준 모듈은 저수준 모듈에 의존하지 않고, 둘 다 추상화에 의존해야 한다. | 결합도 감소, 유연한 아키텍처 | DI (의존성 주입), 인터페이스 |
기타 핵심 원칙
원칙 | 설명 | 목적 및 효과 | 관련 개념/패턴 |
---|---|---|---|
SoC(Separation of Concerns) | 관심사 (기능) 를 분리하여 각각 독립적으로 관리 | 코드 가독성, 유지보수성 향상 | 레이어드 아키텍처, 모듈화 |
DRY(Don’t Repeat Yourself) | 동일한 로직은 중복하지 말고 재사용하라 | 유지보수 용이성, 오류 감소 | 함수화, 유틸리티 모듈 |
KISS(Keep It Simple, Stupid) | 단순하고 명확하게 설계하라 | 복잡도 감소, 버그 발생 확률 최소화 | 최소 구현, 명확한 책임 |
YAGNI(You Ain’t Gonna Need It) | 당장 필요하지 않은 기능은 구현하지 마라 | 낭비 제거, 설계 복잡도 감소 | 애자일, Lean 개발 |
Law of Demeter(LoD) | 객체는 자신과 밀접한 객체와만 상호작용해야 한다 | 낮은 결합도 유지 | 메시지 전달, 캡슐화 |
Composition over Inheritance | 상속보다 객체 합성을 통해 기능을 확장 | 유연성 확보, 상속 트리 복잡도 감소 | 전략 패턴, 데코레이터 패턴 |
Convention over Configuration | 명시적 설정보다 관례 기반 기본값 사용 | 개발 생산성 향상, 설정 최소화 | Rails, Spring Boot, NestJS |
graph TB subgraph "Design Principles" subgraph "필수 구성요소" A1[SOLID 원칙] A2[DRY 원칙] A3[KISS 원칙] end subgraph "선택적 구성요소" B1[YAGNI 원칙] B2[Law of Demeter] B3[Composition over Inheritance] B4[Convention over Configuration] end subgraph "적용 계층" C1[클래스 레벨] C2[모듈 레벨] C3[시스템 레벨] end subgraph "품질 속성" D1[유지보수성] D2[확장성] D3[재사용성] D4[테스트 용이성] end end A1 --> C1 A1 --> C2 A2 --> C1 A2 --> C2 A3 --> C1 A3 --> C2 A3 --> C3 B1 --> C2 B1 --> C3 B2 --> C1 B3 --> C1 B3 --> C2 B4 --> C3 C1 --> D1 C1 --> D4 C2 --> D2 C2 --> D3 C3 --> D1 C3 --> D2
장점과 단점
구분 | 항목 | 설명 |
---|---|---|
✅ 장점 | 유지보수성 향상 | 체계적인 구조로 인한 코드 수정 용이성 |
확장성 보장 | 새로운 기능 추가 시 기존 코드 영향 최소화 | |
재사용성 증대 | 모듈화된 컴포넌트의 다양한 프로젝트 활용 | |
팀 협업 효율성 | 일관된 설계 기준으로 인한 의사소통 향상 | |
테스트 용이성 | 분리된 관심사로 인한 단위 테스트 작성 편의 | |
⚠ 단점 | 초기 개발 시간 증가 | 설계 단계에서의 추가 시간 투자 필요 |
과도한 추상화 위험 | 불필요한 복잡성 증가 가능성 | |
성능 오버헤드 | 추상화 계층으로 인한 런타임 성능 저하 | |
학습 곡선 | 개발자의 원칙 이해와 적용을 위한 학습 시간 | |
원칙 간 상충 | 서로 다른 원칙들 간의 트레이드오프 발생 |
분류에 따른 종류 및 유형
분류 | 원칙 | 주요 특징 | 적용 범위 |
---|---|---|---|
객체지향 설계 | SOLID 원칙 | 클래스와 모듈 설계 지침 | 클래스/모듈 레벨 |
Law of Demeter | 결합도 최소화 | 클래스 간 상호작용 | |
Composition over Inheritance | 유연한 코드 구조 | 클래스 설계 | |
코드 품질 | DRY | 중복 제거 | 전체 코드베이스 |
KISS | 단순성 유지 | 전체 설계 | |
YAGNI | 필요한 기능만 구현 | 기능 개발 | |
아키텍처 설계 | Separation of Concerns | 관심사 분리 | 시스템 아키텍처 |
Loose Coupling | 모듈 간 독립성 | 컴포넌트 설계 | |
High Cohesion | 모듈 내 응집도 | 모듈 설계 | |
개발 프로세스 | Convention over Configuration | 관례 우선 설정 | 프레임워크 설계 |
Principle of Least Astonishment | 예측 가능한 동작 | 인터페이스 설계 |
실무 적용 예시
산업 분야 | 적용 사례 | 설명 |
---|---|---|
전자상거래 | 단일 책임 원칙 (SRP) | 주문 처리, 결제, 배송 등을 각각의 서비스로 분리하여 유지보수성을 향상시킴 |
금융 | 개방 - 폐쇄 원칙 (OCP) | 새로운 금융 상품 추가 시 기존 코드를 수정하지 않고 기능을 확장 |
헬스케어 | 인터페이스 분리 원칙 (ISP) | 의료 기록 조회, 수정, 삭제 기능을 별도의 인터페이스로 분리 |
게임 개발 | 리스코프 치환 원칙 (LSP) | 다양한 캐릭터 클래스가 동일한 방식으로 동작하도록 설계 |
활용 사례
사례 1: 쇼핑몰 백엔드 시스템 설계
시나리오: 쇼핑몰 플랫폼의 주문 처리 시스템은 다양한 외부 서비스와 연동되며 빠르게 변경되는 비즈니스 요구에 따라 확장되어야 함.
사용된 설계 원칙:
- SRP: 주문 도메인을 주문 처리, 결제 처리, 배송 처리로 분리
- OCP: 새로운 결제 수단 추가 시 기존 클래스 수정 없이 새로운 클래스 추가
- DIP: 의존성 주입을 통해 상위 모듈과 하위 모듈 간 의존성 분리
시스템 구성 다이어그램:
graph TD A[OrderController] --> B[OrderService] B --> C["PaymentProcessor (interface)"] C --> D[PayPalService] C --> E[StripeService] B --> F[ShippingService]
Workflow:
- 사용자가 주문을 요청 → OrderController
- OrderService 는 주문 처리 후 인터페이스에 따라 결제 요청
- 결제 수단에 따라 해당 구현체 호출
- 결제 완료 후 배송 서비스 호출
설계 원칙 역할:
- SOLID 로 변경에 강하고 확장 가능한 구조 유지
- DIP 로 테스트 및 유지보수 용이
사례 2: 사용자 맞춤형 뉴스 피드 애플리케이션
시나리오: 한 스타트업이 사용자 맞춤형 뉴스 피드 애플리케이션을 개발하고자 한다. 이 애플리케이션은 다양한 뉴스 소스를 통합하고, 사용자의 관심사에 맞는 콘텐츠를 제공해야 한다.
적용된 설계 원칙:
- 단일 책임 원칙 (SRP): 뉴스 수집, 사용자 프로필 관리, 추천 알고리즘 등을 각각의 서비스로 분리
- 개방 - 폐쇄 원칙 (OCP): 새로운 뉴스 소스 추가 시 기존 코드를 수정하지 않고 확장 가능하도록 설계
- 의존 역전 원칙 (DIP): 뉴스 수집 서비스가 구체적인 뉴스 소스에 의존하지 않고, 추상화된 인터페이스에 의존하도록 설계
시스템 구성 다이어그램:
graph TD A[사용자 인터페이스] --> B[뉴스 추천 서비스] B --> C[뉴스 수집 서비스] B --> D[사용자 프로필 서비스] C --> E[뉴스 소스 API] D --> F[사용자 데이터베이스]
워크플로우:
- 사용자가 애플리케이션에 접속하여 뉴스 피드를 요청한다.
- 뉴스 추천 서비스는 사용자 프로필 서비스를 통해 관심사를 조회한다.
- 뉴스 수집 서비스는 다양한 뉴스 소스 API 를 통해 최신 뉴스를 수집한다.
- 뉴스 추천 서비스는 수집된 뉴스 중에서 사용자의 관심사에 맞는 콘텐츠를 선별하여 사용자에게 제공한다.
사례 3: 온라인 쇼핑몰 플랫폼 구축
시나리오: 온라인 쇼핑몰 플랫폼 구축
시스템 구성
graph TB subgraph "클라이언트 계층" A1[웹 클라이언트] A2[모바일 앱] A3[관리자 콘솔] end subgraph "API Gateway 계층" B1[API Gateway] B2[인증 서비스] B3[로드 밸런서] end subgraph "비즈니스 서비스 계층" C1[사용자 서비스] C2[상품 서비스] C3[주문 서비스] C4[결제 서비스] C5[배송 서비스] C6[알림 서비스] end subgraph "데이터 계층" D1[사용자 DB] D2[상품 DB] D3[주문 DB] D4[결제 DB] D5[Redis Cache] end subgraph "외부 서비스" E1[결제 게이트웨이] E2[배송 업체 API] E3[이메일 서비스] end A1 --> B1 A2 --> B1 A3 --> B1 B1 --> B2 B1 --> B3 B3 --> C1 B3 --> C2 B3 --> C3 B3 --> C4 B3 --> C5 B3 --> C6 C1 --> D1 C2 --> D2 C3 --> D3 C4 --> D4 C1 --> D5 C2 --> D5 C4 --> E1 C5 --> E2 C6 --> E3
적용된 Design Principles 와 역할:
Single Responsibility Principle (SRP)
- 각 마이크로서비스가 단일 비즈니스 기능 담당
- 사용자 서비스: 회원 관리만
- 주문 서비스: 주문 처리만
- 결제 서비스: 결제 처리만
Open/Closed Principle (OCP)
- API Gateway 를 통한 새로운 서비스 추가 용이
- 플러그인 방식의 결제 방법 확장
Dependency Inversion Principle (DIP)
- 서비스 간 직접 의존 대신 인터페이스 기반 통신
- 외부 서비스와의 느슨한 결합
Interface Segregation Principle (ISP)
- 클라이언트별 특화된 API 엔드포인트 제공
- 웹/모바일/관리자 전용 인터페이스 분리
Workflow:
sequenceDiagram participant Client as 클라이언트 participant Gateway as API Gateway participant Auth as 인증 서비스 participant Product as 상품 서비스 participant Order as 주문 서비스 participant Payment as 결제 서비스 participant Shipping as 배송 서비스 participant Notification as 알림 서비스 Client->>Gateway: 주문 요청 Gateway->>Auth: 인증 확인 Auth-->>Gateway: 인증 성공 Gateway->>Product: 상품 재고 확인 Product-->>Gateway: 재고 충분 Gateway->>Order: 주문 생성 Order-->>Gateway: 주문 ID 반환 Gateway->>Payment: 결제 처리 Payment->>Payment: 결제 검증 (KISS 원칙) Payment-->>Gateway: 결제 완료 Gateway->>Order: 주문 상태 업데이트 Order-->>Gateway: 업데이트 완료 Gateway->>Shipping: 배송 요청 Shipping-->>Gateway: 배송 등록 완료 Gateway->>Notification: 알림 발송 Notification-->>Gateway: 알림 전송 완료 Gateway-->>Client: 주문 완료 응답
실무 적용 시 고려사항 및 주의할 점
구분 | 고려사항 | 설명 | 권장사항 |
---|---|---|---|
계획 단계 | 점진적 도입 | 설계 원칙을 한 번에 도입하면 혼란과 거부감 발생 가능 | 핵심 원칙 (SOLID, DRY) 부터 시작해 점진적으로 확장 |
팀 역량 차이 | 팀 구성원 간 설계 원칙에 대한 이해도와 경험 차이 발생 | 정기 교육, 페어 프로그래밍, 코드 리뷰를 통해 정렬 | |
프로젝트 특성 고려 | MVP, 초기 스타트업 vs 장기 유지보수 시스템 등 요구사항이 다름 | 비즈니스 요구에 따라 설계 원칙 우선순위 조절 | |
설계 과잉 방지 | 과도한 추상화는 복잡도 증가 및 생산성 저하 초래 | 반복되는 패턴 발생 시에만 추상화 (3 회 법칙 적용) | |
설계 단계 | 모듈 경계 설정 | 명확한 책임 분할이 없으면 책임이 중첩되고 결합도가 상승함 | DDD(Domain-Driven Design) 또는 SRP 적용 |
인터페이스 정의 | 인터페이스가 지나치게 크거나 애매하면 응집도 저하 및 ISP 위반 | 작고 명확한 인터페이스 정의, Swagger 문서화 | |
추상화와 성능 균형 | 추상 계층 증가 → 성능 저하, 직관성 저하 | 핵심 기능은 최적화 고려, 성능 크리티컬 경로 점검 | |
통신 방식 결정 | 서비스 간 동기/비동기, REST/gRPC 등 선택이 설계에 큰 영향을 미침 | 서비스 특성 기반 통신 프로토콜 선택 (지연 민감도, 안정성 등) | |
구현 단계 | 코드 일관성 유지 | 개발자마다 설계 원칙 적용 방식이 다르면 유지보수 어려움 | Style Guide, SonarQube, Linter 도입 |
테스트 용이성 | DIP 적용 시 의존성 설정/모킹이 복잡할 수 있음 | IoC/DI 컨테이너, 테스트 프레임워크 적극 활용 | |
자동화 도구 활용 | 설계 원칙 준수 여부를 수동 검토하는 것은 비효율적임 | 정적 분석 도구 활용 (SonarQube, ESLint, etc.) | |
문서화 및 ADR 관리 | 설계 의도나 결정 근거가 사라지면 팀 단위 혼선 발생 | 아키텍처 결정 기록 (ADR) 및 인터페이스 문서화 | |
유지보수 단계 | 리팩토링 주기화 | 시간이 지날수록 원칙이 무너질 수 있음 | 리팩토링 전용 스프린트 또는 기술 부채 관리 시간 확보 |
모듈 책임 유지 | 유지보수 중 기능이 분산되거나 중첩되면 원칙 위반 | SRP 위반 시 즉시 리팩토링 또는 책임 재분배 | |
메트릭 기반 개선 | 설계 원칙이 실제로 효과적인지 판단 기준 필요 | 응집도/결합도 (CBO/LCOM), 순환 복잡도, 코드 커버리지 추적 | |
API/계약 안정성 유지 | 인터페이스 변경 시 다른 모듈/팀에 영향이 확산됨 | Contract Testing, API 버저닝 적용 |
- 도입은 단계별로, 핵심 원칙부터 시작해야 실무 적용이 효율적.
- 팀 내 일관성 유지와 자동화 도구 활용은 설계 품질을 장기적으로 유지하는 핵심 수단.
- 설계 원칙은 성능, 가독성, 생산성과의 균형 속에서 적용되어야 하며, 지나친 이상주의는 오히려 장애가 될 수 있다.
최적화하기 위한 고려사항 및 주의할 점
다음은 **설계 원칙 (Design Principles)**을 적용할 때 실무에서 성능을 최적화하기 위한 고려사항 및 주의할 점을 중복 없이 통합·정리한 표입니다. 이 표는 설계 최적화, 런타임 최적화, 운영 환경 모니터링까지 전체 개발 생애주기를 아우르는 관점에서 구성되어 있습니다.
🚀 성능을 최적화하기 위한 고려사항 및 주의할 점
구분 | 고려사항 | 상세 설명 | 권장사항 |
---|---|---|---|
설계 최적화 | 불필요한 추상화 제거 | 과도한 추상 계층은 호출 비용 증가 및 디버깅 어려움 발생 | 성능 중요 경로는 직접 호출, 추상화는 반복 패턴 발생 시 적용 |
계층 최소화 | 지나친 레이어드 아키텍처는 처리 시간 증가 | 계층 수 최소화 및 Hot Path 는 단순 설계 | |
모듈 분리 범위 조정 | 과도한 모듈화는 인터페이스 호출 오버헤드 발생 | 응집도를 기준으로 기능 단위 분리 | |
객체 생성 최적화 | 매번 객체 생성 시 GC(Garbage Collection) 부하 발생 | 객체 풀링, 싱글턴, 플라이웨이트 패턴 사용 | |
의존성 주입 방식 | DI 컨테이너 사용 시 런타임 의존성 해석 비용 존재 | 컴파일 타임 DI 또는 Lazy Injection 적용 | |
런타임 최적화 | 다형성 비용 최소화 | 동적 디스패치로 인한 런타임 비용 증가 | Hot Path 는 정적 디스패치 또는 단일 구현 선택 |
비동기 처리 | 대량의 요청이 직렬 처리될 경우 병목 발생 가능 | Kafka, RabbitMQ 등 메시지 기반 비동기 처리 활용 | |
캐싱 전략 | 반복 요청 시 불필요한 DB 접근 또는 계산 수행 | Redis, Local Cache, TTL 정책 적용 | |
데이터 접근 최적화 | 반복적 DB 호출 및 N+1 문제는 성능 저하의 주요 원인 | 배치 로딩, 쿼리 튜닝, Eager vs Lazy 로딩 전략 활용 | |
재사용 vs 단순성 균형 | 재사용을 위한 과도한 일반화는 Hot Path 성능 저하 유발 | 성능 중심 기능은 중복을 감수하더라도 단순하게 설계 | |
모니터링 및 운영 | 성능 프로파일링 | 추상적 최적화는 오히려 성능 악화 가능, 실제 병목 지점 식별 필요 | APM (Application Performance Monitoring) 도구 사용 |
벤치마킹/테스트 | 설계 변경 전후의 성능을 정량적으로 비교해야 신뢰도 확보 가능 | JMeter, Locust, k6 등으로 벤치마킹 수행 | |
지속적 모니터링 | 운영 환경에서는 데이터 크기/트래픽 변화에 따라 성능 저하 가능성 있음 | Prometheus, Grafana, CloudWatch 등 활용 | |
문서화 및 기술 부채 관리 | 성능 이슈로 인해 원칙을 완화한 부분은 누락되면 장기적으로 유지보수 난이도 증가 | 성능 예외 설계는 ADR(Architectural Decision Record) 로 기록 |
- 성능 중심 설계에서는 단순화, 직접 호출, 최소 추상화가 유리.
- **Hot Path(성능 핵심 경로)**와 일반 경로의 설계 기준은 분리되어야 하며, 가독성과 설계 원칙보다 실제 성능 우선 전략이 필요할 수 있다.
- 설계 원칙은 절대 법칙이 아닌 지침이며, 성능 병목이 예상되거나 확인된 부분에서는 선택적으로 설계 원칙을 완화하는 것이 실무적이다.
주제와 관련하여 주목할 내용
주제 | 항목 | 설명 |
---|---|---|
디자인 패턴 | Gang of Four 패턴 | 23 가지 고전 패턴의 현대적 적용 |
아키텍처 패턴 | MVC, MVP, MVVM, Clean Architecture | |
엔터프라이즈 패턴 | 마틴 파울러의 엔터프라이즈 애플리케이션 패턴 | |
개발 방법론 | 애자일 개발 | 스크럼, 칸반에서의 원칙 적용 |
TDD/BDD | 테스트 주도 개발과 행위 주도 개발 | |
익스트림 프로그래밍 | XP 의 핵심 관행들 | |
코드 품질 | 정적 분석 | 코드 복잡도, 중복도 측정 |
기술 부채 관리 | 원칙 위반으로 인한 부채 관리 | |
리팩토링 기법 | 마틴 파울러의 리팩토링 카탈로그 | |
아키텍처 | 마이크로서비스 | 분산 시스템에서의 원칙 적용 |
헥사고날 아키텍처 | 포트와 어댑터 패턴 | |
이벤트 기반 아키텍처 | 느슨한 결합을 위한 이벤트 활용 | |
최신 기술 | 클라우드 네이티브 | 컨테이너와 쿠버네티스 환경 |
서버리스 | FaaS 에서의 설계 고려사항 | |
DevOps | CI/CD 와 인프라스트럭처 as Code |
추가 학습 주제 정리
카테고리 | 주제 | 설명 |
---|---|---|
객체지향 설계 (OOP) | SOLID 원칙 | 객체지향 설계를 위한 다섯 가지 핵심 원칙 (SRP, OCP, LSP, ISP, DIP) |
GRASP 원칙 | 객체 책임 할당에 대한 일반적인 설계 패턴 (Creator, Controller 등) | |
디자인 스멜 | 유지보수에 악영향을 미치는 잘못된 설계 징후 (ex. God Class, Shotgun Surgery) | |
리팩토링 패턴 | 코드 품질 향상을 위한 반복 가능한 개선 기법 | |
함수형 프로그래밍 | 순수 함수 | 외부 상태에 영향을 주지 않고 입력만으로 결과를 반환하는 함수 |
불변성 (Immutability) | 상태 변경을 피하는 안정적인 설계 원칙 | |
모나드 (Monad) 패턴 | 함수 조합과 에러 처리 등을 위한 고급 함수형 프로그래밍 구조 | |
설계 패턴 | GoF 디자인 패턴 | 객체 생성, 구조, 행위 관련 23 가지 디자인 패턴 (Factory, Strategy 등) |
컴포지션 vs 상속 | " 상속보다는 구성 " 원칙으로 유연성과 테스트 용이성을 확보하는 방식 | |
아키텍처 스타일 | 클린 아키텍처 / 헥사고날 / Onion | 계층 분리, 의존성 역전, 테스트 가능성 중심의 현대 소프트웨어 설계 구조 |
마이크로서비스 아키텍처 | 독립적 배포 및 확장을 지원하는 서비스 중심 아키텍처 | |
성능 최적화 | 설계 기반 성능 튜닝 | 설계 시점에서 추상화/계층 구조의 성능 영향을 고려 |
프로파일링 및 병목 분석 | 런타임 병목 지점을 도구 기반으로 식별하여 최적화 | |
테스트 전략 | TDD (Test-Driven Development) | 테스트 주도 개발: 테스트를 먼저 작성하고 그에 맞춰 코드를 작성 |
DDD (Domain-Driven Design) | 도메인 지식에 기반한 복잡한 비즈니스 로직 중심 설계 전략 | |
동시성 설계 | 이벤트 루프 / Non-blocking I/O | 비동기 프로그래밍 모델 (Node.js, asyncio 등) |
Actor 모델 | 메시지 기반 동시성 구조 (Akka, Erlang 등) | |
락 프리/무잠금 프로그래밍 | 병목 없이 동시성 보장하는 알고리즘 (CAS, atomic operation 등) | |
분산 시스템 | CAP 이론 | Consistency, Availability, Partition Tolerance 사이의 트레이드오프 이해 |
SAGA 패턴 | 분산 환경에서의 롱런 트랜잭션 처리를 위한 보상 메커니즘 | |
CQRS (Command Query Responsibility Segregation) | 명령과 조회의 책임을 분리한 확장성 중심 설계 |
용어 | 설명 |
---|---|
ACID | 트랜잭션의 원자성 (Atomicity), 일관성 (Consistency), 격리성 (Isolation), 지속성 (Durability) 을 보장하는 특성 |
CI/CD | 지속적 통합 (Continuous Integration) 및 지속적 배포 (Continuous Delivery) 를 위한 자동화 파이프라인 |
MVC (Model-View-Controller) | 사용자 인터페이스를 세 계층으로 나누어 설계하는 디자인 패턴 |
리팩토링 (Refactoring) | 기능 변경 없이 코드의 구조를 개선하여 유지보수성을 향상시키는 작업 |
모킹 (Mock) | 테스트를 위해 실제 객체 대신 사용하는 가짜 객체 |
클린 아키텍처 | 계층 간 의존성과 관심사를 분리하고, 내부 도메인을 중심으로 설계하는 아키텍처 스타일 |
결합도 (Coupling) | 모듈 간 상호 의존성의 강도 (낮을수록 유지보수성 향상) |
응집도 (Cohesion) | 모듈 내부 구성 요소들의 관련성과 집중도 (높을수록 품질 향상) |
추상화 (Abstraction) | 시스템의 복잡성을 줄이기 위해 핵심 개념만을 표현하는 설계 기법 |
다형성 (Polymorphism) | 하나의 인터페이스로 다양한 객체 타입을 처리할 수 있는 특성 |
기술 부채 (Technical Debt) | 빠른 개발을 위해 품질을 희생한 결과로 향후 발생할 유지보수 비용 |
코드 스멜 (Code Smell) | 유지보수가 어려운 구조적 결함의 징후 (e.g., 긴 메서드, 중복 코드 등) |
관심사의 분리 (Separation of Concerns) | 서로 다른 책임 또는 기능을 모듈화하여 유지보수를 쉽게 하는 설계 원칙 |
인터페이스 (Interface) | 객체 간 상호작용을 정의하는 명세 또는 계약 (계약 기반 설계의 핵심 요소) |
참고 및 출처
🔷 설계 원칙 및 일반 개념
- Martin Fowler - Design Principles
- GeeksforGeeks: Principles of Software Design
- Wikipedia: Software Design
- Wikipedia: SOLID
- LinkedIn: Software Engineering Principles
- Swimm: 6 Software Design Principles Used by Successful Engineers
- Medium: 9 Popular Software Design Principles
- Scalastic: SOLID, DRY, KISS 등 설계 원칙 정리
- Boldare: DRY, KISS, YAGNI 설명
- Essential Software Design Principles – DesignGurus
🔷 객체지향 고급 개념
- Law of Demeter - Wikipedia
- Law of Demeter in Java – GeeksforGeeks
- Composition over Inheritance - Wikipedia
- Composition vs Inheritance – ArjanCodes
🔷 클린 아키텍처 및 프레임워크
- Clean Architecture by Robert C. Martin – O’Reilly
- AWS Well-Architected Framework - Design Principles
- Google Engineering Practices Guide
- Microsoft Azure Architecture Center
- ThoughtWorks Technology Radar
🔷 아키텍처 및 패턴
- Educative: Software Architecture Diagramming and Patterns
- Red Hat: 14 Software Architecture Design Patterns
- TutorialsPoint: Software Architecture Design Principles
- LinkedIn: Component Design Principles
- ICTWorks: Updated Principles for Digital Development