Pull to refresh

Comments 20

Бросайте уже пытаться сделать из яваскрипта яву или сишарп с их мощными IDE, compile-time проверками и статической типизацией.
Если тут у вас возникает сильное желание использовать DI, то имхо проблема в ваших программистских скилах/неправильном подходе, а не в сложности или объёмности проекта.
Интересно, кстати, утверждение про тесты с учётом того, что в проекте на гитхабе они напрочь отсутствуют.
DI и вездесущие фабрики(об этом речь не велась, но близкая по духу вещь), распространённые в других языках, во многих случаях являются вынужденным овеэнженирингом, обусловленным либо изначально неправильной разработкой не в TDD/BDD стиле, с итоговой получающейся кривой и труднотестируемой архитектурой, либо негибкостью самого языка(статическая типизация). Даже крупные, сложные и сильно покрытые тестами проекты отлично могут разрабатываться без монстрообразного DI. В качестве примера… ну например Ruby on Rails.
А в яваскрипте, где в основном мы обеспечивам рендеринг html, работу интерфейса и проброску событий туда-сюда, переключайте ваш или процедурный(лапша jQuery колбеков), или ООП подходы на MVC головного мозга с backbone или его анлогом в связке с jasmine/mocha.
в яваскрипте, где в основном мы обеспечивам рендеринг html, работу интерфейса и проброску событий туда-сюда

Если ваши задачи на Javascript не выходили за эти рамки, мне нечего вам возразить. 90% людей пришедших в Javascript — это бывшие Front-end Guy, действительно, для них эта статья будет бесполезна. Но люди которые занимаются профессионально программированием на JS, часто сталкиваются со сложными задачами, когда нужно написать большое приложение не имея возможности построить нормальную абстракцию inbox инструментами.
Сейчас для меня web-браузер – это не основная, а одна из платформ для JS. А созданием GUI для обычных сайтов я вообще никогда не занимался.
Интересно, кстати, утверждение про тесты с учётом того, что в проекте на гитхабе они напрочь отсутствуют.

Я не утверждал, что моё приложение покрыто тестами. Эта демка, для людей которые после прочтения статьи задаются вопросом – «А что дальше, как это будет выглядеть на практике в рабочем приложении?». Увы, в этот раз я был сильно ограничен по времени для покрытия демо приложения тестами. Тем более у меня была в мыслях идея написать статью о TDD в JS.
Бросайте уже пытаться сделать из яваскрипта яву или сишарп

Написано же:
в данный момент я работаю над приложениями для Samsung SmartTV
Я работал на IPTV 5 лет назад. Телевизионная приставка — это микрокомп (типа Raspberry PI только хуже — с 64 или 128 М памяти) на ARM с обрезанным Firefox с яваскриптуемым мультимедиа-компонентом (типа плугина), HTML- и JS-ресурсы либо зашиты локально либо грузятся с сервера. Не думаю, что SmartTV сильно отличается, разве что андроид вместо линукса. Так что на каком языке писать — выбора практически нет. И JS-фреймворки тоже не впихнуть — из-за ограничений по доступной памяти. Приходится извращаться и изобретать велосипеды.
Если ваши задачи на Javascript не выходили за эти рамки, мне нечего вам возразить. 90% людей пришедших в Javascript — это бывшие Front-end Guy, действительно, для них эта статья будет бесполезна. Но люди которые занимаются профессионально программированием на JS, часто сталкиваются со сложными задачами, когда нужно написать большое приложение не имея возможности построить нормальную абстракцию inbox инструментами.
Сейчас для меня web-браузер – это не основная, а одна из платформ для JS. А созданием GUI для обычных сайтов я вообще никогда не занимался.

Угу, наслышан. Мы серьёзные разработчики, занимающиеся серьёзными вещами и пишущие только серьёзный код.
Пожалуй, стоит тогда указывать в статье, что она предназначена для занимающихся «профессионально программированием на JS», для которых веб не основная платформа.
Какое-то программирование на конфиг-файлах получается.
Похоже ноги растут из
2. Возможность модернизировать или изменять поведение приложения не меняя его кода.
Тем что у вас код, например console.log записан в текстовой переменной он не перестает быть кодом.
Тем что у вас код, например console.log записан в текстовой переменной он не перестает быть кодом.

Извините, я говорил об Open/closed principle. А Вы о чем?
Какое-то программирование на конфиг-файлах получается.

А TDD это вообще программирование тестами. Но многим нравится.

Извините, за оффтоп. Мне всегда не нравилось что на хабре мало статей о такой замечательной, и быстроразвивающийся, технологии как Javascript. Я говорю о статьях с приемами программирования, или организации кода (как эта), а не статьи вроде — «Вышла новая либа нa JS» или «Пишем слайдер картинок вместе». И вот моя первая статья на хабре, но меня никто не понял.
Я понимаю, что это очень узкое направление в JS, но оно имеет право жить. Может кому-то будет интересно, а может даже и полезно.
Извините, я говорил об Open/closed principle. А Вы о чем?

Не пойму как связан код в string переменных и open/close principle? Или наследование на прототипах ему не удовлетворяет. Ну даже если отбросить console.log и те строки которые у вас помечены как TODO remove, у вас все равно логика реализована в конфиге.
И это в то время как космические корабли бороздят везде отделяют мух от котлет путем MVC, MVVM.

А TDD это вообще программирование тестами. Но многим нравится.

Не путайте методологию разработки с формированием архитектуры. Эта аналогия уровня «многим нравится программировать на клавиатуре mitsumi» — связи с DI столько-же.

Я понимаю, что это очень узкое направление в JS, но оно имеет право жить. Может кому-то будет интересно, а может даже и полезно.

Так напишите что сподвигло вас на это. DI ради DI никому не нужно.
Не пойму как связан код в string переменных

Относитесь к этому как к имени сущности. Вы, наверное, заметили eval в коде, я его использую только потому, что сейчас пишу под SmartTV и планирую перенести на Node.js. Где разные объекты отвечают за глобальную область видимости.
В изначальном варианте eval’a нет, я извлекал непосредственно сущность с глобальной области видимости в JS так:
var SomeGlobalClass = function(){
    this.say = function(){
        console.log('I\'m here');
    };
};
var str = 'SomeGlobalClass';
new window[str]().say(); // I'm here

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

Можете указать конкретный момент? Вы, кажется, не поняли сути DI.
Понимаете, что когда вы пишете подобный код:
var Menu = function(){
	var ajax, domBouilder;
    var constructor = function(){
		ajax = new AJAXclass();
		domBouilder = new SomeDOMboilder();
	};
	...
};
new Menu();

То это уже не правильный код, вы создали класс, в котором зависимости прописаны хардкодом. И это в любом языке будет не правильно. Даже в теории программирования желательно придерживаться чистых функций, об этом даже где-то тут писали. И да, этот момент можно решить фабриками для всех типов сущностей. Но, по-моему, это куда более тяжеловесный и трудоёмкий процесс и в принципе не полностью соответствует Open/closed principle.
Это же решение полностью решает такую проблему, и довольно элегантно. Я не выношу логику за приложение, я выношу определение компонентов (в данном случае AJAXclass и SomeDOMboilder) используемых в «классе», за его пределы.
Не путайте методологию разработки с формированием архитектуры. Эта аналогия уровня «многим нравится программировать на клавиатуре mitsumi» — связи с DI столько-же.

Безусловно. Имелось в виду, что использование такого подхода сразу подразумевает использование как минимум половины SOLID принципов разработки. Я это упомянул в статье, такой подход заставляет писать правильно.

Так напишите что сподвигло вас на это. DI ради DI никому не нужно.

Из этого состоит «Вступление», спасибо что внимательно прочли.
Видимо вы дальше прочитать не осилили.
Говорите пожалуйста за себя. Я прочитал, и пытаюсь прояснить неясные для меня моменты.
Тогда перечитайте ещё раз, так как дальше того пункта у вас явно не пошло.
Мне статья понравилась. Интересно, оригинально и на мой взгляд — имеет право на существование. Гораздо интереснее и познавательнее топиков «новостей» или кривых переводов. Автору спасибо.
Спасибо!
Но проблема в том что это не оригинальный подход, а уже довольно обыденный, и успешно используемый в других языках, например на такую реализацию меня частично подтолкнул DI в ZendFramework 2.0. Я же просто адаптировал и применил этот подход в Javascript, и для моих целей он себя оправдал.
А меня бьют в карму за то что показал какие есть подходы в разработке ПО, в том числе для JS. Так будто это я придумал этот паттерн.
Под оригинальным я имел ввиду реализацию DI в javascript. Сам я работаю с Symfony 2, где активно используется DI. Мне очень нравится такой подход.
хотите DI в JS? пожалуйста:
функцию приводите к строке через toString, разбираете объявление функции и делаете инъекции, всё просто
подсмотренно у angular.js
JS не предоставляет инструментов для полноценного следования этому паттерну (элементарное отсутствие тех же рефлекшенов)


for(var i in {f:1, g:'r', m:0, h:null, l:undefined})
{
    alert(i);
}


Чем не reflection? Есть интроспекция, даже проще чем в Java.
Рефлекшен, это по сути это возможность читать и обрабатывать не объекты (как в вашем случае), а их конструкторы (классы). И таким способом вы не прочтете локальный скоуп объекта и сигнатуру методов.

Например, не инстанцируя объект от этого конструктора вы не прочтете его публичный метод, а до локальных вы вообще никак не достучитесь.
var Class = function(){
	var privateMethod1 = function(a, b){
		return a + b;
	};
	var privateMethod2 = function(c, d){
		return c + d;
	};
	this.publicMethod1 = function(e, f){
		return e + f;
	};
}

tzlom выше написал вполне неплохое решение для рефлекшенов в JS.
Спасибо. Интересная статья. Наверняка в ближайшее время появятся не мало подобных решений (кроме уже упомянутого angular.js). Все таки js слишком гибок для больших приложений, и его нужно как-то дробить на независимые модули.

По поводу подхода насколько я знаю Java-программисты как раз наоборот стараются уйти от xml-конфигурирования проекта — т.к. как минимум:

* IDE плохо поддерживает такие нотации;
* при рефакторингах приходиться менять в 2х местах (код + конфигурация);

Очень выручили бы аннотация, но в js их нет :(
Java-программисты как раз наоборот стараются уйти от xml-конфигурирования проекта

А в какую сторону они уходят? Я, по большей части, lamp разработчик, так что немного далек от того что происходит в Java.
* IDE плохо поддерживает такие нотации;

Если конфиг находится в xml формате, тут не поспоришь.
* при рефакторингах приходиться менять в 2х местах (код + конфигурация);

По-моему это надуманная проблема. Вроде — «Мы не будем писать тесты т.к. уходит много времени на поддержку их в актуальном состоянии» :)
Тем более, в конфиге прописываешь только внешние компоненты используемые классом, а не какую-либо логику. А если уж рефакторинг зашел так далеко, что класс поменял компоненты которые он использует, нужно готовится к тому что переписывать нужно будет многое.
[blah-blah mode]
Но в итоге, кода писать нужно будет меньше. Например часто вместо того чтобы создавать отдельный подкласс, можно просто запросить существующий класс, только другой сборки. Например, у нас была проблема, в приложении было два контроллера для старого и нового API, так получилось, что в новое API не успели перенести все методы из старого, и для определенного списка команд мы использовали старое API. Причем у одного API ответ был в XML, у другого в JSON, да и их структура была сильно отличной. Нам пришлось написать производный DAO, который парсил JSON и новый формат данных. И в разных модулях пришлось использовать DAO в зависимости от используемого API. Когда же всё перевели в новый API нам пришлось облазить весь код в поисках мест где использовался старый DAO и заменить его на новый.
Используя DI подход, единственное что мы бы меняли в коде это — написали бы новый парсер. А в DI сделали бы основную сборку DAO, и ее алиас который бы использовал другой парсер. И по ходу обновления api мы бы меняли только конфиг зависимостей, не трогая код.
А один раз встала необходимость вывести один виджет на всех поддерживаемых языках, вроде простая задача, и пришлось переписывать существующие компоненты. «Случай 4
» примерно об этом.
[/blah-blah mode]
Очень выручили бы аннотация, но в js их нет :(

Ну, это уже другая песня и на мотив метапрограммирования. Использовать аннотации для внедрения зависимостей, по-моему, это как микроскопом забивать гвозди :). А вообще, правда, их в JS не хватает. Я даже придумал механизм для создания, своего рода, «хуков» в js объектах, даже собираюсь написать о нем в новой статье. Но она у меня уже вышла больше этой, так что опубликую ее наверное в октябре, к тому же хочу взять за привычку написание демо приложений, чтобы показать подход на практике, как в этот раз.
спасибо за статью.
даже собираюсь написать о нем в новой статье.

заинтриговали, жду, даже подписался на вас
Sign up to leave a comment.

Articles