Dispatcher pattern implementation and use cases: polymorphism, router.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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