디자인 패턴 소개
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 85번째.
디자인 패턴은 소프트웨어 설계에서 발생하는 일반적인 문제에 대한 재사용 가능한 해결책입니다. 디자인 패턴은 그대로 복사하는 코드가 아니라, 특정 과제를 해결하기 위해 타입과 타입 간 상호작용을 구성하는 방법을 안내하는 템플릿입니다.
디자인 패턴은 일반적으로 세 가지 범주로 분류됩니다:
| 범주 | 목적 | 예시 |
|---|---|---|
| 생성 | 객체 생성 메커니즘 | Singleton, Factory, Builder |
| 구조 | 타입을 더 큰 구조로 구성 | Adapter, Decorator, Composite |
| 행동 | 객체 간 통신 | Observer, Strategy, Command |
Go에서는 디자인 패턴이 전통적인 OOP 언어와는 다르게 보입니다.
클래스나 상속 없이 Go는 인터페이스, 구조체 임베딩, 컴포지션을 사용하여 패턴을 구현합니다. 예를 들어 Java에서 추상 클래스를 사용할 수 있는 경우 Go에서는 인터페이스를 사용합니다. C++에서 상속을 사용할 수 있는 경우 Go에서는 임베딩을 사용합니다.
패턴을 학습하면 일반적인 문제를 인식하고 다른 개발자들과 해결책을 효과적으로 소통하는 데 도움이 됩니다. 누군가 “여기에는 Strategy 패턴을 사용하세요”라고 말하면, 긴 설명 없이도 팀 전체가 그 접근 방식을 이해합니다.
다음 몇 개의 레슨에서는 Go에서 여러 가지 기본 패턴을 구현합니다. Singleton과 Factory 같은 생성 패턴으로 시작한 다음, Observer와 Strategy 같은 행동 패턴으로 넘어갑니다.
챌린지
쉬움디자인 패턴이 코드 구성을 어떻게 돕는지 보여 주는 간단한 알림 시스템을 만들어 봅시다! 앞으로의 학습에서 Observer나 Strategy 같은 패턴으로 쉽게 확장할 수 있는 구조를 만들겠지만, 지금은 좋은 OOP 원칙을 따르는 깔끔한 인터페이스와 타입을 설정하는 데 집중하세요.
코드를 세 개의 파일로 구성합니다.
notifier.go: 알림 시스템의 핵심 인터페이스와 타입을 Define합니다.단일 메서드
Send(message string) string를 가진Notifier인터페이스를 Create하세요. 이 메서드는 confirmation 메시지를 returns합니다.두 개의 구체적인 notifier 타입을 Implement하세요.
EmailNotifier에는Addressfield가 있습니다. 이 타입의Sendmethod는Email to [address]: [message]를 returns합니다.SMSNotifier에는PhoneNumberfield가 있습니다. 이 타입의Sendmethod는SMS to [phone]: [message]를 returns합니다.
dispatcher.go: 인터페이스를 통해 모든 notifier와 함께 작동하는 dispatcher를 Create하세요.Notifierinterfaces의 슬라이스를 holds하는NotificationDispatcherstruct를 Build하세요. 다음 methods를 Add하세요.AddNotifier(n Notifier): notifier를 registered 상태로 만들기Broadcast(message string) []string: 모든 registered notifier를 통해 message를 보내고 모든 confirmation 문자열의 슬라이스를 returns
또한 initialized dispatcher를 returns하는
NewNotificationDispatcher()constructor를 Create하세요.main.go: notifier를 설정하고 message를 broadcast합니다.Create할 notifier의 count를 Read하세요. 각 notifier에 대해 타입(
email또는sms)과 destination(address 또는 phone number)을 Read하세요. 각각을 dispatcher에 Add하세요.그런 다음 broadcast할 message를 Read하세요. 모든 notifier를 통해 전송하고 각 confirmation을 한 줄에 하나씩 print하세요.
다음 입력이 제공됩니다.
- 1번째 줄: notifier의 number
- 각 notifier에 대해: 타입(
email또는sms), 그다음 destination - 마지막 줄: broadcast할 message
예를 들어 다음이 주어졌다고 합시다.
3
email
alice@example.com
sms
555-1234
email
bob@example.com
Server maintenance at midnight출력은 다음과 같아야 합니다.
Email to alice@example.com: Server maintenance at midnight
SMS to 555-1234: Server maintenance at midnight
Email to bob@example.com: Server maintenance at midnight또한 다음이 주어졌다고 합시다.
2
sms
555-9999
sms
555-0000
Meeting canceled출력은 다음과 같아야 합니다.
SMS to 555-9999: Meeting canceled
SMS to 555-0000: Meeting canceled이 구조는 interfaces가 유연하고 확장 가능한 설계를 가능하게 하는 방식을 보여 줍니다. dispatcher는 특정 notifier 타입에 대해 알지 못합니다. 단지 이들이 Send할 수 있다는 것만 압니다. 이것이 Observer와 Strategy 같은 패턴이 기반으로 삼는 토대입니다!
직접 해보기
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// 노티파이어 수를 읽습니다
countStr, _ := reader.ReadString('\n')
count, _ := strconv.Atoi(strings.TrimSpace(countStr))
// 새 디스패처를 생성합니다
dispatcher := NewNotificationDispatcher()
// 각 노티파이어를 읽고 디스패처에 추가합니다
for i := 0; i < count; i++ {
notifierType, _ := reader.ReadString('\n')
notifierType = strings.TrimSpace(notifierType)
destination, _ := reader.ReadString('\n')
destination = strings.TrimSpace(destination)
// TODO: 유형에 따라 적절한 노티파이어를 생성합니다
// 그리고 디스패처에 추가합니다
// Hint: notifierType이 "email" 또는 "sms"인지 확인하세요
}
// 브로드캐스트할 메시지를 읽습니다
message, _ := reader.ReadString('\n')
message = strings.TrimSpace(message)
// TODO: 메시지를 브로드캐스트하고 각 확인을 출력합니다
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서직접 연습해 보세요: 온라인 Go 컴파일러