设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

当IoC遇见了Node.js

2014-6-6 12:00| 发布者: joejoe0332| 查看: 4118| 评论: 0|原作者: 倪震洋|来自: Infoq

摘要: 一个简单的例子:在例子中,汽车(car)需要依赖轮子(wheel)和发动机(engine)才能跑起来。为了处理好这一关系,必须首先人为的通过require把engine和wheel引入进来,然后通过new操作实例化,这样car才能真正的ru ...

  没有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起来。


 


  这个例子非常简单,但是存在着一些问题:


  1. require的时候,需要直接知道engine和wheel的文件位置、文件名、以及所exports的是什么。一旦engine或者wheel的文件名、所在位置、exports方式发生了变化,require操作必须做出相应的改变
  2. car直接依赖于engine和wheel,因此如果我们试图做单元测试,则会发现mock engine或者wheel非常困难,要么就是修改engine、wheel的代码,要么就是修改car的代码


  这个例子只有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方法跑起来,一切都变得如此简单与美好!

  1. 去除了engine和wheel的直接依赖,随便engine和wheel叫什么名字,写在哪里(甚至可以是一个remote对象),重构变得轻而易举
  2. 想对car进行单元测试,只需要依赖注入一个mock的engine和wheel对象即可完成,再也不需要直接修改car或者engine、wheel的代码了


  让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...



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部