목록Design Pattern (18)
Exist Technote

Template Method Pattern이란? 알고리즘의 뼈대만을 정의하고 각 단계에서 수행할 구체적 처리를 서브클래스로 미루는 패턴 활용 어떤 알고리즘의 단계 중 변하지 않는 부분을 한 번 정의하여 변하는 부분을 서브클래스에서 정의할 수 있도록 남기고자 할 때 사용할 수 있다. 서브클래스들의 인스턴스들이 공통적인 연산 알고리즘을 지닐 때 리팩토링을 목적으로 사용할 수 있다. 구조 faif # template_function에 필요한 getter들. (필수) def get_text(): return "plain-text" def get_pdf(): return "pdf" def get_csv(): return "csv" # template_function에 필요한 converter. (훅) def co..

State Pattern이란? 객체 내부의 상태에 따라 스스로 행동을 변경할 수 있게끔 허가하는 패턴. 마치 자신의 클래스를 바꾸는 것처럼 보이게 된다. 예제 변경 전의 라디오 클래스 class Radio: STATIONS = { "AM": ["1250", "1380", "1510"], "FM": ["81.3", "89.1", "103.9"] } def __init__(self): self.modulation = "AM" self.stations_point = 0 def toggle(self): if self.modulation == "AM": self.modulation = "FM" print("FM으로 전환") else: self.modulation == "AM" print("AM으로 전환") def..

Registry Pattern이란? 어떤 클래스의 모든 서브 클래스를 참조하고 싶을 때 사용할 수 있는 패턴 예제 원본 커스텀 # 메타클래스 정의(클래스를 생성하는 클래스) class RegistryMetaClass(type): def __new__(cls, name, bases, attrs): # 클래스를 생성한다. new_cls = type.__new__(cls, name, bases, attrs) # 클래스의 속성에 REGISTRY가 있다면 # bases 내에 RegistryMetaClass를 메타 클래스로 활용한 슈퍼 클래스가 있다는 의미로 간주하여 if hasattr(new_cls, "REGISTRY"): # (다중 상속에도 원하는 방식으로 동작하도록) for base in bases: if h..

Chaining Method란? 메서드가 객체를 반환하여 연쇄적으로 메소드를 이어 동작시킬 수 있는 패턴. 예제 원펀맨 훈련법 class Person: def __init__(self, start=None, end=None): self.actions = [] def traning(self, action:str): self.actions.append(action) return self @property def schedule(self): return "\n".join(self.actions) saitama = Person() # 원하는 만큼 다양한 traning을 추가할 수 있다. # 또한 체이닝만 구현한다면 다른 객체의 메서드 체인으로 넘어갈 수도 있다. saitama\ .traning("푸쉬업 100회..

Observer Pattern이란? 감시자 패턴. 객체들 사이에 일대 다의 의존 관계를 정의하여, 일 객체의 상태가 변할 때 다 객체들이 변화를 통지받아 동작을 수행할 수 있게 만드는 패턴. 구독-발행 패턴과 유사점이 많다. 예제 from contextlib import suppress # 옵저버들을 관리하는 객체 subject. 확장할 수 있도록 설계된 구조가 멋지다. class Subject: # 옵저버를 추가 or 제거 def __init__(self) -> None: self._observers = [] def attach(self, observer) -> None: if observer not in self._observers: self._observers.append(observer) def ..

Proxy Pattern이란? 특정 타 객체로 접근하는 것을 통제하기 위해 해당 객체의 대리자 또는 자리채움자를 제공하는 패턴. 인터페이스를 변경하지 않으면서 기능을 추가하기 위해 사용되는 패턴. 예제 # RealSubject의 do_the_job의 기능으로 불만족스럽다. # RealSubject를 수정하지 않으면서 기능을 추가하고 싶다. class RealSubject: def do_the_job(self, user: str) -> None: print(f"{user}(이)가 작업을 수행합니다.") # 동일한 인터페이스를 지닌 클래스를 선언하여 (ABC를 선언하여 상속해도 되겠다.) class Proxy: def __init__(self) -> None: # has 관계로 소유하여 self._real_..

Facade Pattern이란? 서브 시스템의 인터페이스 집합에 대하여 하나의 통합된 인터페이스를 제공하는 패턴. 서브시스템을 좀 더 사용하기 편하게 만드는 상위 수준의 인터페이스를 정의한다. 예제 # https://github.com/faif/python-patterns/blob/master/patterns/structural/facade.py class CPU: def freeze(self): print("Freezing processor.") def jump(self, position): print("Jumping to:", position) def execute(self): print("Executing.") class Memory: def load(self, position, data): pri..

Flyweight Pattern이란? 크기가 작은 객체가 여러 개(엄~청...) 있을 때 공유를 통해 이들을 효율적으로 지원하는 패턴. 예제 import weakref class Card: # 매핑형, 참조 카운트를 증가시키지 않아 객체가 GC에 의해 제거되는 것을 막지 못한다. _pool = weakref.WeakValueDictionary() def __new__(cls, value, suit): obj = cls._pool.get(value + suit) if obj is None: obj = object.__new__(Card) obj.value, obj.suit = value, suit cls._pool[value + suit] = obj return obj def __repr__(self): ..

Composite Pattern이란? 객체들의 관계가 트리 구조(단일-복합)로 구성되어 있고 단일 객체와 복합 객체를 동일하게 다루어야 할 때 사용되는 패턴. 점->선->면(그리기, 지우기...), 파일->폴더(삭제, 이동...) 예제 from abc import ABC, abstractmethod # 복합객체와 단일객체가 동일하게 갖추어야 하는 인터페이스를 정의 class Tree(ABC): @abstractmethod def render(self): pass class Leaf(Tree): NUMBERING = 1 def __init__(self): self._number = self.NUMBERING self.__class__.NUMBERING += 1 def render(self, deep=0, ..

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 = "Huma..