генеалогия как сушилка для мозгов
Jul. 6th, 2022 01:13 pmЯ, только что понял, что меня больше всего бесит в ООП (вне зависимости от языка). Это _генеалогия_. Рассказы о том, кто кому является родителем и кто потомок. Существуют редчайшие случаи, когда онтология предметной области хорошо ложится на концепцию предок-потомок (в смысле ООП).
Чаще всего это набор риторических упражнений, не имеющий отношения ни к коду, ни к предметной области.
(рандомный пример: Если я работаю с API двух разных провайдеров, то у меня нет "предка" этих API, у меня есть два разных API к которым я хочу иметь одинаковый интерфейс - и рассказы про "предка" GenericApi, из которого пояются FooApi и BarApi - херня и натягивание задачи на генеалогию).
Вот любой рассказ про "обобщённую генеалогию" в ООП вызывает у меня мгновенное иссушение мозга. Я не понимаю зачем я должен использовать эту модель, почему именно эту модель и почему эта модель должна занимать у меня в голове больше места, чем предметная область, которую я пытаюсь охватить.
Я бы даже сказал, польза от ООП заканчивается на концепции класс/инстанс. Это разумное деление, хотя, например, Rust прекрасно без этого обошёлся с помощью понятия "структура" и "методы на структуре". В этом месте, кстати, класс, рассыпается на две более разумные конструкции: структура (тип данных); инстансы этой стурктуры (значения типа) и методы, которые связаны со структурой. Это деление автоматом устраняет "кашу" из данных и методов в обычных классах, и любой код в котором "метод - это элемент структуры" начинают выглядеть ровно так, как выглядят - странно и привлекая к себе внимание.
Есть одна область, в которой я очень люблю наследование и считаю его разумным. Это исключения. Хорошо сделанная система наследований исключений позволяет перехватывать исключения на нужном уровне общности. Это как раз пример ситуации, когда иерархия наследований хорошо ложится на предметную область.
И то! Комфортнее всего с ними работать, когда все эти "наследуемые" исключения или 'pass' (т.е. не имеют ничего своего, кроме типа), или имеют доп. методы, которые никаким образом старые не ломают.
В большинстве же случаев в Питоне классы и наследование используется не для передачи смысла, а как странный метод композции; и чаще всего от безысходности.
Чаще всего это набор риторических упражнений, не имеющий отношения ни к коду, ни к предметной области.
(рандомный пример: Если я работаю с API двух разных провайдеров, то у меня нет "предка" этих API, у меня есть два разных API к которым я хочу иметь одинаковый интерфейс - и рассказы про "предка" GenericApi, из которого пояются FooApi и BarApi - херня и натягивание задачи на генеалогию).
Вот любой рассказ про "обобщённую генеалогию" в ООП вызывает у меня мгновенное иссушение мозга. Я не понимаю зачем я должен использовать эту модель, почему именно эту модель и почему эта модель должна занимать у меня в голове больше места, чем предметная область, которую я пытаюсь охватить.
Я бы даже сказал, польза от ООП заканчивается на концепции класс/инстанс. Это разумное деление, хотя, например, Rust прекрасно без этого обошёлся с помощью понятия "структура" и "методы на структуре". В этом месте, кстати, класс, рассыпается на две более разумные конструкции: структура (тип данных); инстансы этой стурктуры (значения типа) и методы, которые связаны со структурой. Это деление автоматом устраняет "кашу" из данных и методов в обычных классах, и любой код в котором "метод - это элемент структуры" начинают выглядеть ровно так, как выглядят - странно и привлекая к себе внимание.
Есть одна область, в которой я очень люблю наследование и считаю его разумным. Это исключения. Хорошо сделанная система наследований исключений позволяет перехватывать исключения на нужном уровне общности. Это как раз пример ситуации, когда иерархия наследований хорошо ложится на предметную область.
И то! Комфортнее всего с ними работать, когда все эти "наследуемые" исключения или 'pass' (т.е. не имеют ничего своего, кроме типа), или имеют доп. методы, которые никаким образом старые не ломают.
В большинстве же случаев в Питоне классы и наследование используется не для передачи смысла, а как странный метод композции; и чаще всего от безысходности.
no subject
Date: 2022-07-06 03:05 pm (UTC)Ну сколько-нибудь продвинутый ООП оперирует не отношением «предок/потомок», а отношением «надтип/подтип». Граница проходит по тому месту, где объясняют LSP (не тот, который протокол между редактором и языковым сервером, а принцип подставляемости имени Варвары Ивановны Лисковой).
Дальше мы имеем ту же самую решётку типов от
typing.NoReturnдоobjectчерезCallable,Hashable,Reversible,Iterable,Sized,Collection,Container,Mapping,MutableMapping,Sequence,MutableSequence,AbstractSet,MutableSet,Iterator,Generatorи всё такое прочее. Только где-то отношения «я подтип вон того» требуется указывать явно на определении класса/интерфейса (Java, C++), а где-то они выводятся компилятором (TypeScript).А наследование реализации много где объявлено не лучшим способом композиции.