임베딩된 메서드 섀도잉
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 39번째.
때로는 외부 구조체가 임베디드 타입에 이미 있는 메서드를 자체적으로 구현해야 합니다. 이를 섀도잉이라고 하며, 승격된 메서드를 사용자 지정 동작으로 재정의할 수 있게 해줍니다.
임베드된 method와 같은 이름으로 외부 구조체에 method를 정의하면 외부 method가 우선합니다:
type Animal struct {
Name string
}
func (a Animal) Speak() string {
return "Some sound"
}
type Dog struct {
Animal
Breed string
}
func (d Dog) Speak() string {
return "Woof!"
}
이제 Dog에서 Speak()을 호출하면 바깥쪽 메서드가 사용됩니다:
func main() {
d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Labrador"}
fmt.Println(d.Speak()) // Woof! - Dog의 메서드
fmt.Println(d.Animal.Speak()) // Some sound - Animal의 메서드
}
embedded method는 사라진 것이 아닙니다. embedded type 이름을 통해 여전히 명시적으로 액세스할 수 있습니다. 이 패턴은 원래 구현을 사용할 수 있는 상태로 동작을 사용자 지정하고 싶을 때 유용합니다. 예를 들어 overriding method 내부에서 이를 호출할 수 있습니다.
func (d Dog) Speak() string {
return d.Animal.Speak() + " (but actually Woof!)"
}
섀도잉을 사용하면 명시적 한정자를 통해 원래 동작에 계속 접근하면서 어떤 동작을 노출할지 제어할 수 있습니다.
챌린지
쉬움서로 다른 notification channel이 메시지의 형식 지정 및 전달 방식을 사용자 지정할 수 있는 notification system을 만들어 보겠습니다. method shadowing을 사용하여 특정 channel이 기본 동작을 재정의하면서도 필요할 때 원래 구현에 액세스할 수 있도록 합니다.
코드를 세 개의 파일로 구성합니다:
base.go:Title및Priorityfields(둘 다 문자열)를 포함하는BaseNotification구조체를 Create합니다. notification을 표준 형식인[Priority] Title로 반환하는Format() stringmethod를 추가합니다.channels.go:BaseNotification을 embed하고Formatmethod를 자체 구현으로 shadow하는 두 가지 notification channel type을 Create합니다:EmailNotification에는Recipientfield가 있습니다. 해당Format()은Email to [Recipient]: [Priority] Title을 반환해야 합니다.SlackNotification에는Channelfield가 있습니다. 해당Format()은 embed된BaseNotification.Format()method를 call하고 결과 앞에#[Channel]:을 prepend해야 합니다.
main.go: 입력에서 notification 세부 정보를 Read하고, 두 type의 notification을 Create한 다음 다음을 출력하여 shadowing을 보여 줍니다:EmailNotification의 형식 지정된 output (해당 shadow된 method 사용)EmailNotification의 base format (embed된 method를 explicitly call)SlackNotification의 형식 지정된 output (내부적으로 base method 사용)
다음 입력이 제공됩니다:
- 1번째 줄: notification title
- 2번째 줄: Priority level
- 3번째 줄: Email recipient
- 4번째 줄: Slack channel name
예를 들어 Server Alert, HIGH, admin@company.com, ops-alerts가 주어지면 output은 다음과 같아야 합니다:
Email to admin@company.com: HIGH Server Alert
[HIGH] Server Alert
#ops-alerts: [HIGH] Server AlertEmailNotification은 base formatting을 완전히 대체하는 반면, SlackNotification은 원래 method를 call하고 channel context를 추가하여 이를 향상한다는 점에 유의하세요. 두 접근 방식은 method shadowing을 효과적으로 사용하는 서로 다른 방법을 보여 줍니다.
직접 해보기
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// 알림 제목 읽기
scanner.Scan()
title := scanner.Text()
// 우선순위 수준 읽기
scanner.Scan()
priority := scanner.Text()
// 이메일 수신자 읽기
scanner.Scan()
recipient := scanner.Text()
// Slack 채널 이름 읽기
scanner.Scan()
channel := scanner.Text()
// TODO: 기본 알림, title, priority, recipient로 EmailNotification 생성
// TODO: 기본 알림, title, priority, channel로 SlackNotification 생성
// TODO: EmailNotification의 형식화된 출력 출력 (shadowed method 사용)
// TODO: EmailNotification의 기본 형식 출력 (embedded method를 명시적으로 호출)
// TODO: SlackNotification의 형식화된 출력 출력
fmt.Println() // 플레이스홀더 - 구현 시 제거
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서직접 연습해 보세요: 온라인 Go 컴파일러