简体   繁体   English

显示模块模式 (RMP) 的缺点

[英]The Revealing Module Pattern (RMP) disadvantages

I recently got familiar with the Revealing Module Pattern (RMP) and I've read quite a few articles about it.我最近熟悉了 Revealing Module Pattern (RMP),并且阅读了很多关于它的文章。

It seems like a very good pattern and I would like to start using it in a big project.这似乎是一个非常好的模式,我想在一个大项目中开始使用它。 In the project I'm using: Jquery, KO, requireJS, Jquery Mobile, JayData.在我使用的项目中:Jquery,KO,requireJS,Jquery Mobile,JayData。 It seems to me like it'll be a good fit for the KO ViewModels.在我看来,它非常适合 KO ViewModel。

In specific I'd like to use THIS version of it.具体来说,我想使用它的这个版本。

One thing I could not find are disadvantages for using this pattern, is it because there aren't any (I find it hard to believe)?我找不到的一件事是使用这种模式的缺点,是因为没有(我觉得很难相信)吗?

What should I consider before starting to use it?在开始使用它之前我应该考虑什么?

The Revealing Module Pattern (RMP) creates objects that don't behave well with respect to overriding. 显示模块模式(RMP)创建的对象在覆盖方面表现不佳。 As a consequence, objects made using the RMP don't work well as prototypes. 结果,使用RMP制作的对象不能很好地用作原型。 So if you're using RMP to create objects that are going to be used in an inheritance chain, just don't. 因此,如果您使用RMP创建将在继承链中使用的对象,请不要这样做。 This point of view is my own, in opposition to those proponents of the Revealing Prototype Pattern. 我的观点是我自己的,与那些揭示原型模式的支持者相对。

To see the bad inheritance behavior, take the following example of a url builder: 要查看不良的继承行为,请使用以下URL构建器示例:

function rmpUrlBuilder(){
  var _urlBase = "http://my.default.domain/";
  var _build = function(relUrl){
    return _urlBase + relUrl;
  };

  return {
    urlBase: _urlBase,
    build: _build
  }
}

Setting aside the question of why you would use RMP for an object with no private components, note that if you take the returned object and override urlBase with " http://stackoverflow.com ", you would expect the behavior of build() to change appropriately. 抛开为什么要对没有私有组件的对象使用RMP的问题,请注意,如果使用返回的对象并使用“ http://stackoverflow.com ”覆盖urlBase,则可能会期望build()的行为适当地改变。 It doesn't, as seen in the following: 如下所示:

var builder = new rmpUrlBuilder();
builder.urlBase = "http://stackoverflow.com";
console.log(builder.build("/questions"); // prints "http://my.default.domain/questions" not "http://stackoverflow.com/questions"

Contrast the behavior with the following url builder implementation 将行为与以下URL构建器实现进行对比

function urlBuilder = function(){
  return {
    urlBase: "http://my.default.domain/".
    build: function(relUrl){ return this.urlBase + relUrl;}
  }
}

var builder = new urlBuilder();
builder.urlBase = "http://stackoverflow.com";
console.log(builder.build()); // prints "http://stackoverflow.com/questions"

which behaves correctly. 行为正确。

You can correct the Revealing Module Pattern's behavior by using this scope as in the following 您可以通过使用以下范围来纠正“显示模块模式”的行为,如下所示

function rmpUrlBuilder(){
  var _urlBase = "http://my.default.domain/";
  var _build = function(relUrl){
    return this.urlBase + relUrl;
  };

  return {
    urlBase: _urlBase,
    build: _build
  }
}

but that rather defeats the purpose of the Revealing Module Pattern. 但这违反了显示模块模式的目的。 For more details, see my blog post http://ilinkuo.wordpress.com/2013/12/28/defining-return-object-literals-in-javascript/ 有关更多详细信息,请参阅我的博客文章http://ilinkuo.wordpress.com/2013/12/28/defining-return-object-literals-in-javascript/

I read the article that @nemesv referenced me to (Thanks :)) and I thinks there is one more disadvantage that was not mentioned, so I thought I'd add it here for reference. 我阅读了@nemesv引用我的文章(谢谢:)),并且我认为还有一个未提及的缺点,因此我想在此添加它以供参考。 Here is a quote from the article: 这是文章的引文:

Disadvantages 缺点

A disadvantage of this pattern is that if a private function refers to a public function, that public function can't be overridden if a patch is necessary. 这种模式的缺点是,如果私有函数引用了公共函数,则在需要补丁的情况下不能覆盖该公共函数。 This is because the private function will continue to refer to the private implementation and the pattern doesn't apply to public members, only to functions. 这是因为私有函数将继续引用私有实现,并且该模式不适用于公共成员,而仅适用于函数。

Public object members which refer to private variables are also subject to the no-patch rule notes above. 引用私有变量的公共对象成员也应遵守上面的无补丁规则说明。

As a result of this, modules created with the Revealing Module pattern may be more fragile than those created with the original Module pattern, so care should be taken during usage. 因此,使用“显示模块”模式创建的模块可能比使用原始“模块”模式创建的模块更脆弱,因此在使用过程中应格外小心。

And my addition: 还有我的补充:

You can't use inheritance with this pattern . 您不能在这种模式下使用继承 For example: 例如:

var Obj = function(){
    //do some constructor stuff
}

var InheritingObj = function(){
    //do some constructor stuff
}

InheritingObj.prototype = new Obj();

InheritingObj.prototype.constructor = InheritingObj;

This a simple example for inheritance in js, but when using the Revealing Prototype Pattern you'll need to do this: 这是js中继承的一个简单示例,但是当使用显示原型模式时,您需要这样做:

InheritingObj.prototype = (function(){
    //some prototype stuff here
}());

which will override you inheritance. 这将覆盖您的继承。

Other disadvantages with the Revealing Module Pattern include: 显示模块模式的其他缺点包括:

  1. Tight coupling of the public functions with the Return statement 公共功能与Return语句的紧密结合
  2. Mixed usage of object literal for public functions and standalone declarations for private functions 对象文字用于公共功能的混合用法和独立声明用于私有功能的混合用法

I'd recommend using the Definitive Module Pattern over the Revealing Module Pattern ( https://github.com/tfmontague/definitive-module-pattern ) 我建议在显示模块模式( https://github.com/tfmontague/definitive-module-pattern )上使用最终模块模式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM