Инкапсуляция против наследования, помочь сделать выбор

1

Мне нужно написать обработчики для нескольких разных типов case (в Python). Интерфейс для всех этих типов один и тот же, но логика обработки отличается.

Одним из вариантов будет определение общего класса, который получает конкретный тип обработчика как один из параметров __init__:

class Handler:
   def __init__ (self, handlerType):
       self._handlerType = handlerType
       self._handler = handlerType.handleStuff

   def handleStuff(self, *args, **kwargs):
       return self._handler(args, kwargs)


# case specific handlers

class Handler_Case1:
   def handleStuff(self, *args, **kwargs):
       print 'Handling Case 1'


class Handler_Case2:
   def handleStuff(self, *args, **kwargs):
       print 'Handling Case 2'



if __name__ == '__main__':
   handlers = []
   handlers.append(Handler(Handler_Case1))
   handlers.append(Handler(Handler_Case2))
   for h in handlers:
       h.handleStuff()

Однако это приводит к типу TypeError:

TypeError: unbound method handleStuff() должен быть вызван с экземпляром Handler_Case1 в качестве первого аргумента (вместо этого получил экземпляр кортежа)

Другой вариант состоит в том, чтобы имитировать абстрактную функцию, как показано здесь ( "Q: Можете ли вы реализовать абстрактные классы в Python в 0 строках кода?" ):

class Handler:
  def handleStuff(self, *args, **kwargs): abstract
  def commonFunction(self):
       print 'Common function'


 # case specific handlers

 class Handler_Case1(Handler):
  def handleStuff(self, *args, **kwargs):
      print 'Handling Case 1'


 class Handler_Case2(Handler):
  def handleStuff(self, *args, **kwargs):
      print 'Handling Case 2'



 if __name__ == '__main__':
  handlers = []
  h1 = (Handler_Case1())
  h2 = (Handler_Case2())
  handlers.append(h1)
  handlers.append(h2)
  for h in handlers:
      h.handleStuff()
      print

Итак, у меня есть два вопроса:

  • Какой из двух подходов более питонов? и
  • Как реализовать первую?
Теги:
design-patterns
inheritance
abstract-class

1 ответ

4
Лучший ответ

Я мог бы пропустить какую-то тонкую сложность в вашем вопросе, но, учитывая ваш первый пример, что мешает вам делать что-то вроде этого:

class HandlerCase1(object):
    def handle_stuff(self, *args, **kwargs):
        print "Handling case 1"


class HandlerCase2(object):
    def handle_stuff(self, *args, **kwargs):
        print "Handling case 2"


if __name__ == "__main__":
    handlers = []
    handlers.append(HandlerCase1())
    handlers.append(HandlerCase2())
    for h in handlers:
        h.handle_stuff()

И если вы хотите, чтобы классы делились некоторыми обычными (базовыми) функциональными возможностями, есть ли что-то, позволяющее вам это сделать:

class Handler(object):
    def common_function(self):
        print "Common function"


class HandlerCase1(Handler):
    def handle_stuff(self, *args, **kwargs):
        print "Handling case 1"


class HandlerCase2(Handler):
    def handle_stuff(self, *args, **kwargs):
        print "Handling case 2"


if __name__ == "__main__":
    handlers = []
    handlers.append(HandlerCase1())
    handlers.append(HandlerCase2())
    for h in handlers:
        h.handle_stuff()
        h.common_function()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню