Menu
Coddy logo textTech

디자인 패턴 소개

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 같은 행동 패턴으로 넘어갑니다.

challenge icon

챌린지

쉬움

디자인 패턴이 코드 구성을 어떻게 돕는지 보여 주는 간단한 알림 시스템을 만들어 봅시다! 앞으로의 학습에서 Observer나 Strategy 같은 패턴으로 쉽게 확장할 수 있는 구조를 만들겠지만, 지금은 좋은 OOP 원칙을 따르는 깔끔한 인터페이스와 타입을 설정하는 데 집중하세요.

코드를 세 개의 파일로 구성합니다.

  • notifier.go: 알림 시스템의 핵심 인터페이스와 타입을 Define합니다.

    단일 메서드 Send(message string) string를 가진 Notifier 인터페이스를 Create하세요. 이 메서드는 confirmation 메시지를 returns합니다.

    두 개의 구체적인 notifier 타입을 Implement하세요.

    • EmailNotifier에는 Address field가 있습니다. 이 타입의 Send method는 Email to [address]: [message]를 returns합니다.
    • SMSNotifier에는 PhoneNumber field가 있습니다. 이 타입의 Send method는 SMS to [phone]: [message]를 returns합니다.
  • dispatcher.go: 인터페이스를 통해 모든 notifier와 함께 작동하는 dispatcher를 Create하세요.

    Notifier interfaces의 슬라이스를 holds하는 NotificationDispatcher struct를 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: 메시지를 브로드캐스트하고 각 확인을 출력합니다

}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Go 컴파일러