어댑터 패턴 (Adapter Pattern)

임동혁 Ldhbenecia·2023년 4월 23일
0

Design Pattern

목록 보기
6/6
post-thumbnail

디자인 패턴: Adapter Pattern

Structural Design Pattern
Structure Pattern의 시작

  • 하나의 인터페이스를 다른 인터페이스로 전환하는 역할
    -> 이러한 역할을 Adapter Pattern에 적용
  • '이미 제공되어 있는 것'과 '필요한 것' 사이의 '차이'를 없애주는 디자인 패턴

Adapter Pattern (어댑터 패턴)

  • Adapter(어댑터) 패턴은 Wrapper(래퍼) 패턴으로 불리기도 함
  • Wrapper는 '감싸는 것'이라는 의미가 있는데, 무언가를 포장해서 다른 용도로
    사용할 수 있게 교환해주는 것이 wrapper이며, adapter라고 함
  • 두 가지 종류가 있음
    - 클래스에 의한 Adapter 패턴 (상속하는 방법)
    - 인스턴스에 의한 Adapter 패턴 (위임하는 방법)

상속 코드 예시

# Adaptee
class Banner():
  
  def __init__(self, word):
    self.word = word
    
  def showWithParen(self):
    print("(" + self.word + ")")
    
  def showWithAster(self):
    print("*" + self.word + "*")
    
    
# Target
class Print():
  
  def printWeak(self):
    pass
  
  def printStrong(self):
    pass
  
  
# Adapter
class PrintBanner(Banner, Print):
  
  def __init__(self, word):
    # 현재 클래스가 어떤 클래스인지 명확히 표기
    # Super는 여기서 Banner가 Print보다 먼저 선언되었기 떄문에 Super는 Banner 뜻함
    super(PrintBanner, self).__init__(word)
    
  def printWeak(self):
    self.showWithParen()
    
  def printStrong(self):
    self.showWithAster()
    
    
# Client
pb = PrintBanner("hello")
pb.printStrong() # *hello*
pb.printWeak() # (hello)

위임 코드 예시

# Adaptee
class Banner():
  
  def __init__(self, word):
    self.word = word
    
  def showWithParen(self):
    print("(" + self.word + ")")
    
  def showWithAster(self):
    print("*" + self.word + "*")
    
    
# Target
class Print():
  
  def printWeak(self):
    pass
  
  def printStrong(self):
    pass
  
  
# Adapter
class PrintBanner(Print):
  
  def __init__(self, word):
    self.banner = Banner(word)
    
  def printWeak(self):
    self.banner.showWithParen()
    
  def printStrong(self):
    self.banner.showWithAster()
    
    
# Client
pb = PrintBanner("hello")
pb.printStrong() # *hello*
pb.printWeak() # (hello)

### Adapter Pattern 다른 예시
class Animal:
  def walk(self):
    pass
  
class Cat(Animal):
  def walk(self):
    print("cat walking")
    
class Dog(Animal):
  def walk(self):
    print("dog walking")
    
# client
def makeWalk(animal: Animal): # 다형성
  animal.walk()
  
kitty = Cat()
bingo = Dog()

makeWalk(kitty) # cat walking
makeWalk(bingo) # dog walking
  • kitty, bingo는 각각 Cat, Dog의 객체이며 makeWalk를 통해 함수를 실행할 수 있음
class Animal:
  def walk(self):
    pass
  
class Cat(Animal):
  def walk(self):
    print("cat walking")
    
class Dog(Animal):
  def walk(self):
    print("dog walking")
    
class Fish:
  def swim(self):
    print("fish swimming")
    
# client
def makeWalk(animal: Animal): # 다형성
  animal.walk()
  
kitty = Cat()
bingo = Dog()

makeWalk(kitty) # cat walking
makeWalk(bingo) # dog walking


nemo = Fish()
makeWalk(nemo)
  • 이와 같이 당연히 Fish 클래스에는 swim 메서드만 존재하니 당연히 에러가 발생함
    이와 같은 상황에서 어떻게 해야 Fish를 연결할 수 있을까?
class Animal:
  def walk(self):
    pass
  
class Cat(Animal):
  def walk(self):
    print("cat walking")
    
class Dog(Animal):
  def walk(self):
    print("dog walking")
    
class Fish:
  def swim(self):
    print("fish swimming")
    
class FishAdapter(Animal):
  def __init__(self, fish:Fish):
    self.fish = fish
    
  def walk(self):
    self.fish.swim()
    
# client
def makeWalk(animal: Animal): # 다형성
  animal.walk()
  
kitty = Cat()
bingo = Dog()

makeWalk(kitty) # cat walking
makeWalk(bingo) # dog walking


nemo = Fish()
adapted_nemo = FishAdapter(nemo)
makeWalk(adapted_nemo) # fish swimming

FishAdapter class는 Animal을 상속받고 constructor 안에서 Fish 객체를 받음

  • Nemo는 Fish 객체이고 adapted_nemo는 FishAdapter에 nemo를 넘겨줌
  • makeWalk에 adapted_nemo를 넘겨주면 Fish의 Swim 인터페이스를 FishAdapter의 walk를 통해 불러냄
  • Adapter Pattern은 맞지 않는 기존의 인터페이스를 현재 코드에 맞게 변환해주는 역할을 함

profile
지극히 평범한 공대생

0개의 댓글