A A
[Design Pattern] Adapter Pattern - ์–ด๋Œ‘ํ„ฐ ํŒจํ„ด

Adapter Pattern - ์–ด๋Œ‘ํ„ฐ ํŒจํ„ด

Adapter Pattern์€ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง„ ํด๋ž˜์Šค๋“ค์ด ํ•จ๊ป˜ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ค‘๊ฐ„์— ์–ด๋Œ‘ํ„ฐ๋ฅผ ๋‘์–ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

  • ํ•˜๋‚˜์˜ Interface๋ฅผ ๋‹ค๋ฅธ Interface๋กœ ์ „ํ™˜ํ•˜๋Š” ์—ญํ•  → ์ด๋Ÿฌํ•œ ์—ญํ• ์„ Adapter Pattern์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ‘์ด๋ฏธ ์ œ๊ณต๋˜์–ด ์žˆ๋Š” ๊ฒƒ’๊ณผ ‘ํ•„์š”ํ•œ ๊ฒƒ’ ์‚ฌ์ด์˜ ‘์ฐจ์ด’๋ฅผ ์—†์• ์ฃผ๋Š” ๋””์ž์ธ ํŒจํ„ด์„ Adapter ํŒจํ„ด์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
  • ๋˜ํ•œ Adapter ํŒจํ„ด์€ Wrapper ํŒจํ„ด์œผ๋กœ ๋ถˆ๋ฆฌ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
  • Wrapper๋Š” ‘๊ฐ์‹ธ๋Š” ๊ฒƒ’์ด๋ผ๋Š” ์˜๋ฏธ๊ฐ€ ์žˆ๋Š”๋ฐ, ๋ฌด์–ธ๊ฐ€๋ฅผ ํฌ์žฅํ•ด์„œ ๋‹ค๋ฅธ ์šฉ๋„๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ตํ™˜ํ•ด์ฃผ๋Š” ๊ฒƒ์ด wrapper์ด๋ฉฐ, adapter๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
  • ๋‘๊ฐ€์ง€์˜ ์ข…๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ํด๋ž˜์Šค์— ์˜ํ•œ Adapter ํŒจํ„ด (์ƒ์†ํ•˜๋Š” ๋ฐฉ๋ฒ•)
    • ์ธ์Šคํ„ด์Šค์— ์˜ํ•œ Adapter ํŒจํ„ด (์œ„์ž„ ํ•˜๋Š” ๋ฐฉ๋ฒ•)

 

ํ•ต์‹ฌ ๊ฐœ๋…

Example)
Target: ์ง๋ฅ˜ 12V
Client: ๋„คํŠธ์›Œํฌ
Adapter: ์ „๋ฅ˜ ๋ณ€ํ™˜ ์–ด๋Œ‘ํ„ฐ
Adaptee: ์ œ๊ณต๋˜๋Š” ๊ต๋ฅ˜ 100V
  • Target Interface: Client๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” Interface๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • Adaptee ํด๋ž˜์Šค: ๊ธฐ์กด์˜ Interface๋ฅผ ์ œ๊ณตํ•˜๋Š” Class์ž…๋‹ˆ๋‹ค.
  • Adapter ํด๋ž˜์Šค: Adaptee ํด๋ž˜์Šค์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ Target Interface๋กœ ๋ณ€ํ™˜ํ•˜๋Š” Class์ž…๋‹ˆ๋‹ค.
  • Client: Target Interface๋ฅผ ํ†ตํ•ด Adapter์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” Class์ž…๋‹ˆ๋‹ค.

 

์žฅ์ 

  • ํ˜ธํ™˜์„ฑ ์ œ๊ณต: ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” Interface๋ฅผ ๊ฐ€์ง„ Class๋“ค ๊ฐ„์˜ ํ˜‘์—…์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ธฐ์กด ์ฝ”๋“œ ์ˆ˜์ • ์ตœ์†Œํ™”: ๊ธฐ์กด Class์˜ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ ๋„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐœ๋ฐฉ-ํ์‡„ ์›์น™ ์ค€์ˆ˜: ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋‹จ์ 

  • ์ถ”๊ฐ€์ ์ธ Class ์ƒ์„ฑ: Adapter Class๋ฅผ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋ฏ€๋กœ Code๊ฐ€ ๋‹ค์†Œ ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํผํฌ๋จผ์Šค ์˜ํ–ฅ: ์ถ”๊ฐ€์ ์ธ ๊ณ„์ธต์ด ์ƒ๊ธฐ๋ฉด์„œ Performance(์„ฑ๋Šฅ)์— ์•ฝ๊ฐ„์˜ ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Adapter Pattern Example

(hello), hello ← ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ๊ธฐํ•˜๊ณ ์ž ํ•  ๋•Œ

๋ชฉ์ : Banner ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ Print ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ถฉ์กฑ์‹œํ‚ค๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • ์—ฌ๊ธฐ์„œ ์ œ๊ณต๋˜๊ณ  ์žˆ๋Š”๊ฑด, ๊ตํ™˜์žฅ์น˜: Adapter, ํ•„์š”ํ•œ ๊ฒƒ: Target ์ž…๋‹ˆ๋‹ค.
  • ์—ฌ๊ธฐ์„œ Print ์ธํ„ฐํŽ˜์ด์Šค๋Š” → Framework๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • Banner ํด๋ž˜์Šค (์ œ๊ณต๋˜๊ณ  ์žˆ๋Š” ๊ฒƒ)
    • ๋ฌธ์ž์—ด์„ ๊ด„ํ˜ธ๋กœ ๋ฌถ์–ด์„œ ํ‘œ์‹œํ•˜๋Š” showWithParen ๋ฉ”์†Œ๋“œ [ ( ) ]
    • *๋ฅผ ๋ถ™์—ฌ ํ‘œ์‹œํ•˜๋Š” showWithAster ๋ฉ”์†Œ๋“œ [ * ]
  • Print ํด๋ž˜์Šค (ํ•„์š”ํ•œ ๊ฒƒ)
    • ๋ฌธ์ž์—ด์„ ๋Š์Šจํ•˜๊ฒŒ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•œ printWeak ๋ฉ”์†Œ๋“œ [ ( ) ]
    • ๋ฌธ์ž์—ด์„ ๊ฐ•ํ•˜๊ฒŒ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•œ printStrong ๋ฉ”์†Œ๋“œ [ * ]
  • PrintBanner ํด๋ž˜์Šค (๊ตํ™˜ ์žฅ์น˜)
    • ์ œ๊ณต๋˜์–ด ์žˆ๋Š” Bannerํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•ด์„œ, ํ•„์š”๋กœ ํ•˜๋Š” Print ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
    • ShowWithParen ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ printWeak๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ 
    • ShowWithAster ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ printStrong์„ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

Adapter Pattern (์ƒ์† ์˜ˆ์‹œ)

class Banner(): # Adaptee

    def __init__(self, word):
        self.word = word
    
    def showWithParen(self):
        print("(" + self.word + ")")

    def showWithAster(self):
        print("*" + self.word + "*")

class Print(): # Target

    def printWeak(self):
        pass

    def printStrong(self):
        pass

class PrintBanner(Banner, Print): # ์ƒ์† (Adapter)
    
    def __init__(self, word): # word -> banner ๊ธฐ๋Šฅ ์ˆ˜ํ–‰
        # ํ˜„์žฌํด๋ž˜์Šค๊ฐ€ ์–ด๋–คํด๋ž˜์Šค์ธ์ง€๋ฅผ ๋ช…ํ™•ํžˆ ํ‘œ๊ธฐ
        super(PrintBanner, self).__init__(word)
    
    def printWeak(self):
        self.showWithParen()
    
    def printStrong(self):
        self.showWithAster()

# client, Framework
pb = PrintBanner("Hello")
pb.printStrong()
pb.printWeak()
[Running] python -u "/Users/daehyunkim/Documents/GitHub/Bigbread-HUFS-Subject/2024-1 Design Pattern/Week 4/test.py"
*Hello*
(Hello)

Adapter Pattern (์œ„์ž„ ์˜ˆ์‹œ)

class Banner(): # Adaptee

    def __init__(self, word):
        self.word = word
    
    def showWithParen(self):
        print("(" + self.word + ")")

    def showWithAster(self):
        print("*" + self.word + "*")

class Print(): # Target

    def printWeak(self):
        pass

    def printStrong(self):
        pass

class PrintBanner(Print): # ์œ„์ž„ (Adapter)
    
    def __init__(self, word):
        self.banner = Banner(word)
    
    def printWeak(self):
        self.banner.showWithParen()
    
    def printStrong(self):
        self.banner.showWithAster()

# client, Framework
pb = PrintBanner("Hello")
pb.printStrong()
pb.printWeak()
[Running] python -u "/Users/daehyunkim/Documents/GitHub/Bigbread-HUFS-Subject/2024-1 Design Pattern/Week 4/test.py"
*Hello*
(Hello)

Adapter Pattern (๋‹ค๋ฅธ ์˜ˆ์‹œ)

class Animal: # target
    def walk(self):
        pass
    
class Cat(Animal):
    def walk(self):
        print("Cat walking")

class Dog(Animal):
    def walk(self):
        print("Dog walking")

def makeWalk(animal: Animal): # client
    animal.walk() # ํ˜ธํ™˜์„ฑ ๋†’์€ ์ƒํƒœ
  • Base class: Animal → walk ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • Animal์„ ์ƒ์†๋ฐ›์€ Cat & Dog Class ๋ชจ๋‘ walk interface ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • makeWalk ํ•จ์ˆ˜๋Š” animal์„ argument๋กœ ๊ฐ–๊ณ  Animal class์˜ walk ํ•จ์ˆ˜๋ฅผ ๋ถ€๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
walk ์‚ฌ์šฉ์‹œ, animal interface ์‚ฌ์šฉ

 

 

kitty = Cat()
bingo = Dog()

makeWalk(kitty)
makeWalk(bingo)
  • Kitty & Bingo๋Š” ๊ฐ๊ฐ Cat๊ณผ Dog object์ด๋ฉฐ makeWalk๋ฅผ ํ†ตํ•ด walkํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Client → makewalk() → FIsh

 

class Fish: # Adaptee
	def swim(self):
    	print("fish swimming")
        
nemo = Fish()
makewalk(nemo)
  • Fish class๋Š” swim interface๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Fish class์˜ nemo object๋ฅผ ๋งŒ๋“ค์–ด์„œ makeWalk ํ•จ์ˆ˜๋กœ ๋„˜๊ฒจ์ฃผ๋ฉด Error๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
AttributeError: ‘Fish’ Object has no attribute ‘walk’
  • Fish class์˜ Object๊ฐ€ makeWalk interface๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Fish & Animal interface๋ฅผ ์—ฐ๊ฒฐ์‹œ์ผœ ์ฃผ๋Š” Adapter๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

 

class FishAdapter(Animal): # Adapter
    def __init__(self, fish):
        self.fish = fish
    
    def walk(self):
        self.fish.swim()

nemo = Fish()
adapted_nemo = FishAdapter(nemo)

makeWalk(adapted_nemo)
# result: fish swimming
  • FishAdapter class๋Š” Animal์„ ์ƒ์†๋ฐ›๊ณ  constructor ์•ˆ์—์„œ Fish object๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • Nemo๋Š” Fish Object์ด๊ณ  adapted_nemo๋Š” FishAdapter์— nemo๋ฅผ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.
  • MakeWalk์— adapted_nemo๋ฅผ ๋„˜๊ฒจ์ฃผ๋ฉด Fish์˜ Swim interface๋ฅผ FishAdapter์˜ walk์„ ํ†ตํ•ด ๋ถˆ๋Ÿฌ๋ƒ…๋‹ˆ๋‹ค.
Adapter pattern์€ ๋งž์ง€ ์•Š๋Š” ๊ธฐ์กด์˜ interface๋ฅผ ํ˜„์žฌ ์ฝ”๋“œ์— ๋งž๊ฒŒ ๋ณ€ํ™˜์‹œ์ผœ์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.