apple/DesignPattern, Architecture

Swift 디자인패턴 Composite Pattern (복합체 패턴)

lgvv 2022. 6. 15. 18:26

Swift 디자인패턴 Composite Pattern (복합체 패턴)

 

Composite Pattern은 객체들을 트리 구조로 그룹화하여 하나의 객체처럼 조작할 수 있게 함. 구조 패턴으로. 객체들을 트리 구조로 그룹화하여 하나의 객체처럼 조작할 수 있게 함.

 

히스토리

  • 2022-06-15: 디자인 패턴 스터디 정리
  • 2024-11-26: 포스팅 글 재정리 및 조금 더 실용적인 예제 코드로 변경

 

composite Pattern

 

 

Composite Pattern

Composite Pattern은 일반적으로 3개지 개념으로 구성됨

  • Component: 공통 인터페이스를 정의
  • Leaf: 구현된 객체를 나타내며, 더 이상 자식 객체를 가지지 않음
  • Composite: 자식 객체를 포함할 수 있는 객체로, 자식 객체를 추가하거나 제거할 수 있는 메서드를 제공

복합체 패턴 적용을 고려할 수 있는 상황

  • 객체의 계층 구조를 표현해야 할 때
  • 클라이언트가 복합 객체와 단일 객체를 동일하게 다루어야 할 때
  • 복잡한 구조를 단순화하여 관리하고자 할 때

활용 예시

  • RIBs, TCA 등 아키텍처
  • 파일 시스템: 파일과 디렉토리를 표현하는 데 사용될 수 있음

 

코드 예제

Mac을 사용하면 제공되는 Finder처럼 파일 시스템을 구현

import SwiftUI

// Component
protocol FileSystemComponent {
    func display(indent: String)
}

// Leaf
class File: FileSystemComponent {
    private var name: String

    init(name: String) {
        self.name = name
    }

    func display(indent: String) {
        print("\(indent)File: \(name)")
    }
}

// Composite
class Directory: FileSystemComponent {
    private var name: String
    private var children: [FileSystemComponent] = []

    init(name: String) {
        self.name = name
    }

    func add(component: FileSystemComponent) {
        children.append(component)
    }

    func remove(component: FileSystemComponent) {
        if let index = children.firstIndex(where: { $0 as AnyObject === component as AnyObject }) {
            children.remove(at: index)
        }
    }

    func display(indent: String) {
        print("\(indent)Directory: \(name)")
        for child in children {
            child.display(indent: indent + "  ")
        }
    }
}

private struct ContentView: View {
    var body: some View {
        Button("Execute") {
            
            // 클라이언트 코드
            let file1 = File(name: "file1.txt")
            let file2 = File(name: "file2.txt")
            let file3 = File(name: "file3.txt")

            let dir1 = Directory(name: "dir1")
            let dir2 = Directory(name: "dir2")

            // 디렉토리에 파일 추가
            dir1.add(component: file1)
            dir1.add(component: file2)

            // 다른 디렉토리에 파일 추가
            dir2.add(component: file3)

            // 루트 디렉토리 생성 및 서브 디렉토리 추가
            let root = Directory(name: "root")
            root.add(component: dir1)
            root.add(component: dir2)

            // 전체 파일 시스템 구조 출력
            root.display(indent: "")

        }
    }
}

#Preview {
    ContentView()
}

출력결과

 

(참고)

https://www.kodeco.com/books/design-patterns-by-tutorials/v3.0/chapters/20-composite-pattern

 

Design Patterns by Tutorials, Chapter 20: Composite Pattern

This is a structural pattern that groups a set of objects into a tree so that they may be manipulated as though they were one object. If your app's class hierarchy forms a branching pattern, trying to create two types of classes for branches and nodes can

www.kodeco.com

https://refactoring.guru/ko/design-patterns/composite

 

복합체 패턴

/ 디자인 패턴들 / 구조 패턴 복합체 패턴 다음 이름으로도 불립니다: 객체 트리, Composite 의도 복합체 패턴은 객체들을 트리 구조들로 구성한 후, 이러한 구조들과 개별 객체들처럼 작업할 수 있

refactoring.guru