没有IoC的年代 一个简单的例子: var Engine = require('./engine');var Wheel = require('./wheel');var Car = function() { this.engine = new Engine(); this.wheel = new Wheel();}Car.prototype.run = function() { this.engine.run(); this.wheel.run(); console.log('run car...');}module.exports = Car; 在例子中,汽车(car)需要依赖轮子(wheel)和发动机(engine)才能跑起来。为了处理好这一关系,必须首先人为的通过require把engine和wheel引入进来,然后通过new操作实例化,这样car才能真正的run起来。 这个例子非常简单,但是存在着一些问题:
这个例子只有3个对象,读者可能觉得也没啥要紧的,这样直接做也没多大问题。但是一旦系统里面的对象数量变大了呢?复杂的依赖关系可能就是这样的: 这样的系统紧密耦合,往往会造成难以维护、难以重构、难以做单元测试,尤其是当一个新人加入团队的时候,也会因为这份复杂性变得举步维艰,看不明白也改不动。 步入IoC使用IoC之后,car的代码就会变成如下所示: var Car = function(engine) { this.engine = engine; this.wheel = null;}Car.prototype.run = function() { this.engine.run(); this.wheel.run(); console.log('run car...');}module.exports = Car; car无需知道engine、wheel的具体所在以require进来,也无需知道engine和wheel什么时候实例化以调用run方法跑起来,一切都变得如此简单与美好!
让IoC发挥作用本文通过Bearcat所提供的IoC容器来让IoC在Node.js中发挥作用。 Bearcat IoC 使用非常简单,只需要提供一个简单的配置文件即可让IoC容器管理下的系统运转起来: { "name": "simple_inject", "beans": [{ "id": "car", "func": "car", "props": [{ "name": "wheel", "ref": "wheel" }], "args": [{ "name": "engine", "ref": "engine" }] }, { "id": "wheel", "func": "wheel" }, { "id": "engine", "func": "engine" }]} 这里就通过一个简单的context.json配置文件来对IoC进行了描述:告知容器中有一个car,依赖于wheel和engine,wheel通过对象属性的方式注入,engine通过构造函数参数的方式注入,容器中还有一个wheel和一个engine。 启动容器跑起来,只需要把context.json的路径传递给bearcat即可: var Bearcat = require('bearcat');var contextPath = require.resolve('./context.json');var bearcat = Bearcat.createApp([contextPath]);bearcat.start(function(){ var car = bearcat.getBean('car'); // get bean car.run(); // call the method}); 运行结果 [2014-05-05 18:50:41.996] [INFO] bearcat - [app] Bearcat startup in 6 msrun engine...run wheel...run car... |