Я думаю, вы также можете использовать здесь шаблон «цепочки ответственности»:
Шаблон позволяет нескольким объектам обрабатывать запрос без привязки класса отправителя к конкретным классам получателей.Цепочка может быть динамически составлена во время выполнения с любым обработчиком, который следует стандартному интерфейсу обработчика.
Преимущество использования этого шаблона состоит в том, что вы можете определять и расширять различные счетчики в отдельных модулях и динамически объединять ихво время выполнения на основе проблемных условий.Вот как вы можете это сделать.Сначала определите родительский класс оценщика:
from functools import reduce
class BaseScorer(object):
def __init__(self):
self._next_scorer = None
def set_next(self, scorer):
self._next_scorer = scorer
return scorer
def _call_next(self, house, score):
if self._next_scorer is None:
return score
return self._next_scorer.score(house, score)
def score(self, house, score=0):
raise NotImplementedError
@staticmethod
def chain(scorers):
reduce(lambda x, y: x.set_next(y), scorers)
return scorers[0]
Затем определите различные классы оценщика, например:
class WindowScorer(BaseScorer):
def score(self, house, score=0):
if house.windows > 2:
score = score + 10
return self._call_next(house, score)
class GarageScorer(BaseScorer):
def score(self, house, score=0):
if house.garage:
score = score + 10
return self._call_next(house, score)
class FenceScorer(BaseScorer):
def score(self, house, score=0):
if house.fence == 'broken':
score = score - 5
return self._call_next(house, score)
И вот как это можно использовать:
scorer = BaseScorer.chain([
WindowScorer(),
GarageScorer(),
FenceScorer()
])
house = House(windows=4, garage=True, fence='nice')
score = scorer.score(house)