본문 바로가기
golang/design pattern

golang design pattern #7 Composite

by PudgeKim 2021. 11. 12.

Composite 패턴은 어떤 object가 있을 때 해당 object의 group과 단일 object를 똑같이 다루고 싶을 때 사용됩니다.

이러한 composite 패턴 사용시 Tree 구조가 되기 때문에 재귀적인 코드가 사용되게 됩니다.

 

파일/폴더 구조를 예시로 들어보자면 둘다 find라는 메서드가 필요할 수 있습니다.

폴더에서의 search는 폴더내에 있는 파일들을 순환하면서 탐색하는 메서드일 것이고
파일에서의 search는 파일내의 내용을 찾아보는 것일 겁니다.

그런데 폴더안에는 또 다른 폴더가 들어갈 수 있으므로 재귀적인 형태가 되어야합니다.

이런 상황에서 Composite 패턴을 적용시켜보겠습니다.

 

1
2
3
type component interface {
    search(string)
}
cs

우선 group에 해당하는 폴더와 single에 해당하는 파일을 똑같이 다루고 싶은게 목적이므로
공통된 인터페이스로 다루기 위해 위 같은 인터페이스를 정의합니다.

이렇게 인터페이스를 정의하면 폴더와 파일이 search 메서드를 구현하면
둘다 component 타입이라는 공통된 인터페이스로 다룰 수 있게 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
type file struct {
    name string
}
 
func (f *file) search(keyword string) {
    fmt.Printf("Searching for keyword %s in file %s\n", keyword, f.name)
}
 
func (f *file) getName() string {
    return f.name
}
cs

파일 구조체입니다. search 메서드를 구현하였으므로 component 타입을 만족합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type folder struct {
    components []component
    name       string
}
 
func (f *folder) search(keyword string) {
    fmt.Printf("Serching recursively for keyword %s in folder %s\n", keyword, f.name)
    for _, composite := range f.components {
        composite.search(keyword)
    }
}
 
func (f *folder) add(c component) {
    f.components = append(f.components, c)
}
cs

폴더 구조체입니다. 역시 search 메서드를 구현하였으므로 component 타입을 만족합니다.

폴더에서의 search 메서드는 폴더내에 있는 모든 component를 탐색해야하고,
또한, 폴더내에 또 다른 폴더가 있을 수도 있으므로 위처럼 재귀적인 코드로 구현합니다.
(폴더내에 또 다른 폴더가 있다면 다시 폴더의 search 메서드가 실행될 것이므로 재귀적이게 됩니다.)

폴더 내에 파일 또는 폴더를 추가하기 위한 add 메서드도 구현하였습니다.

위에서도 설명했듯이 파일과 폴더를 같은 object라고 느끼게 다룰 것이므로 파라미터 타입이 file 또는 folder가 아닌 
component 타입인것에 주의해야합니다.

'golang > design pattern' 카테고리의 다른 글

golang design pattern #9 Flyweight  (0) 2021.11.14
golang design pattern #8 Decorator  (0) 2021.11.13
golang design pattern #6 Bridge  (0) 2021.11.12
golang design pattern #5 Adapter  (0) 2021.11.12
golang design pattern #4 Singleton  (0) 2021.11.11