Instantly share code, notes, and snippets.

Embed
What would you like to do?
Dispatcher pattern implementation and use cases: polymorphism, router.
from abc import ABC, abstractmethod
class Dispatcher(ABC):
@abstractmethod
def _get_key():
raise NotImplementedError
@classmethod
def register(cls, key):
def wrapper(func):
cls._mapping[key] = func
return wrapper
@classmethod
def run(cls, *args):
key = cls._get_key(args)
if key not in cls._mapping:
raise ValueError
return cls._mapping[key](*args)
class Add(Dispatcher):
_mapping = {}
@staticmethod
def _get_key(args):
return type(args[0])
class Get(Dispatcher):
_mapping = {}
@staticmethod
def _get_key(args):
return args[0]
@Add.register(int)
def _(*numbers):
return sum(numbers)
@Add.register(str)
def _(*words):
return ' '.join(words)
@Get.register('/')
def _(url, *params):
return 200, 'Welcome to the candy shop!'
@Get.register('/candies')
def _(url, *params):
colors = ['calisson', 'nougat', 'macaron']
if not params:
return 200, {'candies': colors}
idx = params[0]
if idx in range(len(colors)):
return 200, {'candy': colors[idx]}
return 404, f'Candy `{idx}` not found.'
add = Add.run
assert add(1, 2, 3) == 6
assert add('hello', 'world') == 'hello world'
get = Get.run
assert get('/') == 200, 'Welcome to the candy shop!'
assert get('/colors') == 200, {'candies': ['calisson', 'nougat', 'macaron']}
assert get('/colors', 0) == 200, {'candy': 'calisson'}
assert get('/colors', 4) == 404, 'Candy `4` not found.'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment