habrahabr

Вы мне Javascript сломали

  • пятница, 25 апреля 2014 г. в 03:10:42
http://habrahabr.ru/post/220631/

Давным-давно

Раньше все писали много отвратительного JS прямо на страницах, не вдумываясь, и это было очень плохо. Подозреваю, его и до сих пор так пишут, но это делают всё те же люди, которые ни блогов, ни хабра не читают, так что давайте мы не будем о них думать (потом нам, конечно, придётся оказаться с ними в одном проекте и — господи, нет, пожалуйста, только не это)

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

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

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

Мы достигли расцвета JS

С приходом jQuery наша жизнь стала ещё лучше, и мир вокруг стал собираться из маленьких переиспользуемых плагинов к jQuery. Наконец, мы достигли расцвета, когда пришёл NPM, и мы начали использовать более-менее работоспособную систему модулей для работы с автономными виджетами.

Я представлял себе будущее, где я мог работать с отличными командами над отличным кодом из маленьких модулей и автономных функций и виджетов. Я даже думал, что нам удастся отвоевать контроль над кодом у корпоративных маньяков с их библиотеками, ОРМами, паттернами и практиками, и основанными на них фабриками фабрик сервисов.

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

Вы всё сломали

Сейчас я всё ещё иногда пишу на JS, но чаще работаю с Erlang, создавая сервисы для стриминга/перекодирования видео и всего такого (поэтому я так редко пишу в блог), но, в общем, мой бэкэнд весьма классный, и мой фронтэнд тоже вполне себе классный (я использую React от фейсбука и NPM для всего остального). Но тут я наткнулся на запись на Стэк Оверфлоу, которая напомнила мне о временах корпоративной разработки, и к своему ужасу я обнаружил, что эта венерическая болезнь, распространяемая джавой, уже появляется на лице моих интернетов.

Angular.js: сервис или провайдер или фабрика?

Ладно, этот вопрос сам по себе ещё не ужасен, давайте посмотрим на самый популярный ответ (уже не самый популярный — его заминусовали после этого поста) и впитаем всю его мудрость, которая, судя по отзывам, там несомненно есть:

Ух ты! Спасибо за подробное объяснение. Теперь всё понятно и легко. Очень круто!!

Будь я добрым человеком, я бы сказал, что этот комментарий — ирония и очень хороший пример закона По, но, прочитав всё, чувствую, что дело, увы, не в этом, и радоваться тут нечему.

Итак — первое, что мы видим — это цитата прямо из грёбаной документации Angular, которая выглядит как-то так:

В Angular «сервис» — это синглтон, создаваемый «фабрикой объектов». Эти фабрики объектов — это функции, которые в свою очередь создаются «провайдером сервиса». Провайдеры сервиса — это «функции-конструкторы». Когда происходит создание, у них должно быть свойство $get, в котором будет располагаться функция фабрики объектов.

И что это за адская хрень такая? Для меня это звучит как «для того, чтобы написать Hello world, сначала нужно создать сервис Hello world, который создаст фабрику Hello world чтобы создать сервис Hello world чтобы написать Hello world на экране».

Чтоооооа? Я что, чью-то диссертацию открыл? Это совершенно непонятно.

Нет, вы читаете не чью-то диссертацию, вы действительно читаете документацию angular.

Если бы это была диссертация, она бы наверное пыталась описать решение какой-то проблемы, вместо того, чтобы описывать переусложнённое решение выдуманной проблемы (это на самом деле не на 100% правда, учёные тоже живут в собственном мире, но почти верно)

Ниже приведён реальный пример, выдуманный для этого вопроса.

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

Сервис, Фабрика и Провайдер могут быть одним и тем же.

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

Нам дают пример «инстанцирования машины», начиная с того что

С помощью сервиса (синглтона), вы не сможете это сделать, потому что сервис нельзя инстанцировать.

Так нам объясняют, зачем нужны провайдеры, потому что

Чтобы инстанцировать, вам понадобится Фабрика или Провайдер.

Нет. Господи. ЧТО. ЧТО ЗА ХРЕНЬ.

var car = new Car({ cylinders: 4 })


Чёртово new. Мы спорили об этом в мире корпоративных бэкэндов столько раз, и снова увидеть это фуфло в JS — это просто физически больно. Весь тот же отстой в языке, который ещё недавно был моим спасением от этого отвратительного говна.

Провайдер может быть конфигурирован для вашего приложения.

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

Код, который приведён потом, я просто обожаю. Он практически уже сам пародия на себя, мне даже комментировать ничего не надо, это же просто оборжаться.

app.service('CarService', function () {
    this.dealer = "Bad";
    this.numCylinder = 4;
});
app.factory('CarFactory', function () {
    return function (numCylinder) {
        this.dealer = "Bad";
        this.numCylinder = numCylinder
    };
});
app.provider('CarProvider', function () {
    this.dealerName = 'Bad';
    this.$get = function () {
        return function (numCylinder) {
            this.numCylinder = numCylinder;
            this.dealer = this.dealerName;
        }
    };
    this.setDealerName = function (str) {
        this.dealerName = str;
    }
});


Чтобы сконфигурировать дилера, нужно всего-навсего

app.config(function (CarProviderProvider) {
    CarProviderProvider.setDealerName('Good');
});


Эй, это же всего лишь конфигурация, не надо ничего делать с настоящим кодом!!!

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

Но почему CarProviderProvider, а не CarProvider?

Вот вам мой совет. Если вы задаёте такой вопрос. Если вы задаёте вопрос, которому нужен такой ответ, к которому подходит этот вопрос, ВЫ ВСЁ СДЕЛАЛИ НЕПРАВИЛЬНО.

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

Люди, да что с вами не так?

У нас была классная штука, а вы её сломали. У нас было куда бежать от омерзительной корпоративной взаимоподдержки, но вместо того чтобы уже научиться блин программировать, вы просто перенесли свои провайдеры провайдеров фабрик в место, где ещё недавно можно было относительно легко что-то быстро сделать.

Идите к чёрту, я ухожу

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

Начинайте думать сами, бросайте эту хрень, пока не поздно и научитесь писать хоть немного нормального кода. Всё что вам нужно уже описано, у вас получится. А если вам нужно, чтобы вас держали за ручку со всеми этими фабриками и провайдерами и фабриками провайдеров сервисов, тогда поймите сразу, что миру не нужен ваш говнокод. Идите и найдите работу, в которой вы действительно преуспеете. Хватит ломать наш javascript.