Этот пост от @DHH о славе Basecamp и Ruby-on-Rails вызвал массу обсуждений в сети и некоторых размышлений с моей стороны. Автор утверждает, что различные абстракции хранилища теперь достаточно мощны, чтобы многие разработчики приложений на базе баз данных могли быть успешными и эффективными, не понимая деталей синтаксиса SQL или того, как именно работает система хранения. В качестве конкретного примера он приводит Basecamp 3, который обслуживает миллионы людей, но при этом не имеет полностью сформированного оператора SQL во всей своей кодовой базе, а вместо этого опирается на абстракцию Active Record, предоставляемую Rails. Active Record - это пример объектно-реляционного сопоставителя, который позволяет программисту работать с объектами на их родном языке программирования, которые затем сохраняются (относительно) прозрачно для базовой системы хранения.

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

Мне потребовалось время, чтобы понять, почему эта статья меня так раздражает.

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

Система более низкого уровня часто обеспечивает большую гибкость, а с гибкостью приходит сложность и трудный выбор для пользователя этой базовой технологии. Многоуровневую структуру можно упростить, признав, что многие приложения следуют общим шаблонам. Делая выбор, фреймворк упрощает разработку класса приложений, соответствующих этому шаблону.

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

Классы Microsoft Foundation (в качестве примера устаревания) предоставили объектно-ориентированную идиому C ++ над базовыми компонентами пользовательского интерфейса Windows. Функционально это упростило создание приложений на основе C ++, поскольку позволило изящно сочетать эти идиомы C ++ с более базовыми API-интерфейсами и передачей сообщений в среде Windows.

Любой многоуровневый подход сопряжен с множеством проблем - я говорил о них в Leaky by Design.

Во-первых, наслоение не завершено. Хотя слой пытается упростить, неизбежно просачивается некоторая основная сложность. Программисту говорят, что он имеет дело с простой системой, но затем возникают проблемы, связанные с ограничениями и ограничениями (или, наоборот, гибкостью) базовой системы. Если разработчик не создал мысленную модель этих основных характеристик, ему будет трудно распознать источник этих утечек и проблем, которые они создают, а также возможные решения по мере того, как их приложение становится все более сложным.

Как вариант, наслоение получается слишком полным. Приложение сталкивается с проблемами, потому что возможности, доступные в системе нижнего уровня, скрыты или плохо взаимодействуют с предположениями, сделанными структурой более высокого уровня. Таким образом, хотя какое-то решение должно быть возможным, оно блокируется слоем, и приложение должно делать сальто, чтобы решить проблемы. Часто эти проблемы связаны с производительностью. Поскольку производительность постоянно меняется из-за быстрой эволюции базовой аппаратной среды, упрощения, которые были неприемлемыми или чрезмерно ограничивающими для одного поколения, становятся приемлемыми для другого поколения. Использование «X» - это безумие! Пока это не так - но потому, что некоторые базовые технологии изменились, а не потому, что первоначальная оценка была неправильной.

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

Другая проблема, с которой я столкнулся с предпосылкой поста, заключается в том, что часто наиболее интересной и важной частью «сжатия» является не то, что было удалено (в данном случае много деталей о синтаксисе и администрировании SQL), а то, что осталось. Для любой системы хранения всегда остается важность локальности.

Не глядя на строчку кода, я могу гарантировать, что глубоко встроенная в дизайн BaseCamp и его абстракция Active Record глубокое понимание локальности и ее важности для обеспечения хорошей производительности. Фактически, проблема почти в каждом нетривиальном дизайне приложения - попытаться сбалансировать локальность и сложность.

Принцип нормализации закреплен в схеме базы данных как некое глубокое понимание. Но интуиция очевидна для самого экологичного программиста (или файлового клерка). Не храните одну и ту же информацию дважды. Проблема в том, что нормализация - это почти полная противоположность локальности. Причина, по которой вам пришлось хранить его дважды, заключается в том, что он вам нужен более чем в одном месте (классически, в списке клиентов и счете-фактуре). Таким образом, разработчик денормализует и добавляет «бизнес-логику» (а не дизайн схемы) для обеспечения семантической согласованности. Со временем уровень бизнес-логики становится более сложным, а поддержание согласованности становится все труднее.

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