«Классы — это не объектно»: интервью Егора Бугаенко с Дэвидом Уэстом

Смелые взгляды Егора Бугаенко на ООП и Java, которыми он делится в блоге и книге, неизменно вызывают большой резонанс: например, опубликованный в нашем хабраблоге диалог Егора с Барухом Садогурским собрал более 300 комментариев и 30 000 просмотров. Отчасти эти взгляды сформировались под влиянием книги «Object Thinking», и недавно Егор взял у её автора Дэвида Уэста интервью в формате двух видеороликов. В первом же ролике встречается множество острых заявлений от Уэста (от того, что идея объектов толком не была воплощена, до того, что классы в ООП не нужны), и мы перевели его содержание на русский.

Егор Бугаенко: Я приготовил вопросы в трёх частях: сначала общие, затем о конкретных практиках и идеях, а в конце о будущем. Для начала хочу спросить: откуда вы начали? Как вы пришли к этой книге? Какой у вас бэкграунд?

Дэвид Уэст: Я был разработчиком большую часть моей жизни. Начал в 1968-м, в том году, когда появился сам термин «software engineering». Я программировал на COBOL, работал почти во всех областях разработки ПО, вплоть до IT-менеджера в государственном агентстве.

Я не был доволен результатами, поэтому отправился доучиваться. Взялся одновременно за антропологию и computer science. Идея была в том, что computer science научит программированию и техническим вещам, а антропология человеческим — работе в команде, управлению, всему этому.

Я защитил диплом, получил работу профессора, причём работу мне дали в первую очередь за практический опыт и знания, а не за академические результаты. Начал преподавать структурный анализ и проектирование.

Но времена менялись. Идея объектов начала выходить на первый план. Я основал объектную лабораторию в университете. У нас были реальные клиенты, так что мы занимались и коммерческими семинарами, и работали над разработкой — и, конечно, преподавали академическую программу по объектам. Так что мы поймали эту волну с самого начала.

Первой коммерческой версией Smalltalk стал Smalltalk-80. Smalltalk был на пути к тому, чтобы отобрать у COBOL звание самого популярного языка программирования в мире. А к 1996-му Smalltalk был мёртв, потому что все писали на Java.

И я написал книгу, когда набирал популярность agile. Agile создали люди, привыкшие заниматься объектами. Если посмотрите на его основателей — будь то extreme programming, scrum, ещё что-то — они все писали на Smalltalk. У людей вроде Кента Бека и Уорда Каннингема, придумавших CRC-карты, всё крутилось вокруг объектов и поведения. А не вокруг типов данных, как у тех людей, которые позже стали доминировать в объектном мире и практически убили его.

И они проектировали объектно, но никогда этого не говорили. Они просто предполагали, что все знают, о чём речь. И я написал книгу, чтобы сказать: «Слушайте, если вы занимаетесь agile, вам надо понимать объектное проектирование».

object_thinking

Егор: Почему, по вашему мнению, Smalltalk умер?

Дэвид: Ну, не вполне умер. Изначально это был очень успешный проект в Xerox PARC, а потом произошли две вещи. Первая из них — Apple. Все знают эту историю о том, как Apple пришли в Xerox PARC и украли там идеи локальной сети (сделав AppleTalk) и графического интерфейса (поместив его в Mac и Lisa). А вот чего люди не знают: когда они пришли в первый раз, в PARC было запрещено показывать им Smalltalk. Xerox не хотели, чтобы его увидели, потому что эта разработка считалась лучшей из всех.

Стив Джобс устроил шумиху, менеджмент Xerox заставил PARC показать ему Smalltalk, и он был восхищён, но они не хотели лицензировать ему язык. Если бы захотели, Smalltalk стал бы языком Apple. Вместо этого в Apple создали для тех же задач Object Pascal.

Несколькими годами позже Xerox PARC купили крупнейший Smalltalk-продукт, Digitalk. У него были сотни тысяч пользователей. А у Xerox были пять тысяч коммерческих пользователей, но денег было гораздо больше, так что они купили Digitalk. И затем они попытались навязать Digitalk-сообществу такое же лицензирование, какое у Xerox было для корпоративных партнёров. А в итоге просто убили весь энтузиазм.

К тому моменту Smalltalk, по сути, стал опенсорсным, и появился Squeak. И в Европе процветающее Squeak-сообщество. Так что Smalltalk не мёртв, просто он в Европе, а не в США.

А кроме того, в Sun тоже хотели лицензировать Smalltalk. Там хотели сделать его основным языком на всех своих компьютерах. Но в итоге не согласились с теми условиями лицензирования, на которых настаивал Xerox.

В общем, язык мог занять задуманное ему место, но совершались бизнес-ошибки. Sun так разозлились, что инициировали создание Java, так что Java была задумана как убийца Smalltalk. В общем-то, и убила. Был интересный период около четырёх лет, когда Smalltalk мог сделать в тысячу раз больше Java, но она была доступна бесплатно, а Smalltalk за деньги, и в итоге всё провалилось просто по экономическим причинам.

В Smalltalk можно было запускать Java-байткод. Был один интерпретатор, и его не волновало, имеет он дело с Java-байткодом или Smalltalk-байткодом.

Егор: Java убила только Smalltalk, или вообще ООП?

Дэвид: Java убила и ООП. До неё шли бурные дебаты между лагерями С++ и Smalltalk по поводу того, что из них «настоящий ОО-язык». В местах вроде конференции OOPSLA дискуссии доходили чуть ли не до драк. Это было похоже на религиозные войны, настолько обе стороны были упёртыми и активными.

Но вообще-то C++ не объектно-ориентированный, он никогда и не задумывался таким. Если почитать, что Страструп писал во время создания C++, оказывается, что он просто хотел сделать программистов на C дисциплинированнее. Он чувствовал, что они слишком неуправляемые, а в итоге не пишут хороший код. Так что C++ был задуман для того, чтобы заставить их писать более хороший и более дисциплинированный код.

Но он ни разу не называет его объектно-ориентированным языком. Другие люди сказали: «Ну, у вас в C++ классы, значит, вы объектно-ориентированные, как Smalltalk». Но ООП не было задумкой.

А в Java было. Java позиционировала себя как объектно-ориентированная, в ней заимствовали кучу идей из Smalltalk. Но в то же время посылать сообщения от объекта к объекту требует машинных ресурсов, и возможно было сэкономить на них, добавив “dot notation“. Поэтому в Java её добавили, в то время как Smalltalk никогда бы не позволил сделать что-то с объектом без отправки ему сообщения.

Как Страуструп в C++, они либо делали то, что выгодно компьютеру, либо находили другие пути.

«Java объектно-ориентированная» — это маркетинговая уловка

Егор: То есть dot notation, Java, C++ — всё это убило идею ООП? А в школах учат, что Java — это и есть ООП.

Дэвид: Это всё маркетинговая уловка. Когда Java пыталась завоевать рынок, было очень удобно говорить, что она объектно-ориентированная, потому что люди хотели этого.

Это неправда. Но идея объектов вообще никогда не была по-настоящему воплощена в каком-либо языке, даже в Smalltalk. Потому что люди постоянно пытались пойти на компромисс в том, что можно делать с машиной. Что поймёт машина, что ты можешь скомпилировать, и как заставить это работать эффективно.

Так что, например, всё понятие класса — это не объектно-ориентированно. Классы не имеют никакого отношения к объектам. Но они были способом эффективно хранить код, позволяя вносить изменения в одном месте вместо многих сразу.

Ближайшее, что когда-либо было к настоящему ОО-языку — Self. Там нет ничего, кроме объектов, там только один класс, или один тип сущностей, и эта сущность — объекты. Там можно использовать методы и переменные, можно клонировать, но нет такого явления, как класс. Однако у Self никогда не было большой популярности.

Егор: Я встречаю в блогах, академических работах и на конференциях утверждения, что всё ООП в целом плохое. В основном от функциональных программистов. Люди из Lisp приходят и говорят: «Это какой-то бардак». Могу привести цитаты, но вы и сами наверняка знаете.

Дэвид: Любопытно с этими функциональщиками. Они переизобретают заново то, что было в Smalltalk, но дают этому другие названия — «динамический», «функциональный». А потом из кожи вон лезут, чтобы заявить «ой, объекты никогда не работали». Это защитный механизм.

А затем им приходится переизобрести ещё кучу вещей, чтобы функции работали. Посмотрите на мир вокруг — вы много функций видите? Я не вижу. А объектов зато вижу выше крыши.

Когда пишешь драйвера или что-то вроде, работаешь на машинном уровне, функциональное программирование очень осмысленно, потому что твоя область интереса — это машина. Но если программа используется для расчёта зарплаты, то в функциональном случае её проектирование становится сложным и запутанным, приходится переводить реальность на язык функций.

В этом главное преимущество Smalltalk: вы берёте реальность и воплощаете её в коде без этих трудностей перевода.

Егор: А что всё-таки насчёт цитат «ООП — плохо»?

Дэвид: В определённом смысле они абсолютно верные. Я уже это упоминал: неэффективно отправлять сообщение вместо простого прямого «get». Это медленнее, а если использовать наследование как в Smalltalk, то всё становится ещё хуже.

Потому что ты отправляешь сообщение объекту. Объект отвечает «Понятия не имею, как на это реагировать». Тогда отправляется сообщение классу: «Знаем ли мы, что с этим делать?» Если и класс не знает, то отправляется суперклассу. Так что накапливаются все эти циклы работы процессора до того, как придёт ответ. И в этом смысле, да, программирование на Smalltalk очень неэффективное. А значит, плохое, да?

А есть ещё и другие примеры ситуаций, в которых код на Smalltalk выполняется медленнее. Так что люди долго говорили «На Smalltalk нельзя писать системы, работающие в реальном времени, не хватит перфоманса».

Но две разные группы людей опровергли это. Дейв Томас был одним из самых ранних сторонников Smalltalk и ООП. Он работал в канадском Карлтонском университете, и Smalltalk стал языком, с которого там начинали обучение программированию. Он основал компанию, которую позже продал IBM, и они писали на Smalltalk софт, работающий в реальном времени на самолётах-истребителях. А чтобы истребитель не сбили, необходим быстрый софт!

А ещё была компания в Техасе, занимавшаяся power switching systems, и там необходимо было укладываться в наносекунды, микросекунды. Они тоже писали на Smalltalk, а когда дело доходило до перфоманса, прибегали к маленьким хитростям, вроде прекомпиляции вызовов методов. Так что не приходилось постоянно интерпретировать сообщения.

Но при этом требовалось два месяца, чтобы создать и протестировать программу, а затем ещё две недели на оптимизацию. Или можно было взять C++ и сделать всё за месяц. Выбор за вами. Но люди, похоже, не переживали.

Они жалуются на собственную неспособность написать код хорошо

Егор: Жалуются не только на перфоманс. Говорят, что ООП приводит к спагетти-коду. Что вы об этом думаете?

Дэвид: Что они жалуются на собственную неспособность написать код хорошо! Я знаю язык. Да, когда пишешь на Smalltalk, результат может выглядеть как спагетти-код. Чтобы понять, что происходит, надо проследовать за всеми этими сообщениями, идущими через систему. Когда доходит до дебаггинга, там сплошной список отправленных сообщений. И надо найти то, с которым возникла проблема, и понять, почему объект повёл себя не как предполагалось. У меня были студенты, которые писали программу на Smalltalk, а потом тратили недели на попытки разобраться в происходящем внутри.

Хорошо спроектированная программа на Smalltalk должна отражать коммуникацию между равными. Там нет «главного», как в Java. Нет одного места, из которого исходит весь контроль. И в итоге выглядит так, будто нет вообще никакого контроля, никакой логики, никакой последовательности.

Но преимущество в том, что писать программу становится гораздо проще. И требуется гораздо меньше кода.

Представим, что вы используете старый стиль программирования, изобретённый в 60-е. Превыше всего у вас будет главный контролирующий модуль, принимающий все решения. Кроме этого, будут модули, получающие информацию, преобразующие её, выдающие output. Но только главный модуль понимает всё о происходящем. И всё становится запутаннее и запутаннее.

Можно сравнить с 1950-ми в СССР, когда хотели централизовать экономику и принимать все решения в Москве. Можно представить себе, насколько сложно всё получается, и мы знаем, к чему это привело. То же верно и в случае с кодом.

Есть выбор: либо чёткий контроль, либо простота, удобство, гибкость, адаптируемость. Но у программистов на Java и C++ нет выбора. В Java нельзя создать класс без создания главной процедуры. Идея разделения на главную процедуру и подпроцедуры так засела в головах у программистов, что они не могут перерасти её и писать хорошо функционирующий объектный код.

Егор: Звучит логично. А теперь практические вопросы. Первый о классах, очень меня интригует. Можно подробнее о том, что они не нужны? А то я их пишу.

Дэвид: Так у вас и выбора нет!

Идея в том, что есть объекты, а в них код. Если два объекта похожи, то и код будет похожим. И проще менять одинаковый код в одном месте, а не двух разных. И классы были лёгким способом собрать эту общую информацию в одном месте. Это компромисс.

Объекты появляются по-разному. В C++ фабрика классов, в Smalltalk иначе. Но всё это лишь удобства для программиста. Это не важно для идеи объекта. Это просто облегчает жизнь. И в моей книге я говорю, что это вторичный концепт.

Объекты, сообщения, инкапсуляция — вот что критично. А классы и наследование — компромиссы, связанные с практическими моментами и возможностями машины.

Класс ничего не должен делать

Егор: Но в Java классы — не просто формочки для объектов. Мы туда помещаем методы…

Дэвид: А зря!

Егор: Вот в этом и мой вопрос!

Дэвид: Ну, как я попытался сказать в книге, класс ничего не должен делать. В Smalltalk есть методы классов, но не надо их использовать. Их использование — возвращение к командному способу мышления. Вы берёте то, что должно быть ответственностью объектов, и по каким-то причинам пытаетесь запихнуть это всё в класс. И в итоге класс делает многое за объекты.

Люди выдумывают аргументы о том, почему они делают что-то определённым способом. Но это плохие аргументы. Они никогда толком не задумывались об альтернативе. Отговариваться проще.

И в Smalltalk, изначально дав методы классов, спровоцировали людей делать так. Я никогда за 30 лет не слышал ни одной хорошей причины использовать метод класса.

Егор: Я могу её привести. Например, возьмём Android SDK, это сплошная Java. Google продвигает его. И Google поместил в Android SDK прямые указания для программистов использовать статические методы, являющиеся методами классов, потому что они быстрее. Там говорят: «Андроид медленный, поэтому не используйте объекты, делайте их как можно меньше, всегда пытайтесь положиться на статические методы».

И с этим связан мой следующий вопрос: перфоманс против объектно-ориентированного мышления. Как тут поступать?

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

Если у тебя архитектура, как у 500-этажного здания, то да, тебе нужен очень быстрый лифт! Но точно ли 500-этажное здание лучше всего подходит для этой проблемы? Может, лучше разбить всё так, чтобы был набор лифтов поменьше? Разделить функциональность Android так, чтобы ни одна часть не оказывалась слишком большой и не требовала статических методов?

Практически всегда существует альтернативный подход, который убирает проблему. Операционные системы — вот уж где больное место объектов. Я пару лет преподавал объектно-ориентированные ОС. Люди говорят, что архитектура у ОС одинаковая, всегда с главным контролем. Но если отталкиваться от объектов реального мира, то компьютер — это набор компонентов. И каждый компонент мог бы брать ответственность. «Я жёсткий диск, я могу принять вашу строку и сохранить её, дать её вам снова, хранить её от повреждений. И могу даже выстраивать очередь. Если мне приходит сразу два запроса на сохранение чего-либо, могу сам их выстроить, а не ждать, пока ОС скажет, какой раньше делать».
Дайте компонентам компьютера распределённые возможности, и ОС превратится в пару тысяч строк кода. А не — сколько там в Windows сейчас, триллионы строк?

Перфоманс всегда идёт в последнюю очередь

Егор: Мой вопрос был в следующем: где баланс между перфомансом и красивым дизайном? Некоторые говорят, что перфоманс важнее, мы пишем код для компьютеров, это просто инструкции. Кого вообще волнует, что там внутри, зачем уделять столько внимания этому? «Я могу сделать это статическими методами, это будет работать, и побыстрее, чем у вас».

Дэвид: Если бы речь шла о том, что нужно написать один раз и забыть, это было бы правдой. Но когда в последний раз вы писали что-то, что не требовало затем изменений? Спустя полгода, год, десять лет? И если вы пишете неэффективно, код сработает нормально сегодня, но его будет невозможно поддерживать, когда требования изменятся.

Десять лет назад на самом новом и мощном компьютере IBM включали режим эмуляции IBM 1401, компьютера 1959 года. У вас есть компьютер, который способен выполнять триллионы операций в секунду, а вы включаете на нём режим эмуляции 1401, чтобы запустить кусок кода, который сегодня уже никто не понимает, потому что он по-прежнему важен для компании.

Егор: Так что должно идти в первую очередь, перфоманс или…

Дэвид: Перфоманс всегда идёт в последнюю. Можно проследить это до 70-х. Посмотрите на мануалы для программистов тех времён — они все говорят, что перфоманс идёт в последнюю очередь. Вы сначала проектируете, кодите, тестируете, а только потом задумываетесь, как сделать это быстрее.

Потому что в долгосрочной перспективе важен не перфоманс. Он изменится уже через год, когда выйдет новый компьютер. В чём смысл тратить кучу времени на оптимизацию для компьютера, который устареет через полтора месяца? Но вот если спроектировано всё правильно, тогда на новый компьютер перенесётся отлично.

Однако мы живём в прагматичном мире. Каков в agile типичный срок работы программиста на одном месте?

Егор: Наверное, год.

Дэвид: А среднее время на один проект?

Егор: Думаю, больше года. Может, два.

Программистам не приходится иметь дело с последствиями собственных действий

Дэвид: Да. Значит, по всей вероятности, вы как программист сначала будете над чем-то работать, а когда оно сломается, вы уже будете в другом месте. И в чём тогда ваша мотивация делать всё правильно? Это чья-то чужая проблема.

Это звучит очень цинично, и я не говорю, что сами программисты думают об этом в таких категориях. Но экономическая и социальная ситуации таковы, что практически никогда не приходится иметь дело с последствиями собственных действий. Никого не увольняют, а даже в случае сокращения человек через два дня работает на новом месте, у него нет проблем.

Егор: Это плохо для индустрии? А какими должны быть последствия для программиста?

Дэвид: Я думаю, репутационными. Репутация должна быть чем-то, чем вы гордитесь. Она должна создаваться окружающими: «Да, я работал с Егором, он пишет прекрасный код» или «Никогда больше не буду с ним работать, он плохо кодит, и при этом помыкает всеми». Стоило бы иметь хотя бы такие последствия.

А ещё были многочисленные попытки лицензировать деятельность разработчиков. В Техасе вы даже не можете называть себя «software engineer» без лицензии.

Если инженеры проектируют мост и он падает, их судят. В софте такого нет, хотя у нас тоже… Вы слишком молоды, чтобы помнить Therac-25. Это был устройство для лучевой терапии раковых больных, софт которого был написан так плохо, что время от времени уровень облучения оказывался в сотню раз выше требуемого. Оно убивало пациентов или наносило им большой вред. И никто не был призван к ответственности за это. Никто не попал в тюрьму. Компания не была закрыта. Чего мы ждём?

Но в первую очередь мне хочется репутации — полу-формализованного способа оценивать друг друга. Это часть того, чтобы быть профессионалом, так?

ООП — ни императивное, ни декларативное

Егор: Звучит разумно. Ещё один практический вопрос: по-вашему, ООП императивное или декларативное? Мы с друзьями много спорим об этом.

Дэвид: А можно мне сказать «ни то, ни другое»? Это категория сама по себе, зависит от того, что вы делаете.

Можно отправить объекту императивное сообщение: «Ты теперь X». Сеттер — это императивно. А можно спросить коллекцию «У тебя есть синие штуки?», и это уже interrogative. Это смесь всего, зависит от того, что за сообщение посылаешь. Как категория это существует отдельно от «декларативно/императивно».

Все эти названия… Объект почти всегда — сам себе группа. Он не принадлежит ни к какой из этих категорий. Но можно заставить его выглядеть как угодно.

Если вспоминать о главном «контролирующем всё» модуле, то как вы контролируете его самого, его сложность? Если мой модуль не принимает решений, он просто отдаёт приказы по заранее заданной инструкции. Это последовательность, которая обычно верна. А если он пытается разобраться «что происходит, как я веду себя в этой ситуации», такое гораздо сложнее написать.

Егор: Императивное проще писать и понимать?

Дэвид: Оно может быть проще, но оно совершенно негибкое. Оно будет работать в заданных обстоятельствах, и если что-либо меняется… Если требования меняются хотя бы немного, надо всё переписывать.

Егор: А что вы думаете о популярной сейчас интеграции ООП и функционального программирования? Например, в Java добавляют многое из функционального программирования. Смешение двух парадигм — правильное направление, или..?

Дэвид: Вероятно, это было необходимо. Впрочем, ничего нового. Уже при создании Java в неё намеренно включали вещи и из Smalltalk, и из C. Это ещё тогда был гибрид процедурного и объектного программирования.

Посмотрите на Ruby. Там попытались эмулировать и Java, и C, и Smalltalk.
Есть старая поговорка о том, что нужно иметь набор инструментов, а не один инструмент. Так что людям дают возможность использовать нужное: если проблема требует функции — можно использовать функцию, если класса или объекта — можно создать объект.

И это правильно, нужны разные инструменты для разных задач, и для программиста эффективнее, когда они все в одном языке. Но тут опять есть психологическая проблема, а не техническая. Если вы начали программировать на языке X, а теперь используете Y, в котором есть возможности из X, Q и P, то какие будете использовать?

Егор: Того языка, с которого начинал.

Дэвид: Да, будете использовать всё подряд из X, а из P и Q очень мало. И это не имеет отношения к тому, что лучше подходит в конкретном случае. Так что мы имеем дело с человеческой психологией. Иногда можно увидеть Ruby-программистов, которые на самом деле пишут в Ruby на Java.

Люди не очень сильны в прекрасной логике

Егор: Моё беспокойство связано с тем, что люди приносят эти функциональные возможности в ООП, и мы теряем идею объектно-ориентированности.

Дэвид: Если вы разрабатываете язык, и вам нужно удерживать пользователей, вы всегда делаете компромиссы между тем, что хотите сказать, тем, о чём хотите сказать, и тем, что позволяет сделать компьютер.

Старые компьютеры были тупыми. Их язык был очень узким и ограниченным. А мир очень интересный и сложный. Пытаясь создать новый язык, вы пытаетесь создать что-то, что и компьютер может понять, и программист может понять, и программист сможет использовать для решения реальных проблем.

И вы хотите сделать переход как можно мягче. С языками вроде C тут всё сложно. Язык C — это то, на чём говорит программист, а больше никто. И на программиста ложится тяжкая ноша: надо разобраться в реальном мире, придумать решение проблемы в реальном мире, а затем перевести это на код в C.

А язык вроде Smalltalk включает в себя модель настоящего мира. Порой это метафора. Если рисуешь объект в Smalltalk, используешь Pen. Что можно сделать с ручкой в реальном мире? Получается интеллектуальная модель, позволяющая выражать вещи легче, чем в других языках.

В каждом языке своя модель, в функциональных она основана на математике и матанализе. Легко ли её использовать? Многие ли ваши коллеги хорошо знают матанализ? В итоге перевод получается сложнее, модель плохо подходит.

Лучший пример — реляционные базы данных. Кодд придумал эту математическую модель информации и способ хранить данные. Сказал, что для организации данных таким способом нужно писать SQL-запросы. Можно математически доказать, что запрос приведёт к корректным результатам.

Но никто не понимает, как правильно писать SQL. Там прекрасная логика. Но люди не очень сильны в прекрасной логике. Реляционная модель не ощущается естественной. Это не то, как мы думаем о вещах. И в итоге на декомпозицию, нормализацию уходит столько сил, что это теряет красоту.

В итоге мы тратим триллионы долларов, просто пытаясь заставить это работать. К чему прекрасная модель, если не можешь её имплементировать?

И то же самое с языками программирования. Если ваш основан на неестественной модели, которая делает написание кода сложнее, а не проще…

Есть класс млекопитающих, класс птиц, а потом сталкиваешься с утконосом, и всё ломается

Егор: А можете развернуть тему наследования? А то вы называете его ношей, а я в числе многих других его использую, но ощущаю, что что-то с ним не так.

Дэвид: На наследование можно посмотреть по-разному. Можно рассматривать его как таксономическую структуру, которая обеспечивает понимание.

Когда в комнате много детей, гораздо проще сказать «Дети, угомонитесь», чем «Джон, Дожи, Джо, Салли и Бекки, угомонитесь». Мы используем таксономии, чтобы осмысленно взаимодействовать с миром.

Но порой случаются ошибки. И в случае с наследованием в программировании это проще простого. Когда выстраиваем большую иерархию, таксономии всегда ломаются.

Посмотрите на систему Линнея. Карл Линней пытался категоризировать все растения и животных в мире. И тогда получается класс млекопитающих, класс птиц, а потом внезапно сталкиваешься с утконосом. У него есть мех, и он откладывает яйца. Всё ломается.

Таксономии всегда ломаются, или становятся слишком сложными. Если я попал в аварию и лишился руки, я больше не принадлежу к вашему классу, у вас две руки, а у меня только одна. И я создаю новый класс.

Считается, что чем больше классов создашь, тем проще становится переиспользовать вещи. Неправда, всё становится сложнее.

Насколько я знаю, крупнейшим в мире проектом на Smalltalk был проект LYNX в Cargill, крупнейшей частной компанией в США. Когда они его затеяли, компания только-только закончила тратить миллионы долларов на создание enterprise-wide data map. Они подумали, используем это, и вставили в свой проект это всё. Они думали, что это сэкономит им деньги благодаря наследованию. Но это не так. Вы неправильно понимаете наследование.

Егор: Потому что это основано на данных.

Дэвид: Потому что это основано на данных, а не на поведении. С поведением приходишь к совсем другой таксономии. Если отталкиваться от него, то набор возможных поведений для человека универсален — не важно, какого цвета твоя кожа. Тогда почему нам не пользоваться одним классом «человек» вместо деления на чернокожих, белых, скандинавов, русских?

И не следует превращать всё в многоуровневую пирамиду. Вместо этого наследование должно быть очень широким, и всего на паре уровней.

  1. Егор Бугаенко
    Егор уже более десяти лет CTO в Teamed.io — софтверной компании с уникальной методологией разработки в распределенном режиме. Егор регулярно пишет на www.yegor256.com, пишет на Java в rultor.com, takes.org и jcabi.com. Егор живет то в Пало-Альто, то в Киеве. @yegor256