CNode

node.js与dojo完美的融合-开发完全面向对象化

Ccory发布于15 年前最后回复12 年前2 回复10373 浏览0 收藏

最近学习了一下node.js,由于我是dojo出身,所以,觉得node.js并不是非常的面向对象化,并不满足面向对象的几个基本条件“封装”、“继承”、“多态”、“重载”等,虽然这些条件,JS是可以模拟出来的,但是重复的造轮子,会使得开发低下,性能堪忧。于是乎鄙人打算写一个node.js的OO module,然后看了一下dojo1.7的源码,发现原来,dojo1.7已经开始支持node.js了,这样就非常好了,我也不必去造轮子了。好了,废话少说,让我们来来看看,dojo是如何进入node.js的上下文的吧。 该文章分两个部分: 1.我们来做一个小的test,来验证dojo是否已加入node.js的上下文中; 2.我们把nodebeginner里面的一个上传图片的例子,用dojo来完成。 第一部分: 开发环境我们可以采用eclipse来完成。将dojo包导入进去: 最外层的dojo文件夹中放入的是dojo库。 我们在这个工程中,新建一个入口类Main.js (function() {     this.dojoConfig = {         has: {             "host-node": 1         }     };     require("H:/Project/dojo_nodejs/dojo/dojo/dojo");     define("Main", [], function() {         console.info("Hello World!");     }); })(); 这里说明一下,this表示的是node.js的上下文,这里给dojo设置host-node,因为dojo默认的模式是host-browser(浏览器窗口模式)。这里还要把dojo.js这个文件require进来,这样就OK啦。 运行效果: 这样,dojo就很轻松的融入到node.js的环境中了,是不是很简单^^¥。好了,下面在第二部分中我们来做一个上传文件的实例来表现dojo在开发node.js这一块强大的OO技术吧。(BTW:上传文件这个例子其实很简单,但是为了表现出用OO的形式来开发node.js,所以会故意写的有点复杂,请不要喷我<##>) 第二部分: 首先我们新建一个cory包,Main.js也需要稍微改一下,如下: (function() {     this.dojoConfig = {         has: {             "host-node": 1         },         paths: {             cory: "../../cory"         }     };     require("H:/Project/dojo_nodejs/dojo/dojo/dojo");     define("Main", [], function() {         console.info("Hello World!");     }); })(); paths就是注册自定义包的位置。这里cory包和最外层的dojo文件夹并列。 然后在cory包中,一共新建4个类,Server.js、UrlParser.js、Router.js、Page.js。 cory.Server:用于创建http服务器。 cory.UrlParser:用于解析URL。 cory.Router:将解析好URL中的pathname进行路由。 cory.Page:对应相应的URL做出逻辑处理。 下面就把各个类的代码展示给大家,主要是展示其语法,至于逻辑的话,nodebeginner.org有详细介绍。 cory.Server: define([     "../dojo/_base/kernel",     "../dojo/_base/declare",     "../dojo/Stateful" ], function(dojo, declare, Stateful) {     // summary:     //  This server to listen the port which you setted.     return declare("cory.Server", Stateful, {         // default value         port: 8888,         _http: dojo.http,         postscript: function(args) {             this.inherited(arguments);             if (args && args.port) {                 this.set("port", args.port);             }         },         start: function(/Function?/callback) {             console.debug("Server is starting...");             var _port = this.get("port");             this._http.createServer(function(request, response) {                 callback(request, response);             }).listen(_port);             console.debug("Server has started. The port is " + _port + ".");         }     }); }); cory.UrlParser: define(["../dojo/_base/declare"], function(declare) {     return declare("cory.UrlParser", null, {         parse2Pathname: function(/String/url) {             var pathname = dojo.url.parse(url).pathname;             console.debug("The current path name is: "" + pathname + "".");             return pathname;         }     }); }); cory.Router: define(["../dojo/_base/declare", "../dojo/Stateful"], function(declare, Stateful) {     return declare("cory.Router", Stateful, {         request: null,         response: null,         //根据不同的url地址名称,路由到不同的页面逻辑处理。         //返回是否路由成功。         rout: function(/Object/path, /String/pathname) {             console.debug("About to route a request for " + pathname);             var _classAndFunc = path[pathname];             var res = this.get("response");             if (!_classAndFunc) {                 console.debug("But this path was not found.");                 if (res) {                     res.writeHead(200, {"Content-Type": "text/plain"});                     res.write("404 Not found");                     res.end();                 }             }             var _lastIndex = _classAndFunc.lastIndexOf(".");             var _className = _classAndFunc.substring(0, _lastIndex);             var _funcName = _classAndFunc.substring(_lastIndex + 1);             var _page = new dojo.getObject(_className)();             _page.set("request", this.get("request"));             _page.set("response", res);             _page_funcName;         }     }); }); cory.Page: define(["../dojo/_base/declare", "../dojo/Stateful"], function(declare, Stateful) {     return declare("cory.Page", Stateful, {         request: null,         response: null,         //@Page(path=["/", "/index"])         displayIndex: function() {             console.debug(""cory.Page.displayIndex" was called");             var res = this.get("response");             if (res) {                 var body =                 ''+                     ''+                         ''+                     ''+                     ''+                         ''+                             ''+                             ''+                         ''+                     ''+                 '';                 res.writeHead(200, {"Content-Type": "text/html"});                 res.write(body);                 res.end();             }         },         //@Page(path=["/upload"])         upload: function() {             console.debug(""cory.Page.upload" was called");             var req = this.get("request"),                 res = this.get("response");             if (req && res) {                 var form = new dojo.formidable.IncomingForm();                 console.debug("about to parse");                 form.parse(req, function(error, fields, files) {                     console.debug("parsing done.");                     dojo.fs.renameSync(files.upload.path, "C:\Documents and Settings\Cory\Local Settings\Temp\test.png");                     res.writeHead(200, {"Content-Type": "text/html"});                     res.write("received image:");                     res.write("");                     res.end();                 });             }         },         //@Page(path=["/show"])         show: function() {             console.debug(""cory.Page.show" was called");             var res = this.get("response");             if (res) {                 dojo.fs.readFile("C:\Documents and Settings\Cory\Local Settings\Temp\test.png", "binary", function(error, file){                     if (error) {                         res.writeHead(500, {"Content-Type": "text/plain"});                         res.write(error + "\n");                     } else {                         res.writeHead(200, {"Content-Type": "image/x-png"});                         res.write(file, "binary");                     }                     res.end();                 })             }         }     }); });  Main.js也需要一点小改动: (function() {     this.dojoConfig = {         has: {             "host-node": 1         },         paths: {             cory: "../../cory"         }     };     require("H:/Project/dojo_nodejs/dojo/dojo/dojo");     var d = dojo;     ["http", "url", "fs", "formidable"].forEach(function(requiredName) {         d[requiredName] = require(requiredName);     });     define("Main", [         "dojo/_base/kernel",         "cory/Server",         "cory/UrlParser",         "cory/Router",         "cory/Page"     ], function(dojo, Server, UrlParser, Router) {         //这里将地址和类中的方法进行绑定。         //其中cory.Page是页面类,后面的.displayIndex、.upload、.show都是该类的方法。         var pathMap = {             "/": "cory.Page.displayIndex",             "/index": "cory.Page.displayIndex",             "/upload": "cory.Page.upload",             "/show": "cory.Page.show"         };         var server = new Server();         server.set("port", 8888);         server.start(function(request, response) {             var router = new Router();             router.set("request", request);             router.set("response", response);             router.rout(pathMap, new UrlParser().parse2Pathname(request.url));         });     }); })(); 运行效果: 后台控制台运行效果: 怎么样,这样的面向对象的方式,让思路更清晰,要比nodebeginner上的例子,引用传来传去的清晰多了吧。 后记:如果采用dojo来开发node.js后台程序,那么,可以继续封装成,类似于servlet形式,甚至可以进行json配置等。这样更有利于学习成本的降低,减少开发大型后台的人力、时间成本等。

查看回复

回复 (2)

S
sp42a#1·12 年前

觉得还是不要让 dojo 框架染指 node,,哪怕基础库也没必要……

K
kopes18#2·13 年前

这里用到的define方法是什么啊?

参与回复
登录后即可参与回复。登录