本文介绍了使用RequireJS在单例和原型范围之间切换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Spring有非常有用的选项,我定义一个bean,我定义了一个范围。如果它是单例,则只创建一个实例。通过原型,每次需要一个bean时,都会创建一个新的实例。



RequireJS通过默认单例提供,所以使用这样简单的模块:



Singleton.js



  define([],function(){
console.log('Instance initialization')
var items = []
var singleton = {
getItems:function(){
return items
},
setItems:function(newItems){
items = newItems
},
addItem:function(item){
items.push(item)
}
};
return singleton;
})

和用法:

  require([showcase / modules / Singleton],function(Singleton){
Singleton.addItem('item1')
console.log(Singleton.getItems())
})
require([showcase / modules / Singleton],function(Singleton){
Singleton.addItem('item2 ')
console.log( Singleton.getItems())
})

输出将为:

有可能以这种方式定义和使用模块,如果我想使用原型,我可以在模块定义中切换还是单身人士范围?所以在我的情况下,没有改变用法,我会得到:

我正在使用Dojo的RequireJS,以防止语法差异

解决方案

首先,问题是当您使用AMD加载程序导入模块时,实际上会获得一个实例,但是第二次导入相同的模块时,实际上返回相同的实例(问题1)。



为了克服这个问题,您应该使用工厂设计模式来获取您的实例,并将您的单例对象转换为可实例化的类(问题2)。您的工厂可能会有一个名为 getInstance()的方法,它接受可以在单例/原型之间切换的 boolean 参数。 / p>

所以没有改变你的使用,你将无法做到这一点,因为我刚刚解决的问题。我可以想出最好的解决方案(一个工厂)是:



Singleton.js



  define([],function(){
console.log('Instance initialization');

// Singleton class
var Singleton = function(){
this.items = [];
this.getItems = function(){
return this.items;
};
this.setItems = function(newItems){
this.items = newItems;
};
this.addItem = function(item){
this.items.push项目);
}
};

//工厂
var factory = {
singletonInstance:new Singleton(),
getInstance:函数(/ ** Boolean * / isSingleton){
if(isSingleton === true){
return this.singletonInstance;
} else {
return new Singleton();
}
}
};
返回工厂;
} );



用法(单身)



  require([app / Singleton],function(singletonFactory){
var Singleton = singletonFactory.getInstance(true);
Singleton.addItem('item1');
console.log(Singleton.getItems());
});
require([app / Singleton],function(singletonFactory){
var Singleton = singletonFactory.getInstance(true);
Singleton.addItem('item2');
console.log(Singleton.getItems());
});



用法(多个实例)



  require([app / Singleton],function(singletonFactory){
var Singleton = singletonFactory.getInstance(false);
Singleton.addItem('item3');
console.log(Singleton.getItems());
});
require([app / Singleton],function(singletonFactory){
var Singleton = singletonFactory.getInstance(false);
Singleton.addItem('item4');
console.log(Singleton.getItems());
});

如果你对一个完整的例子感兴趣,它在。



最终你可以把工厂包装成一个插件你可以这样做:

  require([app / Object!singleton app / Object!prototype],function(){

});

但是我不知道RequireJS是否也支持这个(如果我理解得很好,作为AMD装载机的通用故事)。


Spring has very useful option, that whey I define a bean, I define a scope. If it's singleton, only one instance is created. By prototype, each time a bean is required, a new instance is created.

RequireJS provides by default singletons, so with such simple module:

Singleton.js

define([], function() {
    console.log('Instance  initialization')
    var items = []
    var singleton =  {
      getItems: function() {
        return items
      },
      setItems: function(newItems) {
        items = newItems
      },
      addItem: function(item) {
        items.push(item)
      }
    };
    return singleton;
})

and the usage:

require(["showcase/modules/Singleton"], function(Singleton){
  Singleton.addItem('item1')
  console.log(Singleton.getItems())
})
require(["showcase/modules/Singleton"], function(Singleton){
  Singleton.addItem('item2')
  console.log(Singleton.getItems())
})

the output will be:

Is it possible to define and use the module in such way, that I could switch in the module definition, if I want to use prototype or singleton scope? So in my case, without changing the usage, I'd get:

I'm using RequireJS from Dojo, just in case of syntax differences

解决方案

Well, first of all the problem is that when you import a module using an AMD loader, you will actually get an instance, but the second time you import the same module, the same instance is actually returned (problem 1).

To overcome this problem you should use the factory design pattern to get your instance and also translate your singleton object to a class that can be instantiated (problem 2). Your factory could have a method called getInstance() that accepts a boolean parameter that can toggle between singleton/prototype.

So without changing your usage you won't be able to do this because of the problems I just addressed. The best solution I can come up with (with a factory) is:

Singleton.js

define([], function() {
    console.log('Instance  initialization');

    // Singleton class
    var Singleton = function() {
      this.items = [];
      this.getItems = function() {
        return this.items;
      };
      this.setItems = function(newItems) {
        this.items = newItems;
      };
      this.addItem = function(item) {
        this.items.push(item);
      }
    };

    // Factory
    var factory = {
      singletonInstance: new Singleton(),
      getInstance: function(/** Boolean */ isSingleton) {
        if (isSingleton === true) {
          return this.singletonInstance;
        } else {
          return new Singleton();
        }
      }
    };
    return factory;
});

Usage (singleton)

require(["app/Singleton"], function(singletonFactory){
  var Singleton = singletonFactory.getInstance(true);
  Singleton.addItem('item1');
  console.log(Singleton.getItems());
});
require(["app/Singleton"], function(singletonFactory){
  var Singleton = singletonFactory.getInstance(true);
  Singleton.addItem('item2');
  console.log(Singleton.getItems());
});

Usage (multiple instances)

require(["app/Singleton"], function(singletonFactory){
  var Singleton = singletonFactory.getInstance(false);
  Singleton.addItem('item3');
  console.log(Singleton.getItems());
});
require(["app/Singleton"], function(singletonFactory){
  var Singleton = singletonFactory.getInstance(false);
  Singleton.addItem('item4');
  console.log(Singleton.getItems());
});

In case you're interested in a full example, it's on Plunker.

Eventually you could wrap the factory as a plugin so that you could actually do something like:

require([ "app/Object!singleton", "app/Object!prototype" ], function() {

});

However I don't know if RequireJS also supports this (and if I'm understanding well it should be a generic story for both AMD loaders).

这篇关于使用RequireJS在单例和原型范围之间切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 20:09