Выявление недостатков модели модуля
Недавно я познакомился с шаблоном Revealing Module, и я прочитал несколько статей об этом.
Кажется, это очень хороший образец, и я хотел бы начать использовать его в большом проекте, который у меня есть. В проекте я использую: JQuery, KO, requirejs, JQuery Mobile, JayData. Мне кажется, что это будет хорошо подходит для ViewModels KO.
В частности, я хотел бы использовать ЭТУ версию.
Одна вещь, которую я не мог найти, - это недостатки использования этого шаблона, потому что нет (мне трудно поверить)?
Что следует рассмотреть перед тем, как начать использовать его?
Ответы
Ответ 1
Я прочитал статью, в которой @nemesv ссылается на меня (спасибо:)), и я думаю, что есть еще один недостаток, о котором не упоминалось, поэтому я подумал, что добавлю его здесь для справки. Вот цитата из статьи:
Недостатки
Недостатком этого шаблона является то, что если частная функция относится к публичная функция, эта публичная функция не может быть переопределена, если патч необходимо. Это связано с тем, что частная функция будет продолжать обратитесь к частной реализации, и шаблон не применяется к публичных членов, только для функций.
Публичные элементы объекта, которые ссылаются на частные переменные, также с учетом вышеприведенных примечаний к правилам без патча.
В результате этого модули, созданные с помощью шаблона раскрывающегося модуля могут быть более хрупкими, чем те, которые созданы с использованием исходного модуля шаблон, поэтому следует соблюдать осторожность во время использования.
И мое дополнение:
Вы не можете использовать наследование с этим шаблоном. Например:
var Obj = function(){
//do some constructor stuff
}
var InheritingObj = function(){
//do some constructor stuff
}
InheritingObj.prototype = new Obj();
InheritingObj.prototype.constructor = InheritingObj;
Это простой пример для наследования в js, но при использовании Revealing Prototype Pattern вам нужно будет сделать это:
InheritingObj.prototype = (function(){
//some prototype stuff here
}());
который переопределит ваше наследование.
Ответ 2
Шаблон раскрывающего модуля (RMP) создает объекты, которые не ведут себя хорошо по отношению к переопределению. Как следствие, объекты, созданные с использованием RMP, не так хорошо работают, как прототипы. Поэтому, если вы используете RMP для создания объектов, которые будут использоваться в цепочке наследования, просто не делайте этого. Эта точка зрения - моя собственная, в противовес тем, кто выступает за образец раскрывающегося прототипа.
Чтобы увидеть неправильное поведение наследования, сделайте следующий пример построителя URL:
function rmpUrlBuilder(){
var _urlBase = "http://my.default.domain/";
var _build = function(relUrl){
return _urlBase + relUrl;
};
return {
urlBase: _urlBase,
build: _build
}
}
Отбросив вопрос о том, почему вы используете RMP для объекта без каких-либо частных компонентов, обратите внимание, что если вы берете возвращаемый объект и переопределяете urlBase с помощью /fooobar.com/... ", вы можете ожидать, что поведение build() изменится соответствующим образом. Это не так, как показано ниже:
var builder = new rmpUrlBuilder();
builder.urlBase = "http://qaru.site/";
console.log(builder.build("/questions"); // prints "http://my.default.domain/questions" not "http://qaru.site/questions"
Контрастируйте поведение с помощью следующей реализации построителя URL.
function urlBuilder = function(){
return {
urlBase: "http://my.default.domain/".
build: function(relUrl){ return this.urlBase + relUrl;}
}
}
var builder = new urlBuilder();
builder.urlBase = "http://qaru.site/";
console.log(builder.build()); // prints "http://qaru.site/questions"
который ведет себя правильно.
Вы можете исправить поведение шаблона Revealing Module Pattern, используя эту область действия, как показано ниже.
function rmpUrlBuilder(){
var _urlBase = "http://my.default.domain/";
var _build = function(relUrl){
return this.urlBase + relUrl;
};
return {
urlBase: _urlBase,
build: _build
}
}
но это скорее поражает цель шаблона раскрывающегося модуля. Подробнее см. В сообщении моего блога http://ilinkuo.wordpress.com/2013/12/28/defining-return-object-literals-in-javascript/
Ответ 3
Другие недостатки с шаблоном раскрывающегося модуля включают:
- Тесная связь публичных функций с оператором Return
- Смешанное использование объектного литерала для публичных функций и автономных деклараций для частных функций
Я бы рекомендовал использовать шаблон окончательного модуля по шаблону раскрывающегося модуля
(https://github.com/tfmontague/definitive-module-pattern)