Reference
📢 공부한 내용을 바탕으로 작성하였습니다. 내용에 문제가 있다면 댓글 또는 메일 jnw__@naver.com 주시면 확인 후 빠른 수정하겠습니다. !
어댑터 패턴(Adapter Pattern)` :
인터페이스가 다른 두 클래스를 하나의 인터페이스로 변환시켜주는 구조적인 디자인 패턴
- 특정 클래스 인터페이스를 클라이언트에서 요구하는 다른 인터페이스로 변환
인터페이스가 호환되지 않아 같이 쓸 수 없었던 클래스를 사용할 수 있게 해줌✨ 객체지향 기본 원칙
- 변경되는 부분은 캡슐화한다.
- 상속보다는 구성을 활용한다.
- 구현보다는 인터페이스에 맞춰서 프로그래밍한다.
- 클래스는 확장에는 열려 있어야 하지만 변경에는 닫혀있어야 한다.
- 최소 지식 원칙(Principle of Least Knowledge)
- 객체 사이의
어댑터 패턴
제공된 시스템의 구조가 기존 것과 다르더라도 유연하게 적용할 수 있음
기존 코드
from abc import ABC, abstractmethod
class Quackable(ABC):
@abstractmethod
def quack(self) -> None:
pass
@abstractmethod
def fly(self) -> None:
pass
class Duck(Quackable):
def quack(self)->None:
print("꽥")
def fly(self)->None:
print("날고 있어요.")
class TestDuck:
def test(self, duck:Quackable)->None:
duck.quack()
duck.fly()
my_duck = Duck()
test_obj = TestDuck()
my_duck.test(my_duck)
"""
꽥
날고 있어요
"""
상황 : 칠면조 등 다른 가금류들을 구현해야 해서 외주를 맡겼는데 같은 역할을 하는 함수의 이름이 다름
- 구현된 클래스의 함수명 등을 직접 수정할 수 없다면, 어떻게 해야할까?
전달받은 칠면조 클래스
class Turkey:
def gooble(self)->None:
print("골골")
def fly(self)->None:
print("짧은 거리를 날고 있어요!")
TestDuck 클래스로 Turkey를 테스트하고 싶을 때, 어댑터 패턴을 사용해보자!
class TurkeyAdapter(Quackable):
def __init__(self, turkey:Turkey):
self.turkey = turkey
def quack(self):
self.turkey.gooble()
def fly(self):
# 오리가 나는 거리만큼 날 수 있도록 다섯 번 호출해줌
for dist in range(5):
self.turkey.fly()
테스트 코드
my_duck = Duck()
my_turkey = Turkey()
test_obj = TestDuck()
my_duck.test(my_duck)
my_duck.test(my_turkey)
"""
꽉
날고 있어요
골골
짧은 거리를 날고 있어요
짧은 거리를 날고 있어요
짧은 거리를 날고 있어요
짧은 거리를 날고 있어요
짧은 거리를 날고 있어요
"""
참고
상기 예제 코드는 객체 구성(composition)을 사용
다중 상속을 사용하는 클래스 어댑터 방식도 있음
class TurkeyAdapter(Quackable, Turkey): # 클래스 어댑터 방식 def quack(self)->None: self.gooble() def fly(self)->None: for dist in range(5): self.fly() my_duck = Duck() my_turkey_adapter = TurkeyAdapter() test_obj = TestDuck() test_obj.test(my_duck) test_obj.test(my_turkey_adapter)
객체 합성 (Object Composition):
장점 | 단점 |
---|---|
유연성과 확장성 | 더 많은 코드 작성 필요 |
런타임에 동적인 변경 가능 | |
클래스 계층 구조의 낮은 결합도 |
클래스 어댑터 (Class Adapter):
장점 | 단점 |
---|---|
상속을 이용한 코드 재사용 | 다중 상속 제한 (일부 언어에서) |
구조의 명시성 | 유연성 감소 (정적인 디자인) |