[go] 구조체(struct)의 재사용 가능한 디자인 패턴

구조체는 여러 필드를 묶어 하나의 자료형으로 사용할 수 있는 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 언어에서 매우 유용한 기능 중 하나입니다. 위에서 소개한 구조체 인터페이스, 구조체 임베딩, 구조체 팩토리 함수와 같은 디자인 패턴을 사용하여 구조체를 재사용 가능하고 유연한 방식으로 설계할 수 있습니다. 이를 통해 보다 효율적이고 견고한 코드를 개발할 수 있습니다.

참고 자료