반응형
프로그래밍언어 Go는 전통적인 상속(inheritance) 메커니즘이 없습니다. 하지만 코드 재사용성에 문제가 없으며, 오히려 더 깔끔하고 유연한 코드 구조를 만들 수 있도록 돕습니다. 이 점은 구성(composition)과 인터페이스(interfaces)라는 강력한 개념을 통해 구현됩니다.
왜 상속 없이도 코드 재사용이 가능한가?
- 구성(Composition) 사용
상속은 "is-a" 관계를 표현하는 데 적합하지만, Golang은 "has-a" 관계를 선호합니다. 즉, 큰 기능을 작게 나누어 구성을 통해 조합하여 새로운 구조체를 만들 수 있습니다. 이는 더 유연하고, 특정 기능만 독립적으로 재사용 가능하게 만들어 줍니다. - 인터페이스(Interfaces) 활용
Golang의 인터페이스는 특정 동작(메서드 집합)을 정의하며, 이를 구현하는 구조체는 상속 없이도 다양한 곳에서 재사용될 수 있습니다. 또한, 인터페이스는 Golang에서 매우 가볍고 강력하게 동작하며, 다른 구조체와의 결합도를 낮추는 역할을 합니다.
구성과 인터페이스 활용 예제
문제
동물(Animal)을 모델링하는 프로그램이 있습니다. 각 동물은 고유의 행동을 가지며, 일부 동물들은 비슷한 행동을 공유합니다. 상속 없이 이를 어떻게 재사용할 수 있을까요?
코드
package main
import "fmt"
// 기본 행동을 구조체로 정의
type Walker struct{}
func (w Walker) Walk() {
fmt.Println("I can walk!")
}
type Flyer struct{}
func (f Flyer) Fly() {
fmt.Println("I can fly!")
}
// Animal 인터페이스
type Animal interface {
Speak()
}
// Dog 구조체
type Dog struct {
Walker // 구성
}
func (d Dog) Speak() {
fmt.Println("Woof!")
}
// Bird 구조체
type Bird struct {
Walker // 구성
Flyer // 구성
}
func (b Bird) Speak() {
fmt.Println("Tweet!")
}
func main() {
// Dog 생성
dog := Dog{}
dog.Speak() // 출력: Woof!
dog.Walk() // 출력: I can walk!
// Bird 생성
bird := Bird{}
bird.Speak() // 출력: Tweet!
bird.Walk() // 출력: I can walk!
bird.Fly() // 출력: I can fly!
}
설명
- Walker와 Flyer는 각각 걷기와 날기 기능을 제공합니다.
이들은 독립적으로 정의되었으며, 다른 구조체에서도 재사용 가능합니다. - Dog와 Bird는 각각 Walker와 Flyer를 구성을 통해 포함하고 있으며, 이를 통해 해당 기능을 사용할 수 있습니다. 상속 없이도 필요한 기능을 조합하여 사용한 예입니다.
- Animal 인터페이스는 Speak 메서드만 정의하며, 이를 구현하는 모든 구조체는 Animal 타입으로 처리될 수 있습니다. 즉, Dog와 Bird는 상속 없이도 Animal 인터페이스를 구현하고 재사용할 수 있습니다.
장점
- 유연성: 구조체 간 결합도가 낮아져 유지보수가 용이합니다.
- 명확성: 불필요한 계층 구조 없이 간결한 코드 작성이 가능합니다.
- 재사용성: 독립적인 구성 요소를 조합해 다양한 기능을 쉽게 재사용할 수 있습니다.
Golang의 구성 기반 설계는 초급 개발자도 쉽게 이해할 수 있으며, 상속보다 실용적이고 강력한 설계 패턴을 제공합니다.
반응형
'How To' 카테고리의 다른 글
한랭질환자 조치 요령 (0) | 2025.01.11 |
---|---|
한랭질환 대비 방법 (한파 오면 이렇게 하세요) (0) | 2025.01.11 |