✅ 1. 개체 무결성(Entity Integrity)

비유: 주민등록번호는 꼭 있어야 하고, 중복되면 안 돼!

  • 뜻: 기본키(Primary Key)는 반드시 있어야 하고, 겹치면 안 된다는 규칙이야.
  • 예시:
    학생 테이블이 있어. 모든 학생은 학번이 있어야 해.
    • 학번이 없는 학생 ❌ → 누군지 알 수 없으니 안 됨
    • 학번이 중복된 학생 ❌ → 두 명을 구분할 수 없으니 안 됨

✅ 2. 참조 무결성(Referential Integrity)

비유: 없는 부모 밑에 자식이 있을 수는 없어!

  • 참조 무결성은 말 그대로 참조하는 값이 무결(깨끗하고 정확)해야 한다는 뜻이다.
    즉, "외래키(Foreign Key)"가 가리키는 값이 실제로 존재해야 한다는 규칙이다.

쉽게 말하면,

“내가 누군가를 참조한다고 할 때, 그 사람이 진짜 존재하지 않으면 문제가 생긴다.
데이터베이스도 마찬가지다.
A 테이블에서 -> B 테이블의 데이터를 참조할 때,
그 값이 B 테이블에 실제로 있어야 참조할 수 있다.
없는데 참조하면 그건 오류다.


📦 예시 테이블

🎓 학과 테이블 (부모 테이블, 원본)

학과코드 학과명
CS 컴퓨터공학
EE 전자공학
 

🧑‍🎓 학생 테이블 (자식 테이블, 참조자)

학번 이름 학과코드(외래키)
101 철수 CS
102 영희 EE
103 민수 ME ❌ ← 이게 문제다!
 

🚨 무슨 문제가 생긴 걸까?

학생 테이블에서 학과코드가 외래키다.
근데 민수는 ‘ME’라는 학과에 속해 있다고 적혀 있다.
그런데 학과 테이블에는 ‘ME’라는 코드가 없다.
이렇게 되면 존재하지 않는 학과를 참조하는 거라서 오류가 생긴다.
이걸 참조 무결성 위반이라고 부른다.


🧩해결 방법은?

참조 무결성을 지키려면,
외래키 값은 반드시 부모 테이블(참조 대상)에 존재해야 한다.
그래서 아래 둘 중 하나를 해야 한다.

  1. 부모 테이블에 ‘ME’ 학과를 추가한다
    → 학생이 실제 존재하는 학과를 참조하게 된다
  2. 학생 테이블에서 민수의 학과코드를 ‘CS’나 ‘EE’처럼 존재하는 값으로 바꾼다
    → 잘못된 참조를 없앤다

✅ 3. 속성 무결성(Domain/Attribute Integrity)

비유: 이름란에는 숫자를 쓰면 안 되잖아!

  • 뜻: 각 칼럼(속성)에 들어갈 자료형과 조건(지정된 규칙)을 지켜야 한다는 규칙이야.
  • 주요기법 : 체크CHECK, NULL/NOT NULL, 기본값(DEFAULT)
  • 예시:
    • 나이는 숫자만, 이름은 문자열만
    • 급여는 0보다 커야 함 (음수 ❌)
    • 빈칸으로 두면 안됨(not null)
    • 기본값을 자동으로 채워줌(default)
    • 입력 값이 특정 범위나 조건을 만족해야만 저장되게 하는 조건(check)

✅ 4. 사용자 정의 무결성(User-defined Integrity)

비유: 우리 회사만의 사규나 룰 같은 것!

  • 뜻: 사용자가 직접 정의한 조건이야. 시스템 기본 규칙 외에 특정 조직/서비스에서만 필요한 규칙을 의미해.
  • 예시:
    • 직원 급여는 반드시 200만 원 이상이어야 함
    • 상품 재고는 0 이상이어야 함
    • 주문은 한 번에 5개까지만 가능
    • 특정 조건일 때 자동 실행되는 코드로 무결성 체크(Trigger)

✅ 5. 키 무결성(Key Integrity)

비유: 내가 가진 열쇠(키)는 문을 여는 유일한 수단이야!

  • 뜻: 테이블 내에서 각 행(row)을 고유하게 식별할 수 있는 키(기본키 또는 후보키)는 반드시 유일해야 한다는 규칙이다.
  • 키 무결성은 말 그대로 ‘키는 무결해야 한다’, 즉 꼭 있어야 하고, 중복되면 안 된다는 규칙이다.
    데이터베이스에서 ‘키’는 각 행(데이터 한 줄)을 고유하게 구별하는 역할을 한다.
    그래서 이 키가 중복되거나 없으면, 누가 누구인지 구분이 안 되니까 큰 문제가 생긴다.
  • 예시:
    • 사원 번호가 101인 사람이 여러 명이면 ❌
    • 주민등록번호가 중복되면 ❌

📌 어떤 키가 해당될까?

  • 기본키(Primary Key)
    → 대표 키. 무조건 중복 X / NULL X
  • 후보키(Candidate Key)
    → 기본키가 될 수 있는 후보. 마찬가지로 유일해야 한다.
  • 슈퍼키(Super Key)
    → 유일하게 구분 가능한 모든 키 조합들 (후보키 포함)

🎁 한눈에 보기 요약표

개체 무결성 기본키는 반드시 있고, 겹치면 안 돼! 학번 중복 ❌, 학번 없음 ❌
참조 무결성 외래키는 반드시 존재하는 값이어야 해! 없는 학과 번호 ❌
속성 무결성 각 칼럼의 데이터는 규칙을 따라야 해! 나이에 문자 ❌, 급여 음수 ❌
사용자 정의 우리 조직만의 특별 규칙! 급여 ≥ 200만 원, 재고 ≥ 0
키 무결성 모든 키는 유일해야 해! 주민번호 중복 ❌

 

 

✅ 1. 유스케이스 다이어그램이란?

시스템이 사용자를 위해 어떤 기능을 제공하는지사용자 관점에서 시각적으로 보여주는 다이어그램이다.
즉, “누가 시스템을 이용해서 어떤 행동을 할 수 있는지”를 기능 중심으로 정리한 그림.


1) 구성요소

  • 액터 / 유스케이스 / 시스템 / 시나리오 / 이벤트의 흐름

    구성 요소 기호 설명
    액터
    (Actor)
    👤 (사람 그림) 시스템을 사용(수행)하는 사람 또는 외부 시스템. 주로 사람(고객, 관리자 등)
    유스케이스
    (Use Case)
    ⭕ 타원 액터가 시스템을 통해 수행할 수 있는 기능 또는 행위
    시스템
    (System)
    ▭ 사각형 박스 내가 만들거나 설명하려는 서비스 또는 앱 전체 (전체 시스템의 영역 표현)
    관계
    (Association)
    ― 실선 액터와 유스케이스 간의 연결선 (사용 관계), 또는 유스케이스들 간의 포함/확장 관계

2) 쉬운 비유

🎡 유스케이스 다이어그램은 놀이공원 안내도라고 생각해보자.

  • 🎟️ 놀이공원(시스템) 안에는
  • 👧 방문객(액터)
  • 🎠 롤러코스터, 회전목마(유스케이스) 를 타는 것처럼,
  • 어떤 기능을 누가 쓸 수 있는지를 그림으로 표현한다.

3) 유스케이스 간의 관계

 

관계 표기 설명 예시
Include
(포함)
<<include>> 공통 기능을 다른 유스케이스가 반드시 포함해서 쓸 때 결제하기 ← <<include>> ← 상품 구매
Extend
(확장)
<<extend>> 기본 유스케이스에 특정 조건적으로 추가 또는 확장 기능 배송 옵션 선택 ← <<extend>> ← 결제하기
Generalization
(일반화)
빈 삼각형 화살표 추상적인 액터와 좀 더 구체적인 액터 사이에 맺어주는 관계. 하위 액터에서 상위 액터 쪽으로 실선으로 연결 일반회원, 고객 ▶ VIP회원
 

 시퀀스 다이어그램이란?

객체 간의 동적 상호작용시간 순서대로 시각화한 다이어그램

 

1) 개념

  • 객체 간 상호 작용 메시지 흐름으로 표현한 다이어그램
  • 객체 간 동적 상호 작용시간적 개념을 중심으로 모델링하는 과정이다.
  • 객체의 오퍼레이션과 속성을 상세히 정의해야 한다.
  • 유스케이스를 실현(Realization)한다.
객체 간 상호 작용 시스템 안의 여러 객체들이 서로 “대화”하듯 요청하고 응답함.
예: 로그인할 때 User가 LoginService에 요청하고, LoginService는 DB에 물어봄.
메시지 흐름 객체가 서로 어떤 메서드(함수)를 호출하거나 데이터를 주고받는 순서를 표현함.
동적 모델링 객체가 “시간 흐름 속에서 어떻게 반응하고 변화하는지”를 시각화함.
즉, 정적인 구조가 아니라 행동 중심의 모델링
시간 개념 중심 위 → 아래로 시간이 흐름. 먼저 일어난 일은 위, 나중에 일어난 일은 아래.
오퍼레이션 & 속성 정의 필요 어떤 객체가 어떤 기능(메서드)과 어떤 상태(속성)를 갖고 있는지를 잘 정의해야 정확한 흐름을 그릴 수 있음.
유스케이스 실현(Realization) 유스케이스 다이어그램이 말하는 “무엇을 한다”는 기능을
시퀀스 다이어그램에서 “어떻게 동작하는가”로 풀어내는 과정

2) 구성 요소

  • 객체 / 생명선 / 실행 / 메시지
구성 요소 기호
객체
(Object)
▭ 네모 박스 상단에 이름:클래스명 형식 메시지를 주고받는 주체. 시나리오에 등장하는 모든 역할
생명선
(Lifeline)
객체 아래로 내려오는 점선 해당 객체가 살아 있는 시간. 메시지를 받을 수 있는 상태를 나타냄
활성 구간
(Activation)
생명선 위에 생기는 세로 네모(막대) 객체가 일을 처리 중인 시간
메시지를 받고 실행 중인 상태
메시지
(Message)
→ 실선 화살표 (요청)
← 점선 화살표 (응답)
객체 사이에 주고받는 요청/응답 또는 메서드 호출

🧠 예시로 이해하기: ‘상품 주문’ 시나리오

🛒 유스케이스 다이어그램에서는 단순히:

  • 고객 → 상품 주문 (고객이 상품 주문을 한다.)

하지만 시퀀스 다이어그램에서는 실제 흐름을 이렇게 보여준다.

Customer → OrderController : 상품 주문 요청
OrderController → OrderService : 주문 처리 요청
OrderService → Inventory : 재고 확인
Inventory → OrderService : 재고 있음
OrderService → PaymentService : 결제 요청
PaymentService → BankAPI : 카드 승인
BankAPI → PaymentService : 승인 완료
PaymentService → OrderService : 결제 완료
OrderService → OrderRepository : 주문 저장
OrderService → OrderController : 주문 완료 응답
OrderController → Customer : 주문 성공 메시지
 

📌 이 예시에서 메시지 하나하나가 객체 간 메서드 호출 흐름이다.
**객체의 오퍼레이션(동작)**과 **속성(주문 정보, 재고 상태 등)**이 제대로 정의되어 있어야 정확하고 유용한 시퀀스 다이어그램이 되는 것이다.

 

한 문장으로 요약하자면,

시퀀스 다이어그램은 객체들이 유스케이스를 실현하기 위해 어떤 메시지를 시간 순서대로 주고받는지 시각적으로 표현한 것이다.
이걸 통해 시스템 내부 동작을 더 명확하게 설계하거나 설명할 수 있다.

 

🧠  또 다른 시각 예시

user:User         loginCtrol:LoginController     svc:LoginService
   |                         |                          |
   | ───── login(id, pw) ──>|                          |  // 메시지 (요청)
   |                         | ───── authenticate() ──>|
   |                         | <──── true/false ───────|  // 응답 (점선 화살표)
   | <──── 로그인 결과 ─────|                          |

 

 3) 언제, 왜 쓰는가?

상황 설명
백엔드 기능 설계 사용자 요청이 서버 내부에서 어떻게 흐르는지 알고 싶을 때
복잡한 API 흐름 설명 여러 객체가 서로 요청/응답을 주고받을 때 누구와 먼저 소통하는지 파악할 때
디버깅 또는 로직 확인 순서가 중요한 시점에서 잘못된 흐름을 추적할 때 유용

📄 시퀀스 vs 유스케이스 비교

항목 유스케이스 시퀀스
목적 사용자와 기능 연결 기능 내부의 실행 흐름
관점 “무엇을 하느냐” “어떻게 실행되느냐”
시간 흐름 없음 있음
예시 “상품 주문 가능” “주문할 때 어떤 객체들이 순서대로 동작하는가”

 활동 다이어그램이란?

1) 개념

  • 시스템 또는 업무의 전체 작업 흐름(프로세스)을 시각적으로 표현한 다이어그램이다.
  • 흐름도(flow chart)처럼, “이 일이 끝나면 그다음엔 뭐하지?” 를 한눈에 보여주는 그림.
  • 즉, 조건 분기, 반복, 병렬 실행 같은 흐름을 표현해서 시스템이 어떤 순서로 동작하는지 알려준다.

 

2) 구성요소

  • 시작점 / 전이 / 액션(액티비티) / 조건(판단)노드 / 병합노드 / 포크노드 / 조인노드 / 구획면

구성 요소 기호 / 모양 설명 쉬운 비유

구성 요소 기호 설명
시작점(Initial Node) ● (검은 동그라미) 활동의 시작을 표현
하나의 다이어그램 안에는 하나의 시작점만 존재
액션/액티비티(Activity) ▭ (둥근 사각형) 어떠한 일들의 처리와 실행을 표현
전이(Transition) → (화살표) 작업 간 순서를 나타냄(실행의 흐름을 나타냄)
조건(판단)노드(Decision Node) ◆ (마름모) 조건에 따라 흐름 분리를 표현
들어오는 제어 흐름은 한 개이고,
나가는 제어 흐름은 여러 개로 표현
병합 노드(Merge Node) ◆ (마름모) 분기된 흐름을 다시 합침
들어오는 제어 흐름은 여러 개,
나가는 제어 흐름은 한 개로 표현
포크노드(Fork Node) 굵은 가로선 평행적으로 수행되는 흐름을 나누는 노드.
들어오는 액티비티 흐름은 한개,
나가는 액티비티 흐름은 여러개
조인노드(Join Node) 굵은 가로선 포크 노드로 나눠진 흐름을 다시 하나로 합치는 노드.
들어오는 액티비티 흐름은 여러개.
나가는 액티비티 흐름은 한개.
종료점(Final Node) ◎(검은색 동그라미를 포함한 원) 처리의 종료 표현
하나의 다이어그램 안에는 여러 개의 종료 노드가 있을 수 있음

3) 언제, 왜 쓰는가?

사용 상황 설명
프로세스를 정리하고 싶을 때 회원가입, 주문, 로그인 등 절차가 있는 기능
기획자/개발자/디자이너 간 공유용 시스템 흐름을 누구나 쉽게 이해할 수 있게 시각화
복잡한 조건이나 분기 로직 설명 시 if-else, 반복문, 병렬처리 등 설명할 때 매우 유용

 

📄 활동 vs 시퀀스 비교

항목 활동 다이어그램 시퀀스 다이어그램
무엇을 보여주는가? 작업(행동)의 전체 흐름 객체 간 메시지 주고받는 순서
관심 초점 프로세스, 조건, 분기, 반복 객체 간 상호작용(요청과 응답)
시간 흐름 흐름 방향 기반 (→) 위 → 아래로 시간 흐름 명확
사용자 중심 vs 객체 중심 사용자 중심 시스템 내부 객체 중심
활용 시점 초기 프로세스 기획 / 업무 흐름 도식화 기능 상세 설계, 로직 구현 이해

 


상태 다이어그램이란?

1) 개념

  • 하나의 객체가 자신이 속한 클래스의 상태 변화 혹은 다른 객체와의 상호 작용에 따라 상태가 어떻게 변화하는지 표현하는 다이어그램이다.
  • 어떤 이벤트에 의해 객체 자신이 속한 클래스의 상태 변화나 객체 간 상호 작용하는 과정에서의 상태 변화를 표현한다.
  • 객체의 상태란 객체가 갖는 속성값의 변화이다.

즉, 어떤 객체가 시간이 지나면서, 또는 누군가의 행동(이벤트)에 의해 상태가 어떻게 바뀌는지를 보여주는 그림

용어 설명
객체 프로그램 안에서 살아 움직이는 ‘주인공’ 역할. 예: 사용자, 주문, 문 등
클래스의 상태 변화 클래스(설계도)에 따라 만들어진 객체가 가지고 있는 속성 값이 달라지는 것
예: 주문 상태가 "결제 전" → "결제 완료"로 바뀜
다른 객체와의 상호작용 외부에서 이벤트(예: 버튼 클릭, 메시지 수신 등)가 발생했을 때, 객체가 반응해서 상태를 바꿈
이벤트(Event) 상태를 바꾸는 ‘신호’ 또는 ‘행동’. 예: "로그인 시도", "배송 시작", "타이머 종료" 등
상태(State) 현재 객체가 처한 "모드"나 "상태값". 예: “로그인 전”, “로그인됨”, “오류 상태”

📦 예시로 이해하기: ‘주문 객체’

📍 객체: Order

이 객체는 다음과 같은 상태를 가질 수 있다.

  • Order의 상태(state) = "결제 전" → "결제 완료" → "배송 중" → "배송 완료"

📍 각 상태는 객체의 속성값이라고 생각하면 된다.
즉, 주문 객체의 status 속성이 "결제 전" → "배송 중"으로 바뀌는 것!

📍 그리고 이 상태 변화는 언제 일어나냐면?

  • 이벤트(Event)가 발생할 때!
    • 사용자가 "결제하기" 버튼 클릭 → 상태가 "결제 전" → "결제 완료"로 변함
    • 택배사가 배송 시작 → "결제 완료" → "배송 중"

📌 이 상태의 변화를 시간 순서대로, 화살표로 표현한 게 바로 상태 다이어그램이다~

요약

상태 다이어그램이란? 객체가 어떤 상태에 있다가 어떤 이벤트로 상태가 바뀌는지 그린 그림
객체의 상태란? 객체가 갖는 속성값(예: 주문 상태, 로그인 여부 등)
상태가 바뀌는 이유? 클래스 내부 로직, 또는 외부 이벤트/상호작용 때문
무엇에 유용한가? 기기 상태, 로그인 상태, 주문 처리, UI 화면 전환 등 "상태 중심 시스템" 설계에 아주 유용
 

2) 구성 요소

  • 상태 / 시작 상태 / 종료 상태 / 전이 /이벤트 / 전이 조건
구성요소 기호 설명 예시
시작 상태 ● (검은 동그라미) 상태 다이어그램의 시작점 “처음 상태”
상태 (State) 🟦 둥근 사각형 객체가 놓이는 하나의 “상태” “로그인 대기”, “결제 대기”
이벤트 (Event) 상태 전이 화살표 위 텍스트 상태를 바꾸는 ‘신호’, 조건 “로그인 버튼 클릭”, “타이머 종료”
상태 전이 (Transition) → (화살표) 한 상태에서 다른 상태로 넘어가는 경로 “A 상태 → B 상태”
종료 상태 ⏹ (검은 원 속에 흰 원) 객체가 더 이상 활동하지 않는 마지막 상태 “종료됨”

 

✅ 커뮤니케이션 다이어그램이란?

1) 개념

  • 객체 간의 메시지 흐름과 연결 관계를 함께 시각화한 다이어그램이다.
  • 시퀀스 다이어그램과 비슷하지만, 커뮤니케이션 다이어그램은 '시간 + 구조(연결)'에 모두 초점을 둔다.
  • 즉, 메시지뿐만 아니라 객체 간의 연관까지 표현하는 다이어그램이다.

2) 비유하자면

단체 채팅방에서 여러 사람이 주고받는 대화를 생각해보자.

  • 누가 누구에게 말했는지 (연결 관계)
  • 어떤 순서로 말이 오갔는지 (메시지 순서)
    이 두 가지를 동시에 보는 것임.

📌 시퀀스 다이어그램이 “누가 언제 말했는가”에 집중한다면,
📌 커뮤니케이션 다이어그램은 “누가 누구와 말했는가”에 더 집중한다.

 

3) 구성요소

  • 액터 / 객체 / 링크 / 메시지
구성 요소 기호 설명 예시
객체(Object) ▭ 박스
콜론(:)기준으로 앞쪽에는 객체명,
뒤쪽에는 클래스명 기술
메시지를 주고받는 대상. 클래스의 인스턴스 단톡방에 있는 사람
링크(Link) ─ 실선 객체 간 연결 관계를 나타냄.
액터와 객체, 객체 간 실선으로 표현
링크에 메시지를 표현
대화선 또는 연락선
메시지(Message) 링크 위의 숫자 + 함수명
예: 1: login()
메시지 전달 순서와 내용을 표시 “1: 안녕”, “2: 잘 지내?”

 

📦 구조적 다이어그램 (Structural Diagrams) – ‘정지된 설계도’

1️⃣ 클래스 다이어그램 (Class Diagram)

  • 어원의 의미:  같은 성격끼리 분류한다는 뜻
  • 구성요소

 

구성 요소 설명
클래스
(Class)
객체를 생성하기 위한 청사진 역할을 한다. 공통 속성, 연산(메서드), 관계, 의미를 공유하는 실제 객체들의 집합이다.
속성
(Attribute)
클래스가 가지는 데이터를 나타낸다. 변수 형태로, 인스턴스별로 저장되는 값을 정의하며 name: Type 형태로 표기
연산
(Operation)
클래스가 수행할 수 있는 기능을 추상적으로 정의한다.매개변수와 반환 타입을 포함해 operation(params): ReturnType 형식으로 작성
메서드
(Method)
연산의 구현체로, 실제 코드 수준에서 동작하는 함수를 의미. 시퀀스 다이어그램 등에서 호출될 때 사용
접근 제어자
(Access Modifier)
클래스에 접근할 수 있는 접근 권한을 나타낸다.
+ : 클래스 외부 접근 허용(public)
- : 클래스 내부 접근만 허용(private)
# : 동일 패키지/파생 클래스에서 접근 가능(protected)
~ : 동일 패키지 클래스에서 접근 가능(default)
  • 클래스 간의 관계
관계 종류 정의 UML 표기법 실전 예시
연관
(Association)
클래스가 서로 개념적으로 연결된관계 실선 (ㅡ) Customer -------- Order: 고객이 주문을 관리한다
의존
(Dependency)
하나의 클래스가 또 다른 클래스를 사용하는 관계. 짧은 시간 동안만 연관을 유지. 점선 화살표 (--->) ReportGenerator -.-▶ DatabaseConnection: 보고서 생성 시 DB 연결을 일시적으로 사용
일반화
(Generalization)
상속 관계.하나의 사물이 다른 사물에 비해 더 일반적인지 구체적인지를 표현하는 관계. 일반적인 개념을 부모(상위)라 하고 구체적인 개념을 자식(하위)라고 함. 그래서 다른 의미로 상속 관계라고도 함.  “~은 ~이다”라는 ‘is‑a’ 관계를 나타낸다. 빈 삼각형 화살표 (--▷) Vehicle --▷ Car: 자동차는 차량이다
실체화
(Realization)
인터페이스 구현. 추상클래스나 인터페이스를 상속받아 자식 클래스가 추상 메서드를 구현할 때 사용하는 관계 점선 + 빈 삼각형 (-.▷) Comparable -.▷ Employee: 직원 객체가 비교 기능을 제공
포함
(Composition)
전체(Composite)가 부분(Component)를 강하게 소유하고, 전체가 소멸하면 부분도 함께 소멸됩니다. ‘전체는 부분을 관리한다’는 의미로, 부분의 라이프사이클이 전체에 종속됩니다.
강한 소유(집↔방). 포함하는 사물의 변화가 포함되는 사물에게 영향을 미치는 관계를 표현.
채워진 마름모 () Library ◆— Book: 도서관이 폐관하면 책도 관리 대상에서 사라짐
집합
(Aggregation)
전체가 부분을 느슨하게 묶어 둔 관계로, 부분은 전체와 독립적입니다. 부분의 라이프사이클은 전체와 무관하게 유지될 수 있습니다. 하나의 객체에 여러 개의 독립적인 객체들이 구성되는 관계. 하나의 사물이 다른 사물에 포함되어 있는 관계 표현. 빈 마름모 () Team ◇— Player: 팀이 해체되어도 선수 객체는 여전히 존재

 


2️⃣ 패키지 다이어그램 (Package Diagram)

    • 어원의 의미 : 관련 클래스를 묶음(패키지)
    • 구성요소
      • 패키지 / 의존 관계

1) 🌳 패키지 (Package) — 시스템을 정리하는 폴더

무엇을 나타내는가? 클래스, 인터페이스 등 여러 코드들을 관련 있는 것끼리 묶은 덩어리. 마치 컴퓨터에서 ‘음악’, ‘사진’ 폴더처럼
왜 쓰는가? 시스템이 커질수록 한눈에 보기가 어려움. 패키지로 묶으면 어떤 기능이 어디 있는지 보기 쉽고 유지보수도 편함.
어떻게 생겼나? 폴더처럼 생긴 아이콘에 이름을 붙여 사용한다. 보통 UML에서는 작은 탭이 달린 사각형으로 표현된다.
예시 예를 들어 쇼핑몰 시스템에
📁 OrderPkg → 주문 관련 클래스들
📁 PaymentPkg → 결제 관련 클래스들
📁 MemberPkg → 회원 관련 클래스들
 
  • 👉 정리하자면, **“패키지 = 시스템 기능별 정리 폴더”**

 

2) 🔗 의존 관계 (Dependency) — 다른 패키지의 기능을 잠깐 빌려 씀

무엇을 나타내는가? A 패키지가 B 패키지의 기능을 일시적으로 빌려서 사용할 때 나타내는 관계
표기법은? 점선 화살표(──▶) 로 나타내. 방향은 ‘빌려 쓰는 쪽 → 빌려지는 쪽’
왜 필요한가? “어떤 패키지가 다른 패키지의 기능에 의존한다”는 걸 알려줘서,
→ 누가 누구에게 영향을 주는지 쉽게 파악할 수 있어.
예시 📁 OrderPkg ──▶ PaymentPkg
→ 주문 기능은 결제 기능을 호출해서 사용함.
→ 결제 로직이 바뀌면 주문 쪽도 영향 받을 수 있음.
 
  • 👉 쉽게 말하면, “의존 = 빌려쓰기 관계”,
    “점선 화살표 = 이쪽이 저쪽 걸 잠깐 써요~” 라는 의미

3️⃣ 컴포넌트 다이어그램 (Component Diagram)

    • 어원의 의미: ‘componentem’(함께 놓인 요소) → 모듈 단위
    • 개념 : 시스템을 구성하는 큰 부품들(=컴포넌트)을 보여주는 다이어그램
    • 구성요소
      • 컴포넌트 / 인터페이스 / 의존 관계
구성 요소 쉽게 말하면 정의 및 설명 예시
컴포넌트
(Component)
시스템의 부품 프로그램에서 독립적으로 실행되거나 배포 가능한 덩어리. 보통 하나의 기능 단위. 📦 회원관리 서비스, 주문 처리 모듈, 결제 API
인터페이스
(Interface)
연결 포트 컴포넌트가 어떤 기능을 제공하거나 사용할 수 있는지 외부에 알려주는 연결점. 🔌 로그인 요청, 결제 승인, 상품 목록 가져오기
의존 관계
(Dependency)
빌려 씀 A 컴포넌트가 B 컴포넌트의 기능을 사용하려면, 점선 화살표로 연결함. 주문 컴포넌트 ─▶ 결제 컴포넌트

 

🧠 각각을 더 쉽게 풀어보면…

1) 📦 컴포넌트 (Component)

  • 프로그램의 기능을 담당하는 하나의 "덩어리"
  • 보통 하나의 .jar, .dll, .module 파일로 배포 가능
  • UML에서 직사각형 박스로 그리며, 좌상단에 두 개 겹친 작은 사각형 아이콘이 붙어 있음
     

2)🔌 인터페이스 (Interface)

  • 컴포넌트끼리 소통할 때 쓰는 “메뉴판” 같은 역할
  • 두 종류:
    • 제공 인터페이스 (Provided): 내가 제공하는 기능 → 원형 포트 ●
    • 요구 인터페이스 (Required): 내가 필요한 기능 → U자 모양 ⊃
  • 예시:
    • 결제 서비스는 결제 승인()이라는 기능을 제공 (Provided)
    • 주문 컴포넌트는 결제 승인()을 요구 (Required)

3)➰ 의존 관계 (Dependency)

  • 점선 화살표 ────▶
  • "이쪽 컴포넌트가 저쪽 기능을 잠깐 쓸 거예요~" 라는 의미
  • 예시:
    • OrderComponent ───▶ PaymentComponent

UML(Unified Modeling Language) 다이어그램은 소프트웨어 시스템을 시각적으로 표현하는 도구다.

크게 나누면 구조적(정적) 다이어그램행위적(동적) 다이어그램으로 나뉜다.


✅ 1. 구조적 다이어그램 (Structural Diagrams, aka 정적 다이어그램)

시스템의 **구조(구성 요소와 관계)**를 표현해. 즉, 클래스, 객체, 컴포넌트 등 **변하지 않는 부분(정적 측면)**을 그린 거야.

🔸 주요 다이어그램 종류: [클객 컴배 복패]

다이어그램설명 [클객 컴배 복패]

래스 다이어그램 클래스 간의 관계(상속, 연관, 집합 등)를 표현해. 가장 자주 쓰이는 다이어그램.
체 다이어그램 클래스 다이어그램의 인스턴스 상태를 나타냄. 객체와 그 관계를 보여줘.
포넌트 다이어그램 시스템을 구성하는 컴포넌트(모듈)의 구조와 의존 관계 표현.
치 다이어그램 하드웨어 환경에서 시스템이 어떻게 배치되는지 보여줘 (서버, 노드 등).
합 구조 다이어그램 객체 내부 구성요소와 포트를 나타냄. 클래스 내부 구조까지 세밀하게 표현.
키지 다이어그램 여러 클래스를 묶은 패키지 단위의 관계를 표현.
 

 

👉 구조적 다이어그램 = 어떤 부품들로 시스템이 만들어졌는지 보여줌


✅ 2. 행위적 다이어그램 (Behavioral Diagrams, aka 동적 다이어그램)

시스템의 **동작(행위)**과 시간에 따른 변화, 즉 프로세스 흐름과 객체의 상호작용을 표현해. 즉, 시스템이 어떻게 움직이는지를 보여줘.

🔸 주요 다이어그램 종류: [유시커 상활타]

다이어그램설명 [유시커 상활타]

스케이스 다이어그램 사용자(액터)와 시스템 간 상호작용을 시각화 (요구사항 분석 시 주로 사용).
퀀스 다이어그램 객체 간 메시지 교환 순서를 시간 순서대로 표현해 (누가 누구에게 어떤 메시지를 보냈는지).
뮤니케이션 다이어그램 객체 간 상호작용을 중심으로 연결 구조에 중점. 시퀀스보다 구조를 강조.
태 다이어그램 객체나 시스템의 상태 변화 과정을 표현해 (상태 → 이벤트 → 상태 전이).
동 다이어그램 워크플로우나 절차(로직) 흐름을 표현. if-else, 반복, 병렬 흐름 등 표현 가능.
타이밍 다이어그램 객체의 상태가 시간 축을 따라 어떻게 변하는지 보여줌. 임베디드 시스템 등에서 유용.
 

 

👉 행위적 다이어그램 = 시스템이 시간 흐름에 따라 어떻게 움직이는지 보여줌


🧠 정리: 구조 vs 행위

구분구조적 다이어그램행위적 다이어그램

 

구분 구조적 다이어그램 행위적 다이어그램
관점 시스템 구성 요소 중심 동작과 흐름 중심
시간적 변화 없음 (정적) 있음 (동적)
주요 내용 클래스, 객체, 컴포넌트, 배치 등 유스케이스, 시퀀스, 상태, 활동 등
목적 구성을 명확히 행위 흐름을 명확히

✅ 구조 패턴 (Structural Patterns) - 7가지

여러 객체나 클래스를 연결해서 더 큰 구조를 만들고, 유지보수가 쉬운 코드를 작성하게 도와주는 패턴.
코드를 더 유연하고, 확장성 있게 만들기 위한 설계 방식이라고 생각하면 된다.

  어댑터 패턴 (Adapter Pattern)

🧠 개념 요약

인터페이스(사용 방식)가 호환되지 않는 두 객체를 연결할 수 있게 해줌.

🎓 왜 쓰는가?

기존 코드를 수정하지 않고, 새 코드에 맞춰서 연결하고 싶을 때 사용한다.

🧃 비유

“220V 전자제품을 110V 콘센트에 꽂을 때 변환 어댑터 사용하는 것”

🔧 예시

// 기존 시스템은 MediaPlayer 인터페이스를 사용
interface MediaPlayer { void play(String fileName); }

// 새로운 시스템은 AdvancedPlayer만 지원
class Mp4Player {
    void playMp4(String fileName) { ... }
}

// 어댑터를 통해 둘을 연결
class MediaAdapter implements MediaPlayer {
    private Mp4Player player = new Mp4Player();
    void play(String fileName) { player.playMp4(fileName); }

  브리지 패턴 (Bridge Pattern)

🧠 개념 요약

**기능(추상화)**과 **구현(플랫폼)**을 분리해서 독립적으로 확장할 수 있게 해줌.

다시 말해, 기능(리모컨)과 플랫폼(TV)을 분리해서 따로 바꿀 수 있게 함

📘 Bridge의 어원부터 이해하기

Bridge = “다리를 놓다”, “연결하다”

→ 두 개의 독립된 영역 사이를 연결하는 다리 역할
즉, 기능(추상)과 구현(구체) 사이를 분리하고 연결하는 구조.

🎓 왜 쓰는가?

기능과 구현이 동시에 늘어날 경우, 상속보다 조합으로 처리하는 게 낫기 때문이야.

🧃 비유

리모컨을 여러 TV에 사용할 수 있고, TV도 여러 리모컨을 받을 수 있도록 설계

🔧 예시

// 1. 구현부 (실제 동작 - TV 종류별)
interface TV {
    void turnOn();  // 전원 켜기
    void turnOff(); // 전원 끄기
}

// 삼성 TV
class SamsungTV implements TV {
    public void turnOn() {
        System.out.println("🔵 삼성 TV 켜짐");
    }
    public void turnOff() {
        System.out.println("🔵 삼성 TV 꺼짐");
    }
}

// LG TV
class LGTV implements TV {
    public void turnOn() {
        System.out.println("🟢 LG TV 켜짐");
    }
    public void turnOff() {
        System.out.println("🟢 LG TV 꺼짐");
    }
}

// 2. 추상화 (리모컨 - 기능 제공)
abstract class RemoteControl {
    protected TV tv;  // 구현부와 연결되는 다리 (bridge!)

    RemoteControl(TV tv) {
        this.tv = tv;
    }

    abstract void pressPower(); // 리모컨 기능 정의
}

// 3. 구체 리모컨 (기능 확장 가능)
class BasicRemote extends RemoteControl {
    BasicRemote(TV tv) {
        super(tv);
    }

    void pressPower() {
        System.out.println("🔘 리모컨 전원 버튼 누름");
        tv.turnOn(); // 실제 TV의 켜기 실행
    }
}

-----------------------------------------------------------------------
// 삼성 TV에 리모컨 연결
TV samsung = new SamsungTV();
RemoteControl remote = new BasicRemote(samsung);
remote.pressPower();  // "삼성 TV 켜짐"

// LG TV로 교체해도 리모컨 코드는 그대로 사용 가능
remote = new BasicRemote(new LGTV());
remote.pressPower();  // "LG TV 켜짐"

  컴포지트 패턴 (Composite Pattern)

🧠 개념 요약

객체를 트리 구조로 만들어, 개별 객체와 복합 객체를 같은 방식으로 다룰 수 있게 해줌....

📘 Composite의 어원부터 이해하기

composite = com(함께) + posite(put, 놓다) → “함께 놓인 것”, “복합체”, “합성된 것”

즉, 여러 개의 구성 요소(부분)가 모여서 하나의 전체(복합체)를 이루는 구조를 의미한다.
→ 이 패턴 이름이 “부분-전체(Part-Whole)” 관계를 하나처럼 다룬다”는 뜻이다.

 

컴포지트 패턴 개별 객체(ex. 파일)와 그 객체들을 포함하는 그룹(ex. 폴더)을 동일한 방식으로 다루는 구조를 만드는 패턴이다.

 

예를 들면, 📂 폴더도 더블클릭해서 열리고, 📄 파일도 더블클릭해서 열잖아?
→ 둘 다 “열기(open)”라는 동일한 행동을 하는 객체처럼 다룰 수 있는 것,
이게 바로 “부분과 전체를 동일하게 다룬다”는 의미다!!

🔧 예시

// 공통 기능 정의: 파일이든 폴더든 "열기(open)" 가능해야 함
interface FileSystemItem {
    void open();  // 공통 인터페이스
}

// 리프 객체: 실제 파일
class File implements FileSystemItem {
    String name;

    File(String name) {
        this.name = name;
    }

    public void open() {
        System.out.println("📄 파일 열기: " + name);
    }
}

// 컴포지트 객체: 폴더 (안에 여러 개 아이템을 포함할 수 있음)
class Folder implements FileSystemItem {
    String name;
    List<FileSystemItem> items = new ArrayList<>();

    Folder(String name) {
        this.name = name;
    }

    // 폴더에 파일/폴더 추가
    public void add(FileSystemItem item) {
        items.add(item);
    }

    public void open() {
        System.out.println("📁 폴더 열기: " + name);
        for (FileSystemItem item : items) {
            item.open(); // 폴더 안의 모든 항목을 동일한 방식으로 열기!
        }
    }
}

  데코레이터 패턴 (Decorator Pattern)

📘 어원

decorate = 꾸미다, 장식하다
→ 기존 기능에 "장식처럼" 새 기능을 겹겹이 추가하는 패턴

🧠 개념 요약

기존 객체에 기능을 동적으로 추가할 수 있게 해줌. 상속없이 기능을 확장할 수 있다.

 

🎓 왜 쓰는가?

기능 조합을 동적으로 바꾸고 싶을 때 사용한다.

🧃 비유

“기본 커피에 휘핑, 시럽, 샷 추가 등 옵션을 조합해서 음료를 만드는 것”

🔧 예시

// 커피에 옵션 추가하기

// 커피 인터페이스 (공통 동작)
interface Coffee {
    String getDescription();
    int cost();
}

// 기본 커피 클래스
class BasicCoffee implements Coffee {
    public String getDescription() {
        return "기본 커피 ☕";
    }

    public int cost() {
        return 2000;
    }
}

// 데코레이터: 휘핑 추가
class WhipDecorator implements Coffee {
    private Coffee base;  // 안에 감싸는 기존 커피

    WhipDecorator(Coffee base) {
        this.base = base;
    }

    public String getDescription() {
        return base.getDescription() + " + 휘핑크림";
    }

    public int cost() {
        return base.cost() + 500;
    }
}

// 실제 사용
Coffee coffee = new BasicCoffee();
coffee = new WhipDecorator(coffee);
System.out.println(coffee.getDescription()); // 기본 커피 + 휘핑크림
System.out.println(coffee.cost()); // 2500

 퍼사드 패턴 (Facade Pattern)

📘 어원

facade = 건물의 "정면", 외관
→ 복잡한 내부를 감추고 간단한 외부 인터페이스만 제공하는 것

🧠 개념 요약

복잡한 서브시스템을 간단한 인터페이스 하나로 감싸는 패턴.
클라이언트는 내부 구조를 몰라도 됨.

🎓 왜 쓰는가?

외부에 복잡함을 숨기고, 간단하게 사용하도록 하기 위함.

🧃 비유

“리모컨 하나로 TV + 스피커 + 조명까지 모두 켜기”
→ 내부 동작은 복잡하지만, 사용자 입장에서는 버튼 하나

🔧 예시

// 컴퓨터 켜기
// 복잡한 내부 구성
class CPU {
    void start() { System.out.println("CPU 켜기"); }
}
class Memory {
    void load() { System.out.println("메모리 로딩"); }
}
class Disk {
    void spin() { System.out.println("디스크 회전"); }
}

// 퍼사드 클래스
class Computer {
    CPU cpu = new CPU();
    Memory memory = new Memory();
    Disk disk = new Disk();

    void startComputer() {
        cpu.start();
        memory.load();
        disk.spin();
    }
}

Computer myPC = new Computer();
myPC.startComputer();  // 버튼 하나로 모두 시작

 플라이웨이트 패턴 (Flyweight Pattern)

📘 어원

flyweight = "가볍다", 복싱에서 '라이트급 선수'
 가볍게 공유해서 메모리 아끼기

🧠 개념 요약

공통되는 데이터를 공유해서 메모리를 절약하는 패턴. 수많은 객체가 생성될 때 성능 최적화에 효과적.

🎓 왜 쓰는가?

메모리 사용량이 너무 많을 때, 동일한 부분은 공유해서 효율을 높임.

🧃비유

“게임에서 똑같은 나무를 1000개 그릴 때, 나무 모양은 공유하고 위치만 따로 저장”

🔧 예시

// 나무의 공통 정보 (공유됨)
class TreeType {
    String name;
    String texture;

    TreeType(String name, String texture) {
        this.name = name;
        this.texture = texture;
    }

    void draw(int x, int y) {
        System.out.println(name + " 나무를 " + x + "," + y + "에 그림");
    }
}

// 개별 나무는 위치만 다름
class Tree {
    int x, y;
    TreeType type; // 공유됨

    Tree(int x, int y, TreeType type) {
        this.x = x;
        this.y = y;
        this.type = type;
    }

    void draw() {
        type.draw(x, y);
    }
}

 


  프록시 패턴 (Proxy Pattern)

📘 어원

proxy = 대리인, 대리 처리자
→ 누군가 대신 처리해주는 객체

🧠 개념 요약

어떤 객체에 직접 접근하지 않고, 대리 객체(Proxy)를 통해 접근하도록 하는 패턴

🎓 왜 쓰는가?

  • 상황예시
    ❗ 접근 제한이 필요할 때 관리자만 접근 가능한 기능
    ❗ 실제 객체 생성을 늦춰야 할 때 무거운 파일, 대용량 이미지 등
    ❗ 네트워크/리소스를 줄이고 싶을 때 캐시 프록시, 로컬 대리

🧃 비유

1) 연예인 매니저

  • 연예인에게 직접 연락하는 건 어렵고, 매니저에게 연락해서 스케줄을 잡음
  • 매니저(Proxy)가 요청을 대신 받고, 내부적으로 연예인(Real Object)과 연결

2) 이미지 미리보기

  • 무거운 이미지 파일은 필요할 때만 로딩하고,
  • 미리보기에서는 프록시 객체가 대기하다가 실제 요청 시 이미지 로딩

🔧 예시

// 1. 진짜 이미지 클래스 (무거운 객체)
// 진짜 이미지: 로딩에 시간이 오래 걸림
class RealImage {
    String filename;

    RealImage(String filename) {
        this.filename = filename;
        System.out.println("📸 고화질 이미지를 로딩 중...: " + filename);
    }

    void display() {
        System.out.println("🖼️ 화면에 이미지 보여줌: " + filename);
    }
}
//설명
//생성자(RealImage 생성 시점)에서 이미지를 불러오는 무거운 작업 수행
//display()를 호출해야 이미지를 화면에 보여줌


------------------------------------------------------------------------------------
// 2. 프록시 이미지 클래스 (대리인 역할)
// 프록시 이미지: 진짜 이미지를 대신 관리
class ProxyImage {
    RealImage realImage;  // 실제 이미지를 담을 변수
    String filename;

    ProxyImage(String filename) {
        this.filename = filename;
    }

    void display() {
        // 이미지가 아직 로딩 안됐으면, 그때서야 로딩함!
        if (realImage == null) {
            realImage = new RealImage(filename);
        }

        // 진짜 이미지의 display() 호출
        realImage.display();
    }
}

//설명
//처음에는 realImage가 null이야 (아직 안 만들어짐!)
//display()를 호출하는 순간 → 진짜 이미지를 그때서야 생성
//이후부터는 기존에 만든 이미지로 바로 보여줌


public class Main {
    public static void main(String[] args) {
        System.out.println("1️⃣ ProxyImage 객체 생성 중...");
        ProxyImage image = new ProxyImage("cute-cat.jpg");

        System.out.println("\n2️⃣ 아직 display()를 안 했으니까 이미지 로딩 안 됨");

        System.out.println("\n3️⃣ 이제 display() 호출!");
        image.display();  // 여기서 처음으로 RealImage 생성됨

        System.out.println("\n4️⃣ 두 번째 display(): 이미지 재사용");
        image.display();  // 여기선 RealImage가 이미 있어서 바로 출력됨
    }
}
------------------------------------------------------------------------------------

 

Main함수 출력 결과

1️⃣ ProxyImage 객체 생성 중...

2️⃣ 아직 display()를 안 했으니까 이미지 로딩 안 됨

3️⃣ 이제 display() 호출!
📸 고화질 이미지를 로딩 중...: cute-cat.jpg
🖼️ 화면에 이미지 보여줌: cute-cat.jpg

4️⃣ 두 번째 display(): 이미지 재사용
🖼️ 화면에 이미지 보여줌: cute-cat.jpg

✅ 생성 패턴 (Creational Patterns) - 5가지

객체를 어떻게 생성할지, 생성 과정을 유연하고 재사용 가능하게 설계하는 패턴


① 빌더 패턴 (Builder Pattern)

🧠 개념 요약

복잡한 객체를 만들 때, 객체 생성 과정을 단계별로 나눠서 구성할 수 있게 해주는 패턴.
다양한 구성 요소를 조립해 하나의 객체를 만드는 데 유용.

🎓 왜 쓰는가?

생성자에 너무 많은 파라미터가 있는 경우 코드가 복잡해짐.
→ 이걸 build() 단계로 쪼개서 가독성을 높이고, 다양한 설정 조합을 쉽게 만들 수 있음.

🔧 예시

User user = new UserBuilder()
    .setName("Karina")
    .setAge(24)
    .setEmail("karina@aespa.com")
    .build();

🧃 비유

"햄버거 주문할 때 옵션 고르기"

  • 번: 기본
  • 패티: 소고기 or 치킨
  • 추가: 치즈, 피클, 베이컨 등
    → 조합해서 나만의 햄버거 만들기

②  프로토타입 패턴 (Prototype Pattern)

🧠 개념 요약

기존 객체를 복제(clone) 해서 새로운 객체를 만들 때 사용하는 패턴.
특히, 객체를 만드는 비용이 클 때 유용.

🎓 왜 쓰는가?

객체 생성이 복잡하거나 무겁다면, 하나 만들어 놓고 복사(clone)해서 쓰는 게 효율적임.

🔧 예시

Document doc1 = new Resume("Karina", "Singer");
Document doc2 = doc1.clone(); // 내용은 같지만 다른 객체
 

🧃 비유

"디자인 파일 복붙하기"

  • 이력서 템플릿 하나 만들어놓고, 이름/내용만 살짝 바꿔서 다른 지원서 만들기

③ 팩토리 메서드 패턴 (Factory Method Pattern)

🧠 개념 요약

객체 생성 코드를 서브 클래스에게 위임하는 패턴.
상위 클래스는 객체 생성 방식을 몰라도 됨.

🎓 왜 쓰는가?

객체 생성 코드를 캡슐화해서, 호출하는 쪽에서 어떤 구체 클래스가 만들어지는지 몰라도 사용 가능.

🔧 예시

abstract class Dialog {
    abstract Button createButton();
}

class WindowsDialog extends Dialog {
    Button createButton() { return new WindowsButton(); }
}

🧃 비유

"자판기에서 음료 뽑기"

  • 버튼만 누르면 내부에서 어떤 브랜드의 음료를 꺼내줄지는 몰라도 결과는 동일하게 음료가 나옴

④ 추상 팩토리 패턴 (Abstract Factory Pattern)

🧠 개념 요약

서로 관련 있는 객체들을 묶음으로 생성할 수 있게 해주는 패턴.
팩토리들을 생산하는 "슈퍼 팩토리"

🎓 왜 쓰는가?

여러 개의 관련 객체를 같은 테마나 환경에 맞게 구성할 때 사용함.
(예: 다크 모드 테마에는 어두운 버튼/배경/글씨)

🔧 예시

interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

class DarkModeFactory implements GUIFactory {
    Button createButton() { return new DarkButton(); }
    Checkbox createCheckbox() { return new DarkCheckbox(); }
}

🧃 비유

"스타일 세트로 제공되는 방 인테리어"

  • 북유럽 스타일: 테이블, 소파, 조명 모두 동일한 스타일로 구성됨

⑤ 싱글톤 패턴 (Singleton Pattern)

🧠 개념 요약

클래스의 객체를 오직 하나만 생성하도록 보장하고, 어디서든 그 인스턴스에 접근할 수 있게 함.

🎓 왜 쓰는가?

  • 전역 설정 관리
  • DB 연결 관리
  • 로그 시스템 등 "한 개만 존재해야 하는 객체"에 적합

🔧 예시

class Logger {
    private static Logger instance = new Logger();

    private Logger() {}

    public static Logger getInstance() {
        return instance;
    }
}

🧃 비유

"한 학교에 한 명뿐인 교장 선생님"

📌 1. 디자인 패턴이란?

🎯 개념:

- 소프트웨어 공학의 소프트웨어 설계에서 공통으로 발생하는 문제에 대해 자주 쓰이는 설계 방법을 정리한 패턴이다.
- 디자인 패턴을 참고하여 개발할 경우 개발의 효율성과 유지보수성, 운용성이 높아지며, 프로그램의 최적화에 도움이 된다.

🎯 정의 (쉽게 말하면):

프로그래머 선배들이 문제를 잘 해결했던 “방법 모음집”

  • 우리가 프로그램을 만들다 보면 비슷한 문제를 자주 만나게 된다.
  • 선배 개발자들이 “이럴 땐 이렇게 푸는 게 좋더라” 하고 정리해놓은 설계 방법이 바로 디자인 패턴이다.

🧠 일상 비유:

책장을 만들 때, 매번 설계도 없이 만들려면 시간도 오래 걸리고 어렵다.
이떼, 유명한 [책장 조립 설명서]가 있으면 쉽게 만들 수 있다.
디자인 패턴도 그런 소프트웨어 조립 설명서라고 보면 된다.


📚 2. 디자인 패턴의 3가지 큰 분류

디자인 패턴은 목적에 따라 다음 3가지로 나뉜다.

분류 개념 설명
생성 패턴
(Creational Pattern)
클래스나 객체의 생성과 참조 과정을 정의하는 패턴이다. 즉, 객체를 어떻게 만들지에 대한 패턴
구조 패턴
(Structural Pattern)
구조가 복잡한 시스템을 개발하기 쉽도록 클래스나 객체들을 조합하여 더 큰 구조로 만드는 패턴이다. 즉, 객체들을 어떻게 연결할지에 대한 패턴
행동 패턴
(Behavioral Pattern)
클래스나 객체들이 서로 상호 작용하는 방법과 역할 분담을 다루는 패턴이다. 즉, 객체들이 어떻게 협력할지에 대한 패턴

 

[☞ 생성패턴 공부하러 가기]

 

[정보처리기사 실기 이론] 디자인 패턴 유형 | 생성패턴(Creational Pattern)

✅ 생성 패턴 (Creational Patterns) - 5가지객체를 어떻게 생성할지, 생성 과정을 유연하고 재사용 가능하게 설계하는 패턴① 빌더 패턴 (Builder Pattern)🧠 개념 요약복잡한 객체를 만들 때, 객체 생성

whyjlee.tistory.com

 

[☞ 구조패턴 공부하러 가기]

 

[정보처리기사 실기 이론] 디자인 패턴 유형 | 구조패턴(Structural Pattern)

✅ 구조 패턴 (Structural Patterns) - 7가지여러 객체나 클래스를 연결해서 더 큰 구조를 만들고, 유지보수가 쉬운 코드를 작성하게 도와주는 패턴.코드를 더 유연하고, 확장성 있게 만들기 위한 설계

whyjlee.tistory.com

 

✅ 1. 계층화 패턴 (Layered Pattern)

설명

  • 기능을 계층별로 나눠서 각 계층이 자신의 역할만 담당하도록 구조화 시킨 패턴

쉽게 말하면

  • 학생 → 담임 선생님 → 교무실 → 행정실 순서로 일처리가 올라가고, 답도 역순으로 내려온다.

구조

    • 프레젠테이션 계층: 사용자와 직접 소통하는 부분 (예: 화면, 버튼)
    • 비즈니스 로직 계층: 규칙을 처리하는 곳 (예: 성적 계산)
    • 데이터 접근 계층: 데이터 저장/불러오는 곳 (예: 데이터베이스)

예제: 은행 앱

  • 사용자 인터페이스(UI): 계좌 조회 화면
  • 비즈니스 로직: 이체 가능 여부, 수수료 계산
  • 데이터 계층: 사용자 계좌 정보, 거래 내역 DB

✅ 2. 클라이언트-서버 패턴 (Client-Server Pattern)

  • 설명: 클라이언트가 요청하고, 서버가 응답하는 구조
  • 예제: 웹 브라우저와 웹사이트
    • 크롬(클라이언트)이 네이버에 접속하면, 서버가 홈페이지 HTML을 응답

✅ 3. 파이프-필터 패턴 (Pipe-Filter Pattern)

설명

  • 데이터를 단계별로 처리하는 구조 (필터들 사이에 파이프 연결)

쉽게 말해

  • 물이 필터를 거치면서 점점 깨끗해지는 것처럼, 데이터를 단계별로 처리한다.

구조

  • 필터(Filter): 데이터를 가공하는 작업 단위
  • 파이프(Pipe): 데이터를 다음 필터로 전달

예제: 음악 편집 소프트웨어

  • 잡음 제거 → 볼륨 조절 → 효과 추가 → 파일 저장

✅ 4. 브로커 패턴 (Broker Pattern)

설명

  • 클라이언트와 서버 사이에 중개자(브로커)가 있음

🔍 핵심 개념:

    • 말그대로 브로커 역할. "중간에서 연결해주는 중개인" 역할을 하는 구조
    • 클라이언트는 어떤 서비스를 원하고, 서버는 실제 일을 할 수 있는데, 서로 어디 있는지 몰라서 직접 연결할 수 없을 때, 브로커가 대신 연결해준다.

쉽게 말하면

  • 배달의 민족 같은 중개 앱을 생각해보면,
  • 고객(클라이언트)이 음식을 주문해
  • 가게(서버)는 음식을 만들지
  • 그런데 고객은 가게를 직접 찾거나 연결할 필요 없이,
    배달앱(브로커)이 알아서 중간에서 연결해줌
    • 보통 분산 시스템에서 많이 사용함.

🖧  왜 분산 시스템에 필요할까?

분산 시스템에서는 서버가 하나가 아니고 여러 개이다.
게다가 이 서버들은 다른 컴퓨터, 다른 지역에 흩어져 있을 수도 있다.
그런데 클라이언트가 매번 서버를 직접 찾거나 통신 방식까지 다 알아야 한다면? 너무 복잡하기 때문에 그래서!

 

브로커가 클라이언트와 서버 사이에서 이렇게 도와준다.

    • 서버 등록: "나 이 기능 할 수 있어!"
    • 클라이언트 요청: "이 기능 해줘!"
    • 연결 중개: "오키ㅋ 요청을 저 서버로 보내줄게!"

✅ 5. MVC 패턴 (Model-View-Controller)

  • 설명: 화면(View), 데이터(Model), 요청 처리(Controller)를 분리
  • 예제: 쇼핑몰 웹사이트
    • 상품 조회 → Controller가 요청 → Model에서 데이터 → View에 보여줌

✅ 6. 마스터-슬레이브 패턴 (Master-Slave Pattern)

  • 설명: 마스터가 전체 작업을 분할하고, 여러 슬레이브에게 나눠주어 처리시킴.
             슬레이브는 결과만 다시 마스터에게 보냄.
  • 예제: 데이터베이스 복제 시스템
    • Master DB: 데이터 입력, 변경 수행
    • Slave DB: 읽기 전용, 다수의 사용자 요청 처리에 활용
  • 예를 들어, 네이버 검색엔진이 수많은 사용자의 검색 요청을 슬레이브 DB에서 빠르게 응답함.

✅ 7. 피어 투 피어 패턴 (Peer-to-Peer Pattern)

  • 설명: 모든 컴퓨터가 동등한 위치에서 서로 데이터를 주고받음 (서버가 따로 없음)
  • 예제: 토렌트 다운로드 시스템
    • 누군가 파일을 가지고 있으면, 여러 사용자에게 동시에 전송 가능
    • 각각이 서버이자 클라이언트 역할을 동시에 함

✅ 8. 이벤트 버스 패턴 (Event-Bus Pattern)

  • 설명: 여러 컴포넌트가 이벤트를 주고받을 수 있도록 **중앙 통신 시스템(Event Bus)**을 둠
    송신자는 수신자를 몰라도 됨 (느슨한 결합)
  • 예제: Android 앱의 이벤트 처리
    • 버튼 클릭 → 이벤트 발생 → Event Bus가 리스너에게 전달
    • 대표 라이브러리: EventBus, RxJava

🔍 핵심 개념: ‘어디선가 이벤트가 발생하면, 그걸 듣고 있던 부품들이 알아서 반응하는 구조

 

💡 쉽게 말하면:

  • 학교에서 **교내 방송(이벤트)**을 틀었더니,
  • 어떤 반은 조용히 듣고,
  • 어떤 반은 조용히 앉고,
  • 어떤 반은 방송을 무시함 😅

즉, 방송을 모두가 듣고 있고,
필요한 애들만 필요한 반응을 하는 것.

 

앱 예시 : 카카오톡 메시지 수신 처리

  • 메시지가 도착했다는 이벤트가 발생하면,
    • 📱채팅창은 새 메시지를 화면에 보여주고
    • 🔔알림 센터는 푸시 알림을 띄우고
    • 📥저장 모듈은 메시지를 DB에 저장함

각각의 기능이 이벤트 버스를 통해 알림을 받아따로따로 처리하는 것이다.


✅ 9. 블랙보드 패턴 (Blackboard Pattern)

  • 설명: **여러 컴포넌트(전문가)**들이 하나의 공통 공간(블랙보드)에 접근하여 문제를 해결함
  • 예제: 각 컴포넌트는 블랙보드 상태를 보며 필요한 때에 동작함
  • 음성 인식 시스템
    • 음향 분석, 문맥 분석, 언어 처리 모듈이 각자 블랙보드에서 정보를 가져와 협업
  • 또 다른 예: AI 진단 시스템

🔍 핵심 개념:

 ‘모든 지식을 칠판(블랙보드)에 쓰고, 여러 전문가들이 거기서 정보를 가져와서 각자 해석하고 업데이트하는 구조’

 

💡 쉽게 말하면:

수학 문제를 칠판에 써놓고,

  • 한 학생은 문제를 읽고 숫자를 정리하고,
  • 다른 학생은 공식에 대입하고,
  • 또 다른 학생은 그래프를 그림
    → 결과를 다시 칠판에 써서 다음 사람이 이어받아 작업함

즉, 하나의 공간에 정보가 공유되고, 여러 모듈이 협력적으로 문제 해결을 해나가는 구조이다.

 

🧠 실제 예시:

음성 인식 시스템

  1. 🎤 마이크로 입력된 음성을 블랙보드에 올림
  2. 🔍 모듈1: 음성 → 단어 분리
  3. 🧠 모듈2: 단어 → 문장 해석
  4. 📄 모듈3: 문장 → 의미 분석
  5. 💬 최종 결과 출력

이런 시스템은 모듈끼리 직접 대화하지 않고, 블랙보드라는 공유 공간을 보고, 쓰고, 읽으면서 협력하는 방식이다.


✅ 10. 인터프리터 패턴 (Interpreter Pattern)

  • 설명: 언어나 문법 규칙을 가진 코드를 해석하고 실행하는 구조
  • 예제
  • SQL 파서
    • SELECT * FROM table WHERE age > 20; 이 문장을 해석하고 실행함
  • 정규표현식 엔진
    • 입력된 패턴을 해석해서 해당 문자열을 찾아줌

+ Recent posts