• newland.js的Ioc实现


    newland.js之所以是框架而不是类库,最重要的原因是它只要几步就能建立起一个网站!换言之,它已经包含了网站从启动到运行的重要流程,至于你还需要什么,是制定还是完善等等不确定的东西,框架已经预留了位置给你填空了。


    框架让程序员变成流水线上的工人这一事实是不可逆转的,唯一的区别的有的流水线非常智能,让你过得非常惬意,有的则非常恶心,让你变成苦逼的码畜!


    JAVA的三大框架之一,Spring最伟大的举措就是发明了IoC容器。是的,框架帮你做了许多事,但有些文件还是要你去建的,建在指定的目录下;有些代码你还要去写,依照规定好的格式,是建哪个类,继承哪个父类,差一步也不行。框架带来便捷的同时,也带来的枷锁!IoC的目的是让这些痛苦减少些!


    首先抄一段话解释什么叫IoC——“在依赖注入的模式下,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由容器来完成,然后注入给调用者,因此也称为依赖注入”。


    在我的newland.js框架中,最开始的mass.js模块其实只是提供模块加载机制与一些通用方法,不干正事的,它唯一做的有意义的是调用了mvc这个模块。

     $.require("system/deploy,system/mvc", function(deploy){
            deploy(  process.cwd() );//监听app目录下文件的变化,实现热启动
        });
    

    mvc模块的作用是启动服用器,接受请求!在此之前,它会读取配置文件,把用户指定的拦截器与默认拦截器与所有控制器统统读入内存,装配到系统中!


    所谓的栏截器其实就是structs那套东西,不认识JAVA的同学如果懂node.js,就去看看connectjs的中间件,差不多就是这个意思,用于处理请求与响应用的工具包。


    而控制器是重点,MVC不能没有它。一个控制器有许多功能,因此我们把共用的功能抽取出来构建成基类, 而我们所建的控制器作为子类继承它就可以节约许多代码。

    //遍历app/controllers目录下所有控制器模块,并与拦载器模块一起加载它们!
    $.walk("app/controllers", function(files){
            $.require( inter.concat( files ), function(){
                //拦截器放在最前面
                var intercepters = [].slice.call(arguments,0, inter.length);
                resource_ready( intercepters )
            });
        });
    
    

    在没有用IoC之前,我们的控制器是这个样子的:

    .define("doc_controller",function(){
        var klass = $.factory({
            inherit: $.base_controller,
            index: function(flow){
                $.log("已进入doc#index action");
                flow.session.set("xxx","in doc")
                var view_url = $.path.join("app","views", flow.req.url );
                flow.fire("get_view", view_url, flow.req.url )
            }
    
        });
        $.controllers[ "doc"] = new klass
    });
    
    

    其实用户要写的就是index,show, edit, destroy这样action方法,其他部分就是死格式!什么指定父类,new实例其实交给系统去处理就行了!因此我们的自定义控制器可以削减成这样子!

    $.define("doc_controller",function(){
        return {
            index: function(flow){
                $.log("已进入doc#index action");
                flow.session.set("xxx","in doc")
                var view_url = $.path.join("app","views", flow.req.url );
                flow.fire("get_view", view_url, flow.req.url )
            }
        }
    });
    

    那么子类的创建与继承关系的指定与实例的创建传到mvc.js中去管理:

       var rcname = /\/(\w+)_controller/;
        //遍历app/controllers目录下所有控制器模块,并与拦载器模块一起加载它们!
        $.walk("app/controllers", function(files){
            $.require( inter.concat( files ), function(){
                //取得放在前面的拦截器
                var intercepters = [].splice.call(arguments, 0, inter.length);
                //取得放在后面的控制器
                var controllers = arguments;
                //进行控制反转,构建我们所需要的控制器子类与它的实例
                files.forEach(function(el, i){
                    //mac下的路径为     app/controllers/doc_controller.js
                    //window下的路径为  app\\controllers\\doc_controller.js
                    var match = el.replace(/\\/g,"/").match(rcname);
                    var controller = controllers[i];
                    controller.inherit =  $.base_controller
                    var klass = $.factory(controller);
                    $.controllers[ match[1] ] = new klass;
                });
                resource_ready( intercepters )
            });
        });
    

    需要说明一下的是,newland.js分成两大块,app目录下的模块是用户自建的文件或系统指令下建立的模块(下称app模块),system目录下的模块则是辅助app模块运行用的。需要用户动手的app模块越简单就越好!任何复杂的类最好不要用,就算用都交由框架去处理,去new 实例;任何复杂的功能都做用钩子的形式,或通俗地说,是回调函数的形式,交由框架去调度;所有不确定的功能都做成自定义事件形式,由框架或框架的另外加载的模块去fire。诸如此类,所有耦合就松绑了,得以最大限度地适应需求的变化。

    http://dotnetfresh.cnblogs.com/archive/2005/06/27/181878.html

  • 相关阅读:
    给你的博客园加个面板娘!
    idea实现简单热部署
    idea 上传svn忽略文件
    谈一谈AOP面向切面编程
    做一个自定义注解
    使用aop切面编写日志模块
    数据结构之链表
    数据结构之队列
    数据结构之栈
    数据结构之线性表
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/2635408.html
Copyright © 2020-2023  润新知