Дизайн класса Python - разделение больших классов на несколько групп для групповой работы
OK У меня есть 2 действительно больших классa > 1k строк, каждый из которых я разделил на несколько. Затем они рекомбинируются с использованием множественного наследования. Теперь мне интересно, если есть какой-нибудь более чистый/лучший более питонический способ сделать это. Полностью их факторинг приведет к бесконечным количествам вызовов self.otherself.do_something
, которые, как я думаю, не так, как это должно быть сделано.
Чтобы понять, как это выглядит в настоящее время:
from gui_events import GUIEvents # event handlers
from gui_helpers import GUIHelpers # helper methods that don't directly modify the GUI
# GUI.py
class GUI(gtk.Window, GUIEvents, GUIHelpers):
# general stuff here stuff here
Одна из проблем заключается в том, что Pylint жалуется на то, что триллионы атрибутов "init not called" / "undefined атрибут" / "атрибут, доступный до определения".
EDIT:
Вы можете взглянуть на код, чтобы сделать себе картину о том, что все это на самом деле.
http://github.com/BonsaiDen/Atarashii/tree/next/atarashii/usr/share/pyshared/atarashii/
Обратите внимание, что я действительно пытаюсь что-либо сделать, чтобы это было как можно сухим, я использую pylint для обнаружения дублирования кода, единственное, о чем он жалуется, - это импорт.
Ответы
Ответ 1
Если вы хотите использовать множественное наследование, чтобы объединить все в один большой класс (это может иметь смысл сделать это), вы можете реорганизовать каждый из родительских классов, чтобы каждый метод и свойство были либо частными (начинается с '__
') или имеет короткий префикс в 2-3 символа, уникальный для этого класса. Например, все методы и свойства в вашем классе GUIEvents
могут начинаться с ge_
, все в GUIHelpers
может начинаться с gh_
. Поступая таким образом, вы достигнете некоторой ясности использования отдельных экземпляров подкласса (self.ge.doSomething()
vs self.ge_doSomething()
), и вы избежите конфликтующих имен участников, что является основным риском при объединении таких больших классов в один.
Ответ 2
Начните с поиска классов, которые моделируют концепции реального мира, с которыми ваше приложение должно работать. Это естественные кандидаты на занятия.
По возможности старайтесь избегать множественного наследования; это редко полезно и всегда несколько запутывает. Вместо этого посмотрите на функциональную композицию (отношения "HAS-A" ), чтобы предоставить богатые атрибуты вашим объектам, сделанным из других объектов.
Не забудьте сделать каждый метод одним маленьким, конкретным; это обязательно влечет за собой разложение методов, которые делают слишком много вещей на более мелкие куски.
Рефакторинг случаи, когда вы обнаружите, что многие такие методы дублируют друг друга; это еще один способ найти естественные коллекции функциональности, которые заслуживают того, чтобы быть в отдельном классе.
Ответ 3
Я думаю, что это скорее общая проблема OO-дизайна, чем проблема Python. Python в значительной степени дает вам все классические инструменты OOP, удобно упакованные. Вам нужно будет описать проблему более подробно (например, какие классы содержат GUIEvents
и GUIHelpers
?)
Один важный для Python аспект заключается в следующем: Python поддерживает несколько парадигм программирования, и часто лучшим решением является не ООП. Это может быть и здесь. Но опять же, вам нужно будет добавить более подробные сведения, чтобы получить исчерпывающий ответ.
Ответ 4
Ваш код может быть существенно улучшен за счет реализации проекта Model-View-Controller. В зависимости от того, как ваш графический интерфейс и инструмент настраиваются, вы также можете воспользоваться "виджетами" частей вашего графического интерфейса, так что вместо того, чтобы иметь один гигантский Model-View-Controller, у вас есть основной Model-View-Controller, который управляет связью более мелкие контроллеры Model-View, каждый для отдельных частей вашего графического интерфейса. Это позволит вам разбить инструмент и графический интерфейс на многие классы, и вы сможете повторно использовать его части, уменьшая общий объем кода, который вам нужно поддерживать.
В то время как python поддерживает несколько парадигм программирования, для инструментов GUI лучшее решение почти всегда будет объектно-ориентированным дизайном.