Exist Technote
[Python] Adapter Pattern (어댑터 패턴) 본문

Adapter Pattern이란?
- 호환성이 없는 인터페이스 때문에 함게 동작할 수 없는 클래스들이 함께 작동하도록 하는 패턴.
- 클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴.
- 이미 만들어진 라이브러리를 수정하지 않고 인터페이스를 정의하고 싶을 때 사용되는 패턴.
예제
# 다른 인터페이스들을 지닌 여러 클래스.
class Dog:
def __init__(self):
self.name = "Dog"
def bark(self):
return "woof!"
class Cat:
def __init__(self):
self.name = "Cat"
def meow(self):
return "meow!"
class Human:
def __init__(self):
self.name = "Human"
def speak(self):
return "'hello'"
class Car:
def __init__(self):
self.name = "Car"
def make_noise(self, octane_level):
return f"vroom{'!' * octane_level}"
# 객체들의 인터페이스를 통합하는 어뎁터 클래스.
class Adapter:
def __init__(self, obj, **adapted_methods):
self.obj = obj
self.__dict__.update(adapted_methods)
# attr을 self에서 찾을 수 없을 때 호출되는 메서드.
def __getattr__(self, attr):
return getattr(self.obj, attr)
def original_dict(self):
return self.obj.__dict__
if __name__ == "__main__":
dog = Dog()
cat = Cat()
human = Human()
car = Car()
objects = [
Adapter(dog, make_noise=dog.bark),
Adapter(cat, make_noise=cat.meow),
Adapter(human, make_noise=human.speak),
Adapter(car, make_noise=lambda: car.make_noise(3)),
]
print('name' in objects[0].original_dict())
print('make_noise' in objects[0].__dict__)
# 단일 인터페이스로 활용되는 예제
for obj in objects:
print("A {0} goes {1}".format(obj.name, obj.make_noise()))
여담
- 덕타이핑 방식으로 setattr()를 사용할 수도 있다.
class Test:
def test1(self):
return "test1"
test = Test()
setattr(test, 'test2', test.test1)
print(test.test2())- 디스크립터 또는 데코레이터로도 설계할 수 있지 않을까?
'Design Pattern > Structural' 카테고리의 다른 글
| [Python] Proxy Pattern (프록시 패턴) (0) | 2020.10.09 |
|---|---|
| [Python] Facade Pattern (퍼사드 패턴) (0) | 2020.10.08 |
| [Python] Flyweight Pattern (플라이웨이트) (0) | 2020.10.07 |
| [Python] Composite Pattern (복합체 패턴) (0) | 2020.10.06 |
Comments