A A
[Design Pattern] Bridge Pattern - ๋ธŒ๋ฆฟ์ง€ ํŒจํ„ด

Bridge Pattern

๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด(Bridge Pattern)์€ ์†Œํ”„ํŠธ์›จ์–ด ๋””์ž์ธ ํŒจํ„ด ์ค‘ ํ•˜๋‚˜๋กœ, ๊ตฌํ˜„๋ถ€์™€ ์ถ”์ƒํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค(๊ธฐ๋Šฅ) ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

  • ์ด ํŒจํ„ด์€ ๊ตฌ์กฐ ํŒจํ„ด(Structural Pattern) ์ค‘ ํ•˜๋‚˜๋กœ, ์‹œ์Šคํ…œ์„ ๋” ๋ชจ๋“ˆํ™”ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • Abstraction
    • High Level Layer
    • ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ Interface ํ˜น์€ UI
  • Implementor
    • ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋Œ์•„๊ฐ€๋Š” ์‹ค์ œ ๊ตฌํ˜„ ์ฝ”๋“œ
Abstraction๋งŒ ๋ณผ ์ˆ˜ ์žˆ๊ณ  ์‹ค์ œ Implementor์€ ์ˆจ๊ธธ ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.
์™ธ๋ถ€์—์„œ ๋ณด์—ฌ์ง€๋Š” ๊ฒƒ๊ณผ ๋‚ด๋ถ€ Implementor๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ ์ž ํ•  ๋–„ ์‚ฌ์šฉํ•˜๊ธฐ ์ข‹์Šต๋‹ˆ๋‹ค.

Bridege Pattern: Example 1


Class ๊ณ„์ธต์˜ ํ˜ผ์žฌ์™€ ๋ถ„๋ฆฌ

์šฐ๋ฆฌ๊ฐ€ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋ ค๊ณ  ํ•  ๋•Œ, ์ž์‹ ์˜ ์˜๋„๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ๊ฐํ•ด๋ณผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋ ค๋Š” ์˜๋„์ธ๊ฑด์ง€, ์ˆ˜ํ–‰ํ•˜๋ ค๋Š” ์˜๋„์ธ๊ฑด์ง€?
  • ํด๋ž˜์Šค ๊ณ„์ธต์ด ํ•˜๋‚˜๋ผ๋ฉด ๊ธฐ๋Šฅ์˜ ํด๋ž˜์Šค ๊ณ„์ธต๊ณผ ๊ตฌํ˜„์˜ ํด๋ž˜์Šค ๊ณ„์ธต์ด ํ•˜๋‚˜์˜ ๊ณ„์ธต ๊ตฌ์กฐ ์•ˆ์— ํ˜ผ์žฌ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ํด๋ž˜์Šค ๊ณ„์ธต์„ ๋ณต์žกํ•˜๊ฒŒ ํ•˜์—ฌ ์˜ˆ์ธก์„ ์–ด๋ ต๊ฒŒ ํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋˜ํ•œ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋ ค๊ณ  ํ•  ๋•Œ ํด๋ž˜์Šค ๊ณ„์ธต์˜ ์–ด๋””์— ๋งŒ๋“ค์–ด์•ผ ํ• ์ง€ ํ•ด๋งค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ๊ธฐ๋Šฅ์˜ ํด๋ž˜์Šค ๊ณ„์ธต, ๊ตฌํ˜„์˜ ํด๋ž˜์Šค ๊ณ„์ธต์„ ๋‘๊ฐœ์˜ ๋…๋ฆฝ๋œ ํด๋ž˜์Šค ๊ณ„์ธต์œผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š”๊ฒƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ทผ๋ฐ, ๋‹จ์ˆœํžˆ ๋ถ„๋ฆฌํ•ด๋ฒ„๋ฆฌ๋ฉด ํฉ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๊ฐœ์˜ ํด๋ž˜์Šค ๊ณ„์ธต ์‚ฌ์ด์— ๋‹ค๋ฆฌ๋ฅผ ๋†“์•„์ค„ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. → ์ด ๋‹ค๋ฆฌ๋ฅผ Bridge Pattern์œผ๋กœ ๋†“์•„์ค๋‹ˆ๋‹ค.

Bridge Pattern

  • Abstraction๊ณผ Implementor๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ independentํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • Abstraction๊ณผ Implementor ์‚ฌ์ด์— ๋‹ค๋ฆฌ๋ฅผ ๋†“๋Š” ์—ญํ•  ์ž…๋‹ˆ๋‹ค.

Bridge Pattern: Example 2

  • Animal์„ Boat, Car, Airplane ์ค‘์— ํƒœ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Class ๊ตฌ์กฐ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ์ฝ”๋”ฉ์„ ํ•œ๋‹ค๋ฉด Animal 2์ข…๋ฅ˜ ์šด์†ก์ˆ˜๋‹จ 3์ข…๋ฅ˜, ์ฆ‰ 6(2x3=6)๊ฐ€์ง€ ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ ์—ฌ๊ธฐ์„œ ๋” ๋งŽ์€ ์ข…๋ฅ˜๊ฐ€ ์ƒ๊ธฐ๋ฉด ๋ณต์žกํ•ด์ง‘๋‹ˆ๋‹ค. ์ด๋•Œ Bridge Pattern์„ ์ƒ๊ฐํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Vehicle class๋ฅผ ๋งŒ๋“ค์–ด Base class๋กœ ์‚ผ๊ณ  Boat, Car, Airplane class๋Š” Vehicle class๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค.
  • Vehicle class๋Š” Animal์„ property๋กœ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • Vehicle๊ณผ Animal ๋‘˜ ์‚ฌ์ด์˜ ๊ด€๊ณ„๊ฐ€ ์ด์–ด์ง€๋ฉด์„œ Bridge๋กœ ๋ด…๋‹ˆ๋‹ค.

 

# Animal classes
class Animal:
    def speak(self):
        pass

class Cat(Animal):
    def speak(self):
        print('a cat ', end='')

class Dog(Animal):
    def speak(self):
        print('a dog ', end='')
  • Animal์—์„œ ์ƒ์†๋ฐ›์€ Cat๊ณผ Dog class๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋‘ speak ํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

# Vehicle classes
class Vehicle:
    def __init__(self, animal: Animal):
        self.animal = animal

    def start(self):
        pass

class Car(Vehicle):
    def start(self):
        self.animal.speak()
        print('drives a car')

class Boat(Vehicle):
    def start(self):
        self.animal.speak()
        print('sails a boat')

class Airplane(Vehicle):
    def start(self):
        self.animal.speak()
        print('flies an airplane')
  • Vehicle class๋Š” ๋‚ด๋ถ€์— Animal Object๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
  • start ํ•จ์ˆ˜๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
  • Car, Boat, Airplane class๋Š” Vehicle์„ ์ƒ์† ๋ฐ›์Šต๋‹ˆ๋‹ค.

 

# Usage example
cat = Cat()
boat = Boat(cat)
boat.start()  # ์ถœ๋ ฅ: a cat sails a boat
  • Cat object์ธ cat์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • Boat object์ธ boat ์ƒ์„ฑํ›„ ์ธ์ž๋กœ cat์„ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.
  • boat๋ฅผ ์ถœ๋ฐœ์‹œํ‚ค๋ฉด boat๋ฅผ ํƒ„ cat์˜ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

 

dog = Dog()
car = Car(dog)
car.start()  # ์ถœ๋ ฅ: a dog drives a car
  • Dog object์ธ dog์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • Car object์ธ car ์ƒ์„ฑํ›„ ์ธ์ž๋กœ dog์„ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.
  • car๋ฅผ ์ถœ๋ฐœ์‹œํ‚ค๋ฉด car๋ฅผ ํƒ„ dog์˜ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

Bridge Pattern: Example 3

# Abstraction ์—ญํ• ์˜ Car class
class Car:
    def __init__(self, power: Power):
        self.power = power

    def drive(self):
        self.power.powerUp()

    def stop(self):
        self.power.powerDown()

class Sedan(Car):
    def sedanOnlyFn(self):
        print('sedan only')
  • Abstraction ์—ญํ• ์˜ Car class ์ž…๋‹ˆ๋‹ค.
  • ๋‚ด๋ถ€ Property๋กœ power๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
  • Sedan์€ Car ์ข…๋ฅ˜๋กœ ์ƒ์† ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • Drive, Stop ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Drive ํ•จ์ˆ˜๋Š” PowerUp, Stop ํ•จ์ˆ˜๋Š” PowerDown์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 

# Implementor ์—ญํ• ์˜ Power class
class Power:
    def powerUp(self):
        pass

    def powerDown(self):
        pass

class Engine(Power):
    def powerUp(self):
        print('engine power up')

    def powerDown(self):
        print('engine power down')

class Motor(Power):
    def powerUp(self):
        print('motor power up')

    def powerDown(self):
        print('motor power down')
  • Implementor ์—ญํ• ์˜ Power Class ์ž…๋‹ˆ๋‹ค.
  • Engine, Motor๋Š” Power ์ข…๋ฅ˜๋กœ ์ƒ์† ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • PowerUp, PowerDown ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

# Usage example
sedan = Sedan(Motor())
sedan.drive()         # ์ถœ๋ ฅ: motor power up
sedan.stop()          # ์ถœ๋ ฅ: motor power down
sedan.sedanOnlyFn()   # ์ถœ๋ ฅ: sedan only
  • Sedan ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  argument๋กœ Power์˜ ์ž์‹ Class์€ Motor๋ฅผ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.
  • Sedan.driveํ•˜์—ฌ powerUp ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ํ•ฉ๋‹ˆ๋‹ค.
  • Sedan.stopํ•˜์—ฌ powerDown์„ ํ˜ธ์ถœ ํ•ฉ๋‹ˆ๋‹ค.
  • sedanOnlyFN์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • ๋‚ด๋ถ€ Implementor๋Š” Motor์ด์ง€๋งŒ ๊ทธ ์™ธ๋ถ€๋Š” Sedan์ด๋ผ๋Š” Output์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.
Bridge Pattern์€ ๊ฒ‰์—์„œ ๋ณด์—ฌ์ง€๋Š” Abstraction๊ณผ ๋‚ด๋ถ€ Implementor๋ฅผ ๊ตฌ๋ถ„ํ•ด์„œ Bridge๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

๋ถ„๋ฆฌํ•ด ๋‘๋ฉด ํ™•์žฅ์ด ํŽธํ•ด์ง‘๋‹ˆ๋‹ค

  • Bridge pattern์€ ๊ธฐ๋Šฅ์˜ Class, ๊ตฌํ˜„์˜ Class ๊ณ„์ธต์„ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ๋‘๊ฐœ์˜ ํด๋ž˜์Šค ๊ณ„์ธต์„ ๋ถ„๋ฆฌํ•ด ๋‘๋ฉด ๊ฐ๊ฐ์˜ ํด๋ž˜์Šค ๊ณ„์ธต์„ ๋…๋ฆฝ์ ์œผ๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์œผ๋ฉด ๊ธฐ๋Šฅ์˜ ํด๋ž˜์Šค ๊ณ„์ธต์— ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ณ , ์ด๋–„ ๊ตฌํ˜„์˜ ํด๋ž˜์Šค ๊ณ„์ธต์€ ์ „ํ˜€ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•œ ๊ธฐ๋Šฅ์€ ๋ชจ๋“  ๊ตฌํ˜„์— ๋Œ€ํ•ด ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ์†์€ ๊ฒฌ๊ณ ํ•œ ์—ฐ๊ฒฐ, ์œ„์ž„์€ ๋Š์Šจํ•œ ์—ฐ๊ฒฐ

  • ์ƒ์†์€ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๊ธฐ ์œ„ํ•ด ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ํด๋ž˜์Šค๊ฐ„ ์—ฐ๊ฒฐ์„ ๊ฐ•ํ•˜๊ฒŒ ๊ณ ์ •์‹œํ‚ต๋‹ˆ๋‹ค.
class SomethingGood(Something)
  • SomethingGood ํด๋ž˜์Šค๋Š” Something ํด๋ž˜์Šค์˜ ํ•˜์œ„ ํด๋ž˜์Šค๊ฐ€ ๋˜๋ฉฐ, ์ด ๊ด€๊ณ„๋Š” ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๊ณ ์ณ์“ฐ์ง€ ์•Š๋Š” ํ•œ ๋ด๊ฟ€์ˆ˜ ์—†๋Š” ๋งค์šฐ ๊ฒฌ๊ณ ํ•œ ์—ฐ๊ฒฐ์ด ๋ฉ๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ, ํด๋ž˜์Šค๊ฐ„ ๊ด€๊ณ„๋ฅผ ์ฒ™์ฒ™ ๋ด๊พธ๊ณ  ์‹ถ์„๋–„ ์ƒ์†์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ถ€์ ์ ˆ ํ• ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ต์ฒดํ•  ๋•Œ๋งˆ๋‹ค ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๊ธฐ ๋–„๋ฌธ์ž…๋‹ˆ๋‹ค.
  • ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ์—” ‘์ƒ์†’์ด ์•„๋‹ˆ๋ผ ‘์œ„์ž„’์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒˆ๋กœ์šด concrete implementor๋ฅผ ๋งŒ๋“ค๋”๋ผ๋„ ์ธ์Šคํ„ด์Šค๋งŒ abstraction์œผ๋กœ ๋„˜๊ฒจ์ฃผ๋ฉด ์†Œ์Šค์ฝ”๋“œ ์ˆ˜์ •์ด ํ•„์š”์—†์ด ๋ฐ”๋กœ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.