Раз уж вы ссылаетесь на Стефанова, приведу пару цитат из него:
Про синглтоны:
Usefulness warning: The following discussion is not so useful as a practical pattern but more as a theoretical exercise in imitating the workarounds for issues related to the designs of some (statically, strongly typed) class-based languages in which functions are not first-class
objects.
Про фабрики (цитату вы прервали на самом интересном месте)
The second point is more important in static class languages in which it may be nontrivial to create instances of classes, which are not known in advance (in compile time). In javaScript, this part of the implementation is quite easy.
Прототипное наследование вызывает те же проблемы, что и shallow copy. Даже больше — при клонировании хотя бы простые значения можно изменять в унаследованном объекте независимо.
Наследование объекта от объекта:
var parent = {},
child;
function Surrogate(){}
Surrogate.prototype = parent;
child = new Surrogate();
или
var parent = {},
child = Object.create(parent,{});
или
var parent = {},
child = {},
key;
for (key in parent){
if (parent.hasOwnProperty(key) && !child.hasOwnProperty(key)){
child[key] = parent[key];
}
}
Наследование от синглтона сомнительно само по себе.
На мой взгляд, многие классические паттерны в javascript просто не имеют смысл, так как этот язык гибче тех, на которые они в первую очередь рассчитаны.
Если бы стояла задача описать этот паттерн одной фразой, то она получилась бы примерно следующей: Singleton — это класс, который может иметь только один экземпляр.
Но в javascript нет классов! Проблема высосана из пальца.
Но у него есть и существенный недостаток: основная цель паттерна singleton — обеспечить доступ к объекту без использования глобальных переменных, а данный способ предоставляет доступ к переменной app только в текущей области видимости.
Facepalm. А если сделать функцию она магическим образом не будет глобальной? В requirejs можно возвращать и объект, вы не поверите.
Суть фабричного метода — не в том, что вы описали, а в том, чтобы предоставить возможность подклассам переопределить класс (или в общем случае — способ создания) объектов, которые создаются в процессе работы этого класса. В javascript такая задача тоже может появиться, но она решается просто добавление конструктора в объект и переопределением при необходимости:
var obj = {
createAnimal: function(){
return new this.animal();
}
};
obj.animal = Dog;
obj.animal = Cat;
То что вы описали тоже решается без каких то проблем и мысле о «паттернах»:
var animal = {
cat: Cat,
dog: Dog
};
new animal['cat'];
Когда говорят что eval is evil, имеется в виду, что в большинстве случаев он не нужен и поэтому стоит подумать над альтернативными вариантами. Конечно, бывает, что он просто необходим.
Из-за этого тупого утверждения «Eval = Bad» большая часть приложений используют воистину извращённые способы выполнения кода на клиенте, но по сути те же eval.
Это лишь признак непонимания разработчиков сути утверждения eval is evil. Так как под eval имеются в виду исполнение стороннего кода вообще, любыми способами.
Перефразировал бы как «НЕ используйте JS Lint») долго сидел на нем и следовал фанатично всем мелочам. По факту — это того не стоит. Используйте JSHint.
Отдельно хочется заметить, что многие из приведенных примеров JS Lint бы не прошли)
Ну, по сути, Bootstrap и Backbone в руки — и вперед. Но проблема в том, что количество boilerplate-кода зашкаливает, всякие штуки типа таблиц и подобных виджетов приходится прикручивать руками, бороться с несовместимостью представления данных и т. д.
А в ExtJS куча виджетов из коробки, единая архитектура, форматы представления данных, соглашения о структуре папок. Плюс можно обходиться без модификации html и css вообще, что немаловажно. Из минусов — совершенно чудовищный dom на выходе, большой размер, тормоза и утечки памяти.
В общем, разные инструменты для разных задач. Но факт — для всяких CMS, CRM и иже с ними ExtJS подоходит очень хорошо.
Про синглтоны:
Про фабрики (цитату вы прервали на самом интересном месте)
Наследование объекта от объекта:
или
или
Наследование от синглтона сомнительно само по себе.
Но в javascript нет классов! Проблема высосана из пальца.
Facepalm. А если сделать функцию она магическим образом не будет глобальной? В requirejs можно возвращать и объект, вы не поверите.
Суть фабричного метода — не в том, что вы описали, а в том, чтобы предоставить возможность подклассам переопределить класс (или в общем случае — способ создания) объектов, которые создаются в процессе работы этого класса. В javascript такая задача тоже может появиться, но она решается просто добавление конструктора в объект и переопределением при необходимости:
var obj = { createAnimal: function(){ return new this.animal(); } }; obj.animal = Dog; obj.animal = Cat;То что вы описали тоже решается без каких то проблем и мысле о «паттернах»:
var animal = { cat: Cat, dog: Dog }; new animal['cat'];Это лишь признак непонимания разработчиков сути утверждения eval is evil. Так как под eval имеются в виду исполнение стороннего кода вообще, любыми способами.
Перефразировал бы как «НЕ используйте JS Lint») долго сидел на нем и следовал фанатично всем мелочам. По факту — это того не стоит. Используйте JSHint.
Отдельно хочется заметить, что многие из приведенных примеров JS Lint бы не прошли)
(Shapes || (Shapes = {}))А что вас, собственно, неустраивает? Короткая, элегантная и в целом довольно распространенная форма.
Да ну ладно вам! Миллион раз описана, разжевана и в рот положена. И столько есть мест, где подсмотреть решение можно
А в ExtJS куча виджетов из коробки, единая архитектура, форматы представления данных, соглашения о структуре папок. Плюс можно обходиться без модификации html и css вообще, что немаловажно. Из минусов — совершенно чудовищный dom на выходе, большой размер, тормоза и утечки памяти.
В общем, разные инструменты для разных задач. Но факт — для всяких CMS, CRM и иже с ними ExtJS подоходит очень хорошо.
Это не так, и именно в этом и заключаются мощные возможности блоков для обработки событий
А как же блоки? и не протоколы, раз уж на то пошло, а делегирование.
С любовью, Ваш кэп.