Критика ООП
Объектно-ориентированный подход сегодня считается "самым передовым". Однако не следует слепо верить в его всемогущество. Отдача (в виде скорости разработки) от объектного проектирования чувствуется только в больших проектах и в проектах, которые родственны объектному подходу: построение графического интерфейса, моделирование систем и т.п.
Также спорна большая гибкость объектных программ к изменениям. Она зависит от того, вносится ли новый метод (для серии объектов) или новый тип объекта. При процедурном подходе при появлении нового метода пишется отдельная процедура, в которой в каждой ветке алгоритма обрабатывается свой тип данных (то есть такое изменение требует редактирования одного места в коде). При ООП изменять придется каждый класс, внося в него новый метод (то есть изменения в нескольких местах). Зато ООП выигрывает при внесении нового типа данных: ведь изменения происходят только в одном месте, где описываются все методы для данного типа. При процедурном подходе приходится изменять несколько процедур. Сказанное иллюстрируется ниже. Пусть имеются классы A, B, C и методы a, b, c:
# ООП class A: def a(): ... def b(): ... def c(): ...
class B: def a(): ... def b(): ... def c(): ...
class C: def a(): ... def b(): ... def c(): ...
# процедурный подход
def a(x): if type(x) is A: ... if type(x) is B: ... if type(x) is C: ...
def b(x): if type(x) is A: ... if type(x) is B: ... if type(x) is C: ...
def c(x): if type(x) is A: ... if type(x) is B: ... if type(x) is C: ...
При внесении нового типа объекта изменения в ОО-программе затрагивают только один модуль, а в процедурной - все процедуры:
# ООП
class D: def a(): ... def b(): ... def c(): ...
# процедурный подход
def a(x): if type(x) is A: ... if type(x) is B: ... if type(x) is C: ... if type(x) is D: ...
def b(x): if type(x) is A: ... if type(x) is B: ... if type(x) is C: ... if type(x) is D: ...
def c(x): if type(x) is A: ... if type(x) is B: ... if type(x) is C: ... if type(x) is D: ...
И наоборот, теперь нужно добавить новый метод обработки. При процедурном подходе просто пишется новая процедура, а вот для объектного приходится изменять все классы:
# процедурный подход
def d(x): if type(x) is A: ... if type(x) is B: ... if type(x) is C: ...
# ООП
class A: def a(): ... def b(): ... def c(): ... def d(): ...
class B: def a(): ... def b(): ... def c(): ... def d(): ...
class C: def a(): ... def b(): ... def c(): ... def d(): ...
Язык программирования Python изначально был ориентирован на практические нужды. Приведенное выше выражается в стандартной библиотеке Python, то есть в том, что там применяются и функции (обычно сильно обобщенные на довольно широкий круг входных данных), и классы (когда операции достаточно специфичны). Обобщенная природа функций Python и полиморфизм, не завязанный целиком на наследовании - вот свойства языка Python, позволяющие иметь большую гибкость в комбинации процедурного и объектно-ориентированного подходов.