Menu
Coddy logo textTech

디자인 패턴 소개

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 85번째.

디자인 패턴은 소프트웨어 설계에서 발생하는 일반적인 문제에 대한 재사용 가능한 해결책입니다. 이는 직접 복사하는 코드가 아니라, 특정 문제를 해결하기 위해 타입의 구조와 상호작용을 어떻게 구성할지 안내하는 템플릿입니다.

디자인 패턴은 일반적으로 세 가지 범주로 분류됩니다:

범주목적예시
생성(Creational)객체 생성 메커니즘Singleton, Factory, Builder
구조(Structural)타입을 더 큰 구조로 합성Adapter, Decorator, Composite
행위(Behavioral)객체 간의 통신Observer, Strategy, Command

Go에서 디자인 패턴은 전통적인 OOP 언어들과는 다르게 보입니다.

클래스나 상속 없이, Go는 interfaces, struct embedding, 그리고 composition을 사용하여 패턴을 구현합니다. 예를 들어, Java가 abstract class를 사용할 수 있는 곳에서 Go는 interface를 사용합니다. C++가 inheritance를 사용할 수 있는 곳에서 Go는 embedding을 사용합니다.

패턴을 배우는 것은 일반적인 문제를 인식하고 다른 개발자들과 효과적으로 해결책을 소통하는 데 도움이 됩니다. 누군가가 "여기서는 Strategy 패턴을 사용합시다"라고 언급하면, 팀 전체가 긴 설명 없이도 그 접근 방식을 이해하게 됩니다.

다음 레슨들에서는 Singleton 및 Factory와 같은 생성 패턴부터 시작하여 Observer 및 Strategy와 같은 행동 패턴에 이르기까지 Go의 여러 가지 기본적인 패턴을 구현해 보겠습니다.

challenge icon

챌린지

쉬움

디자인 패턴이 코드를 구성하는 데 어떻게 도움이 되는지 보여주는 간단한 알림 시스템을 만들어 봅시다! 향후 레슨에서 Observer 또는 Strategy와 같은 패턴으로 쉽게 확장할 수 있는 구조를 만들게 될 것입니다. 하지만 지금은 좋은 OOP 원칙을 따르는 깔끔한 인터페이스와 타입을 설정하는 데 집중하세요.

코드는 세 개의 파일로 구성됩니다:

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

    확인 메시지를 반환하는 단일 메서드 Send(message string) string를 가진 Notifier 인터페이스를 생성하세요.

    두 개의 구체적인 알림 타입을 구현하세요:

    • Address 필드를 가진 EmailNotifierSend 메서드는 Email to [address]: [message]를 반환합니다.
    • PhoneNumber 필드를 가진 SMSNotifierSend 메서드는 SMS to [phone]: [message]를 반환합니다.
  • dispatcher.go: 인터페이스를 통해 모든 알림 도구와 함께 작동하는 디스패처를 생성합니다.

    Notifier 인터페이스 슬라이스를 보유하는 NotificationDispatcher 구조체를 만드세요. 다음 메서드들을 추가하세요:

    • 알림 도구를 등록하는 AddNotifier(n Notifier)
    • 등록된 모든 알림 도구를 통해 메시지를 전송하고 모든 확인 문자열의 슬라이스를 반환하는 Broadcast(message string) []string

    또한 초기화된 디스패처를 반환하는 NewNotificationDispatcher() 생성자를 만드세요.

  • main.go: 알림 도구를 설정하고 메시지를 브로드캐스트합니다.

    생성할 알림 도구의 개수를 읽습니다. 각 알림 도구에 대해 타입(email 또는 sms)과 목적지(주소 또는 전화번호)를 읽습니다. 각각을 디스패처에 추가합니다.

    그런 다음 브로드캐스트할 메시지를 읽습니다. 모든 알림 도구를 통해 메시지를 보내고 각 확인 메시지를 개별 줄에 출력합니다.

다음 입력이 제공됩니다:

  • 줄 1: 알림 도구의 개수
  • 각 알림 도구에 대해: 타입(email 또는 sms), 그 다음 목적지
  • 마지막 줄: 브로드캐스트할 메시지

예를 들어, 다음과 같이 주어지면:

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

이 구조는 인터페이스가 어떻게 유연하고 확장 가능한 설계를 가능하게 하는지 보여줍니다. 디스패처는 구체적인 알림 타입을 알지 못하며, 단지 그들이 Send를 할 수 있다는 것만 압니다. 이것이 Observer 및 Strategy와 같은 패턴이 구축되는 기초입니다!

치트 시트

디자인 패턴은 소프트웨어 설계에서 흔히 발생하는 문제에 대한 재사용 가능한 해결책입니다. 이는 타입의 구조와 그들 간의 상호작용을 어떻게 구성할지 안내하는 템플릿입니다.

디자인 패턴은 세 가지 카테고리로 분류됩니다:

카테고리목적예시
생성 (Creational)객체 생성 메커니즘Singleton, Factory, Builder
구조 (Structural)타입을 더 큰 구조로 합성Adapter, Decorator, Composite
행위 (Behavioral)객체 간의 통신Observer, Strategy, Command

Go에서 디자인 패턴은 클래스와 상속 대신 인터페이스(interfaces), 구조체 임베딩(struct embedding), 그리고 합성(composition)을 사용하여 구현됩니다. 전통적인 OOP 언어가 추상 클래스를 사용하는 곳에서 Go는 인터페이스를 사용합니다. 상속을 사용하는 곳에서 Go는 임베딩을 사용합니다.

직접 해보기

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: 타입에 따라 적절한 알림 서비스를 생성하고
		// 디스패처에 추가합니다
		// 힌트: notifierType이 "email"인지 "sms"인지 확인하세요

	}

	// 방송할 메시지를 읽습니다
	message, _ := reader.ReadString('\n')
	message = strings.TrimSpace(message)

	// TODO: 메시지를 방송하고 각 확인 메시지를 출력합니다

}
quiz icon실력 점검

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

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