Подтвердить что ты не робот

Выявление недостатков модели модуля

Недавно я познакомился с шаблоном Revealing Module, и я прочитал несколько статей об этом.

Кажется, это очень хороший образец, и я хотел бы начать использовать его в большом проекте, который у меня есть. В проекте я использую: JQuery, KO, requirejs, JQuery Mobile, JayData. Мне кажется, что это будет хорошо подходит для ViewModels KO.

В частности, я хотел бы использовать ЭТУ версию.

Одна вещь, которую я не мог найти, - это недостатки использования этого шаблона, потому что нет (мне трудно поверить)?

Что следует рассмотреть перед тем, как начать использовать его?

4b9b3361

Ответ 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)