구조체는 여러 필드를 묶어 하나의 자료형으로 사용할 수 있는 Go 언어의 기능입니다. 하지만 구조체를 재사용 가능한 디자인 패턴으로 활용하기 위해서는 몇 가지 고려해야 할 사항이 있습니다.
1. 구조체 인터페이스
구조체를 사용할 때 가장 기본적인 패턴 중 하나는 구조체에 인터페이스(interface)를 구현하는 것입니다. 인터페이스를 사용하면 여러 구조체를 같은 타입으로 취급할 수 있으며, 이는 코드의 유연성과 재사용성을 높일 수 있습니다.
다음은 인터페이스를 활용한 구조체의 예시입니다.
type Shape interface {
Area() float64
Perimeter() float64
}
type Rectangle struct {
width float64
height float64
}
type Circle struct {
radius float64
}
func (r Rectangle) Area() float64 {
return r.width * r.height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.width + r.height)
}
func (c Circle) Area() float64 {
return math.Pi * c.radius * c.radius
}
func (c Circle) Perimeter() float64 {
return 2 * math.Pi * c.radius
}
func PrintShapeInfo(s Shape) {
fmt.Printf("Area: %.2f\n", s.Area())
fmt.Printf("Perimeter: %.2f\n", s.Perimeter())
}
위 코드에서 Shape 인터페이스는 구조체에 Area()와 Perimeter() 메서드를 구현하도록 강제합니다. Rectangle과 Circle 구조체는 이 인터페이스를 구현하고, PrintShapeInfo 함수는 Shape 인터페이스를 매개변수로 받아 해당 구조체의 정보를 출력합니다.
2. 구조체의 임베딩(Embedding)
구조체 임베딩은 구조체 내에 다른 구조체를 필드로 포함시키는 기능입니다. 이를 통해 구조체를 재사용하면서 확장할 수 있는 방법을 제공합니다.
다음은 구조체 임베딩을 활용한 예시입니다.
type Person struct {
name string
age int
}
type Employee struct {
Person
department string
}
func main() {
employee := Employee{
Person: Person{
name: "John",
age: 30,
},
department: "IT",
}
fmt.Println(employee.name)
fmt.Println(employee.age)
fmt.Println(employee.department)
}
위 코드에서 Person 구조체를 Employee 구조체에 임베딩하였습니다. 이를 통해 Employee 구조체는 Person의 필드와 메서드를 그대로 상속받을 수 있습니다.
3. 구조체 팩토리 함수
구조체 팩토리 함수는 특정 구조체의 인스턴스를 생성할 때 사용하는 함수입니다. 이를 통해 구조체의 생성 과정을 추상화하고, 클라이언트는 직접 구조체를 생성하는 대신 팩토리 함수를 호출하여 인스턴스를 얻을 수 있습니다.
다음은 구조체 팩토리 함수의 예시입니다.
type Point struct {
x, y int
}
func NewPoint(x, y int) Point {
return Point{x, y}
}
func main() {
p := NewPoint(3, 5)
fmt.Println(p)
}
위 코드에서 NewPoint 함수는 Point 구조체의 인스턴스를 생성하여 반환합니다. 클라이언트는 NewPoint 함수를 호출하여 Point 구조체를 생성하고, 이를 통해 코드의 가독성과 추상화 수준을 높일 수 있습니다.
결론
구조체는 Go 언어에서 매우 유용한 기능 중 하나입니다. 위에서 소개한 구조체 인터페이스, 구조체 임베딩, 구조체 팩토리 함수와 같은 디자인 패턴을 사용하여 구조체를 재사용 가능하고 유연한 방식으로 설계할 수 있습니다. 이를 통해 보다 효율적이고 견고한 코드를 개발할 수 있습니다.
참고 자료
- The Go Programming Language Specification - Struct types
- Effective Go - Embedding
- Go in Action - Chapter 6. Interfaces