A A
[Design Pattern] Composite Pattern - ์ปดํฌ์ง€ํŠธ ํŒจํ„ด

Composite Pattern

์ปดํฌ์ง€ํŠธ ํŒจํ„ด(Composite Pattern)์€ ๊ฐ์ฒด๋ฅผ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ๋ถ€๋ถ„-์ „์ฒด ๊ณ„์ธต์„ ๊ตฌํ˜„ํ•˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‹จ์ผ ๊ฐ์ฒด์™€ ๋ณตํ•ฉ ๊ฐ์ฒด๋ฅผ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ปดํฌ์ง€ํŠธ ํŒจํ„ด์€ ๊ตฌ์กฐ ํŒจํ„ด(Structural Pattern)์˜ ์ผ์ข…์œผ๋กœ, ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์–ด ํ•˜๋‚˜์˜ ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ปดํ“จํ„ฐ์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ๋Š” Directory ๋ผ๋Š” ๊ฒƒ์ด ์žˆ๊ณ , Directory์•ˆ์—๋Š” ํŒŒ์ผ์ด๋‚˜ ๋‹ค๋ฅธ ํ•˜์œ„ Directory๊ฐ€ ์žˆ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋งˆ์น˜์ƒ์ž ์•ˆ์˜ ์ƒ์ž” ๊ฐ™์€ ๊ตฌ์กฐ, ์ฆ‰ ์žฌ๊ท€์  ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
  • Directory ์—”ํŠธ๋ฆฌ๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ์กฐ์‚ฌํ•  ๋•Œ, ๊ทธ๋ฆ‡๊ณผ ๋‚ด์šฉ๋ฌผ์„ ๊ฐ™์€ ์ข…๋ฅ˜๋กœ ์ทจ๊ธ‰ํ•˜๋ฉด ํŽธ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด ๊ทธ๋ฆ‡์„ ๋‚ด์šฉ๋ฌผ๊ณผ ๋™์ผ์‹œ ํ•˜์—ฌ ์žฌ๊ท€์ ์ธ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Design Pattern์„ Composite Pattern ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

  • Leaf์˜ ์—ญํ• : leaf๋Š” ๋‚ด์šฉ๋ฌผ์„ ํ‘œ์‹œํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ ๋‚ด๋ถ€์—๋Š” ๋‹ค๋ฅธ๊ฒƒ์„ ๋„ฃ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • Composite์˜ ์—ญํ• : ๊ทธ๋ฆ‡์„ ๋‚˜ํƒ€๋‚ด๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ leaf์—ญํ• ์ด๋‚˜ Composite ์—ญํ• ์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Component์˜ ์—ญํ• : leaf์—ญํ• ๊ณผ Composite ์—ญํ• ์„ ๋™์ผ์‹œํ•˜๊ธฐ ์œ„ํ•œ ์—ญํ• ์„ ํ•˜๋ฉฐ, component๋Š” leaf์—ญํ• ๊ณผ composite ์—ญํ• ์— ๊ณตํ†ต์ ์ธ ์ƒ์œ„ ํด๋ž˜์Šค๋กœ ์‹คํ˜„ํ•ฉ๋‹ˆ๋‹ค.

  • “Object์˜ ๊ทธ๋ฃน”๊ณผ “Object์˜ Single Instance”๊ฐ€ ๊ฐ™์€ ํƒ€์ž…์œผ๋กœ ์ทจ๊ธ‰๋˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.
  • Composite Pattern์„ ํ†ตํ•ด Object๋“ค์„ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ•˜๋‚˜์˜ Object๊ฐ€ ๊ทธ Object๊ฐ€ ๋“ค์–ด์žˆ๋Š” Group์„ ๊ฐ™์€ ํƒ€์ž…์œผ๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.
  • Group์˜ ๋„ค๋ชจ ์นธ๋“ค์€ ๋ฆฌ์ŠคํŠธ๋กœ ์•ˆ์— Object๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
  • ์ด ๋‘˜์„ ๊ฐ™์€ ํƒ€์ž…์œผ๋กœ ์ทจ๊ธ‰ํ•œ๋‹ค๋Š” ๋ง์€ ๋‘˜์ด ๊ฐ™์€ interface๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

  • Composite Pattern์—์„œ๋Š” ์ด๋Ÿฌํ•œ Base Interface๋ฅผ Component, ์ƒ์†๋ฐ›์€ ๊ฐ์ฒด๋ฅผ Leaf, ์ด๋ฅผ ์ƒ์†๋ฐ›์€ ๊ทธ๋ฃน์„ Composite์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
  • Composite์•ˆ์˜ List์—๋Š” Component ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
  • Component๊ฐ€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ด ๋ฆฌ์ŠคํŠธ ์•ˆ์—๋Š” ๊ฒฐ๊ตญ Leaf, Composite ๋ชจ๋‘ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (Component๋ฅผ ์ƒ์†๋ฐ›์€ ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.)
  • Component๋ฅผ ์ƒ์†๋ฐ›์€ leaf์™€ composite์€ Component์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
class Component:
    def fn(self):
        pass

class Leaf(Component):
    def fn(self):
        print('leaf')

class Composite(Component):
    def __init__(self):
        self.components = []

    def add(self, component: Component):
        self.components.append(component)

    def fn(self):
        print('composite')
        for component in self.components:
            component.fn()
  • Component class
    • Base Interface
    • fn ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • Leaf class
    • Component๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค.
    • fn์„ ํ†ตํ•ด "leaf" ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • Composite class
    • Component๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค.
    • Component ๊ฐ์ฒด์˜ ๋ฆฌ์ŠคํŠธ์ธ components ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
    • add(): components ๋ฆฌ์ŠคํŠธ์— component ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
    • fn์€ "composite" ์ถœ๋ ฅํ•˜๊ณ  components ๋ฆฌ์ŠคํŠธ ๋‚ด๋ถ€์— ์žˆ๋Š” element ํ•˜๋‚˜์”ฉ ๋ถˆ๋Ÿฌ์„œ ๊ฐ ๊ฐœ์ฒด์— ๋Œ€ํ•ด fn ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
composite1 = Composite()
composite2 = Composite()

composite1.add(leaf1)
composite1.add(leaf2)

composite2.add(composite1)

composite2.fn()

  • Composite Object์ธ composite1๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๊ทธ ์•ˆ์— Leaf 2๊ฐœ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
  • Composite Object์ธ composite0๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • composite0์€ Leaf 1๊ฐœ์™€ composite1์„ ์†Œ์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋งˆ์ง€๋ง‰์œผ๋กœ composite0์—์„œ fn ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
composite
leaf
composite
leaf
leaf
  • composite0 ์•ˆ์— ์žˆ๋Š” ๋ชจ๋“  Object์— ๋Œ€ํ•ด์„œ fnํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํŠธ๋ฆฌ ๊ตฌ์กฐ์—์„œ ๋ฃจํŠธ๋ฅผ ๊ธฐ์ ์œผ๋กœ ํ•จ์ˆ˜ fn์„ ํ˜ธ์ถœํ•˜์—ฌ ๊ทธ ์•ˆ์— ๋“ค์–ด์žˆ๋Š” ๋ชจ๋“  Object์— ๋Œ€ํ•ด ํ•จ์ˆ˜ fn์ด ํ˜ธ์ถœ๋˜๋Š” ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.
Composite Pattern์˜ ์žฅ์ ์€ ํŠธ๋ฆฌ๊ตฌ์กฐ๊ฐ€ ๋งค์šฐ ๋ณต์žกํ•  ๋•Œ ํŠธ๋ฆฌ ๋ฃจํŠธ์—์„œ ํ•จ์ˆ˜ ํ•˜๋‚˜๋งŒ ํ˜ธ์ถœํ•˜๋ฉด Composite Pattern์„ ๋”ฐ๋ผ์„œ Leaf๊นŒ์ง€ ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

Composite Pattern Example

class Animal:
    def speak(self):
        pass

class Cat(Animal):
    def speak(self):
        print("meow")

class Dog(Animal):
    def speak(self):
        print("bark")

class AnimalGroup(Animal):
    def __init__(self):
        self.animals = []

    def add(self, animal: Animal):
        self.animals.append(animal)

    def speak(self):
        print("group speaking..")
        for animal in self.animals:
            animal.speak()
  • Animal class
    • Base Interface
    • speak ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šค๋นˆ๋‹ค.
  • Cat class
    • Animal์„ ์ƒ์†๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.
    • speak๋ฅผ ํ†ตํ•ด "meow" ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • Dog class
    • Animal์„ ์ƒ์† ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.
    • speak๋ฅผ ํ†ตํ•ด "bark" ์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • AnimalGroup class
    • Animal๋ฅผ ์ƒ์†๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.
    • Animal ๊ฐ์ฒด์˜ ๋ฆฌ์ŠคํŠธ์ธ animals ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
    • add(): animals ๋ฆฌ์ŠคํŠธ์— Animal ๊ฐ์ฒด ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
    • speak(): "group speaking.." ์ถœ๋ ฅํ•˜๊ณ  animals ๋ฆฌ์ŠคํŠธ ๋‚ด๋ถ€์— ์žˆ๋Š” element ํ•˜๋‚˜์”ฉ ๋ถˆ๋Ÿฌ์„œ ๊ฐ ๊ฐœ์ฒด์— ๋Œ€ํ•ด speak ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
# ์‚ฌ์šฉ ์˜ˆ์‹œ
cat_group = AnimalGroup()
cat_group.add(Cat())
cat_group.add(Cat())
cat_group.add(Cat())

dog_group = AnimalGroup()
dog_group.add(Dog())
dog_group.add(Dog())

zoo = AnimalGroup()
zoo.add(cat_group)
zoo.add(dog_group)

zoo.speak()
  • at_group์€ AnimalGroup์˜ ๊ฐ์ฒด๋กœ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • add ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด Cat ๊ฐ์ฒด 3๋งˆ๋ฆฌ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • dog_group์€ AnimalGroup์˜ ๊ฐ์ฒด๋กœ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • add ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด Dog ๊ฐ์ฒด 2๋งˆ๋ฆฌ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • zoo๋Š” AnimalGroup์˜ ๊ฐ์ฒด๋กœ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • add ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด cat_group๊ณผ dog_group ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • zoo์—์„œ speak() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
group speaking..
group speaking..
meow
meow
meow
group speaking..
bark
bark
  • zoo์—์„œ speak ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ทธ ๋‚ด๋ถ€์— ๋“ค์–ด์žˆ๋Š” ๋ชจ๋“  object์— ๋Œ€ํ•ด์„œ speak ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
Composite Pattern์˜ ํ•ต์‹ฌ์€ Group๊ณผ Object๊ฐ€ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•จ์œผ๋กœ์จ ๋ฃจํŠธ์—์„œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ํ•จ์ˆ˜๊ฐ€ ํŠธ๋ฆฌ์•ˆ์— ์žˆ๋Š” ๋ชจ๋“  ํ•จ์ˆ˜๋กœ ํผ์ง€๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.