??xml version="1.0" encoding="utf-8" standalone="yes"?>中文字幕亚洲一区,另类小说亚洲色图,亚洲美女在线国产http://www.tkk7.com/canonical/archive/2011/12/25/367146.htmlcanonicalcanonicalSun, 25 Dec 2011 13:23:00 GMThttp://www.tkk7.com/canonical/archive/2011/12/25/367146.htmlhttp://www.tkk7.com/canonical/comments/367146.htmlhttp://www.tkk7.com/canonical/archive/2011/12/25/367146.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/367146.htmlhttp://www.tkk7.com/canonical/services/trackbacks/367146.html  览器前端编E的面貌?005q以来已l发生了深刻的变化,qƈ不简单的意味着出现了大量功能丰富的基础库,使得我们可以更加方便的编写业务代码,更重要的是我们看待前端技术的观念发生了重大{变,明确意识C如何以前端特有的方式释放E序员的生力。本文将l合jQuery源码的实现原理,对javascript中涌现出的编E范式和常用技巧作一单介l?br /> 
1. AJAX: 状态驻留,异步更新
  首先来看一点历双Ӏ?br />A. 1995qNetscape公司的Brendan Eich开发了javacript语言Q这是一U动?dynamic)、弱cd(weakly typed)、基于原?prototype-based)的脚本语a?br />B. 1999q微软IE5发布Q其中包含了XMLHTTP ActiveX控g?br />C. 2001q微软IE6发布Q部分支持DOM level 1和CSS 2标准?br />D. 2002qDouglas Crockford发明JSON格式?br />xQ可以说Web2.0所依赖的技术元素已l基本成形,但是q没有立d整个业界产生重大的媄响。尽一?#8220;面异步局部刷?#8221;的技巧在E序员中间秘密的传Q甚臛_生了bindowsq样庞大臃肿的类库,但ȝ来说Q前端被看作是瘠而又肮脏的沼泽地Q只有后台技术才是王道。到底还~少些什么呢Q?br />  当我们站在今天的角度d?005q之前的js代码Q包括那些当时的牛h所写的代码Q可以明昄感受到它们在E序控制力上的孱弱。ƈ不是?005q之前的js技术本w存在问题,只是它们在概念层面上是一盘散沙,~Zl一的观念,或者说~少自己独特的风? 自己的灵。当时大多数的hQ大多数的技术都试图在模拟传l的面向对象语言Q利用传l的面向对象技术,dCl的GUI模型的仿制品?br />  2005q是变革的一q_也是创造概늚一q。伴随着Google一pd让h耳目一新的交互式应用的发布,Jesse James Garrett的一文章《Ajax: A New Approach to Web Applications》被qؓ传播。Ajaxq一前端Ҏ的概念迅速将众多分散的实늻一在同一口号之下Q引发了Web~程范式的{换。所谓名不正则言不顺Q这下无名群众可扑ֈl织了。在未有Ajax之前Qh们早已认识到了B/S架构的本质特征在于浏览器和服务器的状态空间是分离的,但是一般的解决Ҏ都是隐藏q一区分Q将前台状态同步到后台Q由后台l一q行逻辑处理Q例如ASP.NET。因为缺乏成熟的设计模式支持前台状态驻留,在换늚时候,已经装蝲的js对象被q被丢弃Q这栯q能指望它去完成什么复杂的工作吗?
  Ajax明确提出界面是局部刷新的Q前台驻留了状态,q就促成了一U需要:需要js对象在前台存在更长的旉。这也就意味着需要将q些对象和功能有效的理hQ意味着更复杂的代码l织技术,意味着Ҏ块化Q对公共代码基的渴求?br />  jQuery现有的代码中真正与Ajax相关Q用XMLHTTP控g异步讉K后台q回数据Q的部分其实很少Q但是如果没有Ajax, jQuery作ؓ公共代码Zq乏存在的理由?br />
2. 模块化:理名字I间
  当大量的代码产生出来以后Q我们所需要的最基础的概念就是模块化Q也是对工作进行分解和复用。工作得以分解的关键在于各h独立工作的成果可以集成在一赗这意味着各个模块必须Z一致的底层概念Q可以实C互,也就是说应该Z一套公׃码基Q屏蔽底层浏览器的不一致性,q实现统一的抽象层Q例如统一的事件管理机制等。比l一代码基更重要的是Q各个模块之间必L有名字冲H。否则,即两个模块之间没有M交互Q也无法共同工作?br />  jQuery目前鼓吹的主要卖点之一是对名字空间的良好控制。这甚至比提供更多更完善的功能点都重要的多。良好的模块化允许我们复用Q何来源的代码Q所有h的工作得以积累叠加。而功能实C仅是一时的工作量的问题。jQuery使用module pattern的一个变U来减少对全局名字I间的媄?仅仅在window对象上增加了一个jQuery对象(也就?函数)?br />   所谓的module pattern代码如下Q它的关键是利用匿名函数限制临时变量的作用域?br />  var feature =(function() {

// U有变量和函?br />var privateThing = 'secret',
    publicThing = 'not secret',

    changePrivateThing = function() {
        privateThing = 'super secret';
    },

    sayPrivateThing = function() {
        console.log(privateThing);
        changePrivateThing();
    };

// q回对外公开的API
return {
    publicThing : publicThing,
    sayPrivateThing :  sayPrivateThing
}
})();
  js本n~Z包结构,不过l过多年的尝试之后业内已l逐渐l一了对包加载的认识QŞ成了RequireJs库这样得C定共识的解决Ҏ。jQuery可以与RequireJS库良好的集成在一? 实现更完善的模块依赖理。http://requirejs.org/docs/jquery.html
 
  require(["jquery", "jquery.my"], function() {
    //当jquery.js和jquery.my.js都成功装载之后执?br />    $(function(){
      $('#my').myFunc();
    });
  });
 
  通过以下函数调用来定义模块my/shirt, 它依赖于my/cart和my/inventory模块Q?br />  require.def("my/shirt",
    ["my/cart", "my/inventory"],
    function(cart, inventory) {
        // q里使用module pattern来返回my/shirt模块对外暴露的API
        return {
            color: "blue",
            size: "large"
            addToCart: function() {
                // decrement是my/inventory对外暴露的API
                inventory.decrement(this);
                cart.add(this);
            }
        }
    }
  );

3. 奇?Q对象提?br />  当你W一眼看?函数的时候,你想C什么?传统的编E理论L告诉我们函数命名应该准确Q应该清晰无误的表达作者的意图Q甚臛_U长名字要优于短名字Q因为减了出现歧义的可能性。但是,$是什么?qQ它所传递的信息实在是太隐晦Q太暧昧了?是由prototype.js库发明的Q它真的是一个神奇的函数Q因为它可以一个原始的DOM节点提升(enhance)Z个具有复杂行为的对象。在prototype.js最初的实现中,$函数的定义ؓ
  var $ = function (id) {
    return "string" == typeof id ? document.getElementById(id) : id;
  };
  q基本对应于如下公式
      e = $(id)
  q绝不仅仅是提供了一个聪明的函数名称~写Q更重要的是在概念层面上建立了文本id与DOM element之间的一一对应。在未有$之前Qid与对应的element之间的距d分遥q,一般要element~存到变量中Q例?br />  var ea = docuement.getElementById('a');
  var eb = docuement.getElementById('b');
  ea.style....
但是使用$之后Q却随处可见如下的写?br />  $('header_'+id).style...
  $('body_'+id)....
id与element之间的距M乎被消除了,可以非常紧密的交l在一赗?br />  prototype.js后来扩展?的含义,
  function $() {
    var elements = new Array();
    
    for (var i = 0; i < arguments.length; i++) {
        var element = arguments[i];
        if (typeof element == 'string')
          element = document.getElementById(element);
    
        if (arguments.length == 1)
          return element;
    
        elements.push(element);
    }
    
    return elements;
  }
  q对应于公式
    [e,e] = $(id,id)
  很遗憾,q一步prototype.js走偏了,q一做法很少有实用的价倹{?br />  真正?发扬光大的是jQuery, 它的$对应于公?br />    [o] = $(selector)
  q里有三个增?br />  A. selector不再是单一的节点定位符Q而是复杂的集合选择W?br />  B. q回的元素不是原始的DOM节点Q而是l过jQueryq一步增强的h丰富行ؓ的对象,可以启动复杂的函数调用链?br />  C. $q回的包装对象被造型为数lŞ式,集合操作自然的整合到调用链中?br />
  当然,以上仅仅是对奇?的一个过分简化的描述,它的实际功能要复杂得? 特别是有一个非常常用的直接构造功?
   $("<table><tbody><tr><td>...</td></tr></tbody></table>")....
  jQuery根据传入的html文本直接构造出一pd的DOM节点,q将其包装ؓjQuery对象. q在某种E度上可以看作是对selector的扩? html内容描述本n是一U唯一指定.
  $(function{})q一功能实在是让h有些无语? 它表C当document.ready的时候调用此回调函数。真的,$是一个神奇的函数, 有Q何问题,?一下?br />  ȝh, $是从普通的DOM和文本描qC界到h丰富对象行ؓ的jQuery世界的跃q通道。跨q了q道门,来C理想国?br />   
4. 无定形的参数Q专注表达而不是约?br />  q型语a既然头上着??? 总难免让人有些先天不的感觉. 在程序中~ZcdU束, 是否真的是一U重大的~憾? 在传l的强类型语a? 函数参数的类?个数{都是由~译器负责检查的U束条g, 但这些约束仍然是q远不够? 一般应用程序中Z加强U束, M增加大量防M性代? 例如在C++中我们常用ASSERT, 而在java中也l常需要判断参数值的范围
    if (index < 0 || index >= size)
        throw new IndexOutOfBoundsException(
            "Index: "+index+", Size: "+size);            
  很显? q些代码导致程序中存在大量无功能的执行路径, x们做了大量判? 代码执行到某个点, pȝ抛出异常, 大喊此\不? 如果我们换一个思\, 既然已经做了某种判断,能否利用q些判断的结果来做些什么呢? javascript是一U弱cd的语a,它是无法自动U束参数cd? 那如果顺势而行,q一步弱化参数的形? ??推进CU极? 在弱无可q时? weak会不会成为标志性的特点?
  看一下jQuery中的事gl定函数bind,
   A. 一ơ绑定一个事?$("#my").bind("mouseover", function(){});
   B. 一ơ绑定多个事?$("#my").bind("mouseover mouseout",function(){})
   C. 换一个Ş? 同样l定多个事g
      $("#my").bind({mouseover:function(){}, mouseout:function(){});
   D. 想给事g监听器传点参?br />      $('#my').bind('click', {foo: "xxxx"}, function(event) { event.data.foo..})
   E. 想给事g监听器分个组
      $("#my").bind("click.myGroup″, function(){});
   F. q个函数Z么还没有疯掉???
   
   q是类型不定, 在固定位|上的参数的意义总要是确定的? 退一万步来说, q是参C|不重要?函数本n的意义应该是定的吧? 但这是什?
      取?value = o.val(), 讄?o.val(3)
      
   一个函数怎么可以q样q分, 怎么能根据传入参数的cd和个C同而行Z同呢? 看不眼是不? 可这是Z的hD. 既然不能防止, 那就故意允许. 虽然形式多变, 却无一句废? ~少U束, 不妨表?我不是出来吓人的).
   
5. 铑ּ操作: U性化的逐步l化
  jQuery早期最主要的卖点就是所谓的铑ּ操作(chain).
 
  $('#content') // 扑ֈcontent元素
    .find('h3') // 选择所有后代h3节点
    .eq(2)      // qo集合, 保留W三个元?br />        .html('改变W三个h3的文?)
    .end()      // q回上一U的h3集合
    .eq(0)
        .html('改变W一个h3的文?);

在一般的命o式语a? 我们总需要在重重嵌套循环中过滤数? 实际操作数据的代码与定位数据的代码纠~在一? 而jQuery采用先构造集合然后再应用函数于集合的方式实现两种逻辑的解? 实现嵌套l构的线性化. 实际? 我们q不需要借助q程化的思想可以很直观的理解一个集? 例如 $('div.my input:checked')可以看作是一U直接的描述,而不是对q程行ؓ的跟t?
   循环意味着我们的思维处于一U反复回l的状? 而线性化之后则沿着一个方向直U前q? 极大减轻了思维负担, 提高了代码的可组合? Z减少调用铄中断, jQuery发明了一个绝妙的L: jQuery包装对象本ncM数组Q集合). 集合可以映射到新的集合, 集合可以限制到自q子集合,调用的发赯是集合Q返回结果也是集合,集合可以发生l构上的某种变化但它q是集合, 集合是某U概念上的不动点Q这是从函数式语a中吸取的设计思想。集合操作是太常见的操作, 在java中我们很Ҏ发现大量所谓的装函数其实是在封装一些集合遍历操? 而在jQuery中集合操作因为太直白而不需要封?
   铑ּ调用意味着我们始终拥有一?#8220;当前”对象Q所有的操作都是针对q一当前对象q行。这对应于如下公?br />     x += dx
调用铄每一步都是对当前对象的增量描qͼ是针Ҏl目标的逐步l化q程。Witrixq_中对q一思想也有着q泛的应用。特别是Z实现q_机制与业务代码的融合Q^C提供对象Q容器)的缺省内容,而业务代码可以在此基上进行逐步l化的修正,包括取消~省的设|等?br />  话说回来, 虽然表面上jQuery的链式调用很? 内部实现的时候却必须自己多写一层@? 因ؓ~译器ƈ不知?自动应用于集合中每个元素"q回?
  $.fn['someFunc'] = function(){
    return this.each(function(){
      jQuery.someFunc(this,...);
    }
  }
 
6. data: l一数据理
  作ؓ一个js库,它必解决的一个大问题是js对象与DOM节点之间的状态关联与协同理问题。有些js库选择以js对象ZQ在js对象的成员变量中保存DOM节点指针Q访问时L以js对象为入口点Q通过js函数间接操作DOM对象。在q种装下,DOM节点其实只是作ؓ界面展现的一U底?#8220;汇编”而已。jQuery的选择与Witrixq_cMQ都是以HTML自nl构为基Q通过js增强(enhance)DOM节点的功能,它提升Z个具有复杂行为的扩展对象。这里的思想是非侵入式设?non-intrusive)和优雅退化机?graceful degradation)。语义结构在基础的HTML层面是完整的Qjs的作用是增强了交互行为,控制了展现Ş式?br />  如果每次我们都通过$('#my')的方式来讉K相应的包装对象,那么一些需要长期保持的状态变量保存在什么地方呢QjQuery提供了一个统一的全局数据理机制?br />  获取数据 $('#my').data('myAttr')   讄数据 $('#my').data('myAttr',3);
q一机制自然融合了对HTML5的data属性的处理
   <input id="my" data-my-attr="4" ... />
 通过 $('#my').data('myAttr')可以读取到HTML中设|的数据?br /> 
 W一ơ访问dataӞjQueryؓDOM节点分配一个唯一的uuid, 然后讄在DOM节点的一个特定的expando属性上, jQuery保证q个uuid在本面中不重复?br />   elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
 以上代码可以同时处理DOM节点和纯js对象的情c如果是js对象Q则data直接攄在js对象自n中,而如果是DOM节点Q则通过cachel一理?br /> 因ؓ所有的数据都是通过data机制l一理的,特别是包括所有事件监听函?data.events)Q因此jQuery可以安全的实现资源管理。在clone节点的时候,可以自动clone其相关的事g监听函数。而当DOM节点的内容被替换或者DOM节点被销毁的时候,jQuery也可以自动解除事件监听函? q安全的释放相关的js数据?br /> 
7. eventQ统一事g模型
  "事g沿着对象树传?q一图景是面向对象界面编E模型的_N所在。对象的复合构成对界面结构的一个稳定的描述Q事件不断在对象树的某个节点发生Qƈ通过冒机制向上传播。对象树很自然的成ؓ一个控制结构,我们可以在父节点上监听所有子节点上的事gQ而不用明与每一个子节点建立兌?br />  jQuery除了Z同浏览器的事件模型徏立了l一抽象之外,主要做了如下增强:
  A. 增加了自定制事g(custom)机制. 事g的传播机制与事g内容本n原则上是无关? 因此自定制事件完全可以和览器内|事仉过同一条处理\? 采用同样的监听方? 使用自定制事件可以增Z码的内聚? 减少代码耦合. 例如如果没有自定制事? 兌代码往往需要直接操作相关的对象
  $('.switch, .clapper').click(function() {
    var $light = $(this).parent().find('.lightbulb');
    if ($light.hasClass('on')) {
        $light.removeClass('on').addClass('off');
    } else {
        $light.removeClass('off').addClass('on');
    }
  });
而如果用自定制事g,则表辄语义更加内敛明确,
  $('.switch, .clapper').click(function() {
    $(this).parent().find('.lightbulb').trigger('changeState');
  });
  B. 增加了对动态创点的事g监听. bind函数只能监听函数注册到已经存在的DOM节点? 例如
    $('li.trigger').bind('click',function(){}}
  如果调用bind之后,新徏了另一个li节点,则该节点的click事g不会被监?
  jQuery的delegate机制可以监听函数注册到父节点上, 子节点上触发的事件会Ҏselector被自动派发到相应的handlerFn? q样一来现在注册就可以监听未来创徏的节?
    $('#myList').delegate('li.trigger', 'click', handlerFn);
  最qjQuery1.7中统一了bind, live和delegate机制, 天下一l? 只有on/off.
    $('li.trigger’).on('click', handlerFn);  // 相当于bind
    $('#myList’).on('click', 'li.trigger', handlerFn);  // 相当于delegate
    
8. 动画队列Q全局旉协调
  抛开jQuery的实C? 先考虑一下如果我们要实现界面上的动画效果, 到底需要做些什? 比如我们希望一个div的宽度在1U钟之内?00px增加?00px. 很容易想? 在一D|间内我们需要不时的去调整一下div的宽? [同时]我们q需要执行其他代? 与一般的函数调用不同的是, 发出动画指o之后, 我们不能期待立刻得到惌的结? 而且我们不能原地{待l果的到? 动画的复杂性就在于:一ơ性表达之后要在一D|间内执行,而且有多条逻辑上的执行路径要同时展开, 如何协调?
  伟大的艾萨克.牛顿爵士在《自然哲学的数学原理》中写道:"l对的、真正的和数学的旉自n在流逝着". 所有的事g可以在时间u上对? q就是它们内在的协调? 因此Z从步骤A1执行到A5, 同时步骤B1执行到B5, 我们只需要在t1时刻执行[A1, B1], 在t2时刻执行[A2,B2], 依此cL.
    t1 | t2 | t3 | t4 | t5 ...
    A1 | A2 | A3 | A4 | A5 ...
    B1 | B2 | B3 | B4 | B5 ...
  具体的一U实现Ş式可以是
  A. Ҏ个动? 其分装Z个Animation对象, 内部分成多个步骤.
      animation = new Animation(div,"width",100,200,1000,
                  负责步骤切分的插值函?动画执行完毕时的回调函数);
  B. 在全局理器中注册动画对象
      timerFuncs.add(animation);
  C. 在全局旉的每一个触发时? 每个注册的执行序列推进一? 如果已经l束, 则从全局理器中删除.
     for each animation in timerFuncs
        if(!animation.doOneStep())
           timerFuncs.remove(animation)

  解决了原理问?再来看看表达问题, 怎样设计接口函数才能够以最紧凑形式表达我们的意? 我们l常需要面临的实际问题:
  A. 有多个元素要执行cM的动?br />  B. 每个元素有多个属性要同时变化
  C. 执行完一个动M后开始另一个动?br />jQuery对这些问题的解答可以说是榨尽了js语法表达力的最后一点剩余h?
   $('input')
     .animate({left:'+=200px',top:'300'},2000)
     .animate({left:'-=200px',top:20},1000)
     .queue(function(){
       // q里dequeue首先执行队列中的后一个函?因此alert("y")
       $(this).dequeue();
       alert('x');
      })
     .queue(function(){
        alert("y");
        // 如果不主动dequeue, 队列执行׃断了,不会自动l箋下去.
        $(this).dequeue();
      });

  A. 利用jQuery内置的selector机制自然表达对一个集合的处理.
  B. 使用Map表达多个属性变?br />  C. 利用微格式表N域特定的差量概念. '+=200px'表示在现有值的基础上增?00px
  D. 利用函数调用的顺序自动定义animation执行的顺? 在后面追加到执行队列中的动画自然要等前面的动d全执行完毕之后再启动.
   
  jQuery动画队列的实现细节大概如下所C?
   A. animate函数实际是调用queue(function(){执行l束旉要调用dequeue,否则不会驱动下一个方法})
      queue函数执行? 如果是fx队列, q且当前没有正在q行动画(如果q箋调用两次animate,W二ơ的执行函数在队列中等?,则会自动触发dequeue操作, 驱动队列q行.
      如果是fx队列, dequeue的时候会自动在队列顶端加?inprogress"字符?表示要执行的是动画.
   B. 针对每一个属性,创徏一个jQuery.fx对象。然后调用fx.custom函数(相当于start)来启动动甅R?br />   C. custom函数中将fx.step函数注册到全局的timerFuncs中,然后试图启动一个全局的timer.
       timerId = setInterval( fx.tick, fx.interval );
   D. 静态的tick函数中将依次调用各个fx的step函数。step函数中通过easing计算属性的当前|然后调用fx的update来更新属性?br />   E. fx的step函数中判断如果所有属性变化都已完?则调用dequeue来驱动下一个方法?br />
  很有意思的? jQuery的实C码中明显有很多是接力触发代码: 如果需要执行下一个动d取出执行, 如果需要启动timer启动timer{? q是因ؓjsE序是单U程?真正的执行\径只有一?Z保证执行U烦不中? 函数们不得不互相帮助一? 可以惌, 如果E序内部h多个执行引擎, 甚至无限多的执行引擎, 那么E序的面貌就会发生本质性的改变. 而在q种情Ş? 递归相对于@环而言会成为更自然的描q?
 
9. promise模式Q因果关pȝ识别
  现实?L那么多时间线在独立的演化着, Z物在时空中交?却没有发生因? 软g? 函数们在源代码中排着? 隑օ会生一些疑? 凭什么排在前面的要先执行? N没有它就没有? 让全宇宙喊着1,2,3齐步前进, 从上帝的角度?大概是管理难度过大了, 于是便有了相对论. 如果怺之间没有交换信息, 没有产生怺依赖, 那么在某个坐标系中顺序发生的事g, 在另外一个坐标系中看? 可能是颠倒顺序的. E序员依葫芦ȝ, 便发明了promise模式.
  promise与future模式基本上是一回事,我们先来看一下java中熟悉的future模式.
  futureResult = doSomething();
  ...
  realResult = futureResult.get();
  发出函数调用仅仅意味着一件事情发生过, q不必然意味着调用者需要了解事情最l的l果. 函数立刻q回的只是一个将在未来兑现的承诺(Futurecd), 实际上也是某种句柄. 句柄被传来传? 中间转手的代码对实际l果是什?是否已经q回漠不兛_. 直到一D代码需要依赖调用返回的l果, 因此它打开future, 查看了一? 如果实际l果已经q回, 则future.get()立刻q回实际l果, 否则会d当前的执行\? 直到l果q回为止. 此后再调用future.get()L立刻q回, 因ؓ因果关系已经被徏? [l果q回]q一事g必然在此之前发生, 不会再发生变?
  future模式一般是外部对象d查看future的返回? 而promise模式则是由外部对象在promise上注册回调函?
  function getData(){
   return $.get('/foo/').done(function(){
      console.log('Fires after the AJAX request succeeds');
   }).fail(function(){
      console.log('Fires after the AJAX request fails');
   });
  }
 
  function showDiv(){
    var dfd = $.Deferred();
    $('#foo').fadeIn( 1000, dfd.resolve );
    return dfd.promise();
  }
 
  $.when( getData(), showDiv() )
    .then(function( ajaxResult, ignoreResultFromShowDiv ){
        console.log('Fires after BOTH showDiv() AND the AJAX request succeed!');
        // 'ajaxResult' is the server’s response
    });
  jQuery引入Deferredl构, Ҏpromise模式对ajax, queue, document.ready{进行了重构, l一了异步执行机? then(onDone, onFail)向promise中追加回调函? 如果调用成功完成(resolve), 则回调函数onDone被执行, 而如果调用失?reject), 则onFail被执行. when可以{待在多个promise对象? promise巧妙的地Ҏ异步执行已经开始之后甚臛_l结束之?仍然可以注册回调函数
  someObj.done(callback).sendRequest() vs. someObj.sendRequest().done(callback)
 callback函数在发出异步调用之前注册或者在发出异步调用之后注册是完全等L, q揭C出E序表达永远不是完全_? d在着内在的变化维? 如果能有效利用这一内在的可变? 则可以极大提升ƈ发程序的性能.
   promise模式的具体实现很? jQuery._Deferred定义了一个函数队列,它的作用有以下几点:
   A. 保存回调函数?br />   B. 在resolve或者reject的时L保存着的函数全部执行掉?br />   C. 已经执行之后, 再增加的函数会被立刻执行?br /> 
   一些专门面向分布式计算或者ƈ行计的语言会在语言U别内置promise模式, 比如E语言.
     def carPromise := carMaker <- produce("Mercedes");
     def temperaturePromise := carPromise <- getEngineTemperature()
     ...
     when (temperaturePromise) -> done(temperature) {
       println(`The temperature of the car engine is: $temperature`)
     } catch e {
       println(`Could not get engine temperature, error: $e`)
     }
  在E语言? <-是eventuallyq算W? 表示最l会执行, 但不一定是现在. 而普通的car.moveTo(2,3)表示立刻执行得到l果. ~译器负责识别所有的promise依赖, q自动实现调?
 
10. extend: l承不是必须?br />  js是基于原型的语言, q没有内|的l承机制, q一直让很多深受传统面向对象教育的同学们耿耿于怀. 但承一定是必须的吗? 它到底能够给我们带来什? 最U朴的回{是: 代码重用. 那么, 我们首先来分析一下承作Z码重用手D늚潜力.
  曄有个概念叫做"多重l承", 它是l承概念的超U赛亚h? 很遗憑֐来被诊断为存在着先天~陷, 以致于出C一U对于承概늚解读: l承是"is a"关系, 一个派生对?is a"很多基类, 必然会出现精分? 所以多重承是不好?
   class A{ public: void f(){ f in A } }
   class B{ public: void f(){ f in B } }
   class D: public A, B{}
 如果DcMA,B两个基类l承, 而A和BcM都实C同一个函数f, 那么DcM的f到底是A中的fq是B中的f, 抑或是A中的f+B中的f? q一困境的出现实际上源于D的基cA和B是ƈ列关p? 它们满交换律和l合? 毕竟,在概念层面上我们可能难以认可两个L概念之间会出C属关p? 但如果我们放松一些概念层面的要求, 更多的从操作层面考虑一下代码重用问? 可以单的认ؓB在A的基上进行操? 那么可以得C个线性化的结? 也就是说, 攑ּA和B之间的交换律只保留结合律, extends A, B ?extends B,A 会是两个不同的结? 不再存在诠释上的二义? scala语言中的所谓trait(Ҏ?机制实际上采用的是q一{略.
  面向对象技术发明很久之? 出现了所谓的面向斚w~程(AOP), 它与OOP不同, 是代码结构空间中的定位与修改技? AOP的眼中只有类与方? 不知道什么叫做意? AOP也提供了一U类似多重承的代码重用手段, 那就是mixin. 对象被看作是可以被打开,然后L修改的Map, 一l成员变量与Ҏp直接注射到对象体? 直接改变了它的行?
  prototype.js库引入了extend函数,
  Object.extend = function(destination, source) {
    for (var property in source) {
      destination[property] = source[property];
    }
    return destination;
  }
  是Map之间的一个覆盖运? 但很用, 在jQuery库中也得C延用. q个操作cM于mixin, 在jQuery中是代码重用的主要技术手D?--没有l承也没什么大不了?

11. 名称映射: 一切都是数?
  代码好不? 循环判断必须? 循环和判断语句是E序的基本组成部? 但是优良的代码库中却往往找不到它们的t媄, 因ؓq些语句的交l会模糊pȝ的逻辑ȝ, 使我们的思想q失在疲于奔命的代码q踪? jQuery本n通过each, extend{函数已l极大减了对@环语句的需? 对于判断语句, 则主要是通过映射表来处理. 例如, jQuery的val()函数需要针对不同标{进行不同的处理, 因此定义一个以tagName为key的函数映表
   valHooks: { option: {get:function(){}}}
q样在程序中׃需要到处写
   if(elm.tagName == 'OPTION'){
     return ...;
   }else if(elm.tagName == 'TEXTAREA'){
     return ...;
   }
可以l一处理
   (valHooks[elm.tagName.toLowerCase()] || defaultHandler).get(elm);
   
  映射表将函数作ؓ普通数据来理, 在动态语a中有着q泛的应? 特别? 对象本n是函数和变量的容器, 可以被看作是映射? jQuery中大量用的一个技巧就是利用名U映来动态生成代? 形成一U类似模板的机制. 例如Z实现myWidth和myHeight两个非常cM的函? 我们不需?br />  jQuery.fn.myWidth = function(){
      return parseInt(this.style.width,10) + 10;
    }
    
    jQuery.fn.myHeight = function(){
      return parseInt(this.style.height,10) + 10;
    }
而可以选择动态生?br />    jQuery.each(['Width','Height'],function(name){
      jQuery.fn['my'+name] = function(){
        return parseInt(this.style[name.toLowerCase()],10) + 10;
      }
    });
 
12. 插g机制Q其实我很简?nbsp;   
  jQuery所谓的插g其实是$.fn上增加的函数, 那这个fn是什么东?
  (function(window,undefined){
    // 内部又有一个包?br />    var jQuery = (function() {
      var jQuery = function( selector, context ) {
            return new jQuery.fn.init( selector, context, rootjQuery );
        }
       ....
      // fn实际是prototype的简?br />      jQuery.fn = jQuery.prototype = {
          constructor: jQuery,
          init: function( selector, context, rootjQuery ) {...  }
      }
    
      // 调用jQuery()是相当于new init(), 而init的prototype是jQuery的prototype
      jQuery.fn.init.prototype = jQuery.fn;
    
      // q里q回的jQuery对象只具备最基本的功? 下面是一pd的extend
      return jQuery;
    })();  
    ...
     // jQuery暴露为全局对象
    window.jQuery = window.$ = jQuery;
  })(window);
  昄, $.fn其实是jQuery.prototype的简?
 
  无状态的插g仅仅是一个函? 非常?
  // 定义插g
  (function($){
      $.fn.hoverClass = function(c) {
          return this.hover(
              function() { $(this).toggleClass(c); }
          );
      };
  })(jQuery);
 
  // 使用插g
  $('li').hoverClass('hover');
 
 对于比较复杂的插件开? jQuery UI提供了一个widget工厂机制,
 $.widget("ui.dialog", {
   options: {
        autoOpen: true,...
     },
     _create: function(){ ... },
     _init: function() {
        if ( this.options.autoOpen ) {
            this.open();
        }
     },
     _setOption: function(key, value){ ... }
     destroy: function(){ ... }
 });
 
 调用 $('#dlg').dialog(options)? 实际执行的代码基本如下所C?
  this.each(function() {
        var instance = $.data( this, "dialog" );
        if ( instance ) {
            instance.option( options || {} )._init();
        } else {
            $.data( this, "dialog", new $.ui.dialog( options, this ) );
        }
    }
 可以看出, W一ơ调?('#dlg').dialog()函数时会创徏H口对象实例,q保存在data? 此时会调用_create()和_init()函数, 而如果不是第一ơ调? 则是在已l存在的对象实例上调用_init()Ҏ. 多次调用$('#dlg').dialog()q不会创建多个实?

13. browser sniffer vs. feature detection
  览器嗅?browser sniffer)曄是很行的技? 比如早期的jQuery?br />  jQuery.browser = {
        version:(userAgent.match(/.+(?:rv|it|ra|ie)[/: ]([d.]+)/) || [0,'0'])[1],
        safari:/webkit/.test(userAgent),
        opera:/opera/.test(userAgent),
        msie:/msie/.test(userAgent) && !/opera/.test(userAgent),
        mozilla:/mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
  };
  在具体代码中可以针对不同的浏览器作出不同的处?br />  if($.browser.msie) {
      // do something
  } else if($.browser.opera) {
      // ...
  }  

  但是随着览器市场的竞争升, 竞争Ҏ之间的互相模仿和伪装DuserAgent一片؜? 加上Chrome的诞? Safari的崛? IE也开始加速向标准靠拢, sniffer已经起不到积极的作用. Ҏ检?feature detection)作ؓ更细_度, 更具体的手D? 逐渐成ؓ处理览器兼Ҏ的L方式.
  jQuery.support = {
        // IE strips leading whitespace when .innerHTML is used
        leadingWhitespace: ( div.firstChild.nodeType === 3 ),
        ...
    }
    只基于实际看见的,而不是曾l知道的, q样更容易做到兼Ҏ?

14. Prototype vs. jQuery
  prototype.js是一个立意高q的? 它的目标是提供一U新的用体验,参照Ruby从语aU别对javascriptq行攚w,q最l真的极大改变了js的面貌?, extends, each, bind...q些耳熟能详的概念都是prototype.js引入到js领域? 它肆无忌惮的在window全局名字I间中增加各U概? 大有谁先占坑谁有? 舍我其谁的气? 而jQuery则扣扣烦? q比较实用化的理念, 目标仅仅是write less, do more而已.  
  不过{待Ȁq的理想M者的命运往往都是壮志未酬w先? 当prototype.js标志性的bind函数{被吸收到ECMAScript标准中时, 便注定了它的没落. 到处修改原生对象的prototype, q是prototype.js的独门秘技, 也是它的ȝ. 特别是当它试图模仿jQuery, 通过Element.extend(element)q回增强对象的时? 是d被jQueryl带到沟里去? prototype.js与jQuery不同, 它L直接修改原生对象的prototype, 而浏览器却是充满bug, 谎言, 历史包袱q夹杂着商业阴谋的领? 在原生对象层面解决问题注定是一场悲? 性能问题, 名字冲突, 兼容性问题等{都是一个帮助库的能力所无法解决? Prototype.js?.0版本据说要做大的变革, 不知是要与历史决? 攑ּ兼容? q是l箋挣扎, 在夹~中求生.

canonical 2011-12-25 21:23 发表评论
]]>
C++配置理http://www.tkk7.com/canonical/archive/2008/01/12/174892.htmlcanonicalcanonicalSat, 12 Jan 2008 12:58:00 GMThttp://www.tkk7.com/canonical/archive/2008/01/12/174892.htmlhttp://www.tkk7.com/canonical/comments/174892.htmlhttp://www.tkk7.com/canonical/archive/2008/01/12/174892.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/174892.htmlhttp://www.tkk7.com/canonical/services/trackbacks/174892.html   我们希望配置cd配置阶段能够支持动态属性名Q?br />
  GConfig cfg;
  cfg.set(
"bgColor.b",3.0);
  cfg.set(
"lightEnabled",false);

  t_float b 
= cfg.get("bgColor.b");
  bool l 
= cfg.get("lightEnabled");

    但是内部使用时支持直接的属性访问,便于~译器检查, 也提高运速度?br />
        t_float b = cfg.bgColor.b;
        bool l 
= cfg.lightEnabled;


所qC++的类型系l能够偷Ld很多见不得h的勾当,因此便有了下面这个简易机制?br />
#define S_P(x) do{if(strcmp(name,#x) == 0) { x = value; return; } } while(0)
#define G_P(x) 
do{if(strcmp(name,#x) == 0) { value = x; return; } } while(0)

class _GConfig{
public:
  bool lightEnabled;

  t_float minX;
  t_float maxX;
  t_float minY;
  t_float maxY;

  _GConfig(){
    
// initialize all primitive members
    memset(this,0,sizeof(_GConfig));
  }
};

class GConfig: public _GConfig{
public:
  GColor bgColor;

  GConfig(){
  }

  _variant_t get(
const char* name){
    _variant_t value;
    get(name,value);
    
return value;
  }

  
void get(const char* name,_variant_t& value){
    G_P(lightEnabled);

    G_P(minX);
    G_P(maxX);
    G_P(minY);
    G_P(maxY);
   
    G_P(bgColor.r);
    G_P(bgColor.g);
    G_P(bgColor.b);
    G_P(bgColor.a);
  }

  
void set(const char* name, _variant_t value){
    S_P(lightEnabled);

    S_P(minX);
    S_P(maxX);
    S_P(minY);
    S_P(maxY);
   
    S_P(bgColor.r);
    S_P(bgColor.g);
    S_P(bgColor.b);
    S_P(bgColor.a);
  }
};

_variant_t是VC++?lt;comdef.h>中提供的对变体数据类型的装。用S_P和G_Pq样的宏可以q译器查变量名的正性?br />

canonical 2008-01-12 20:58 发表评论
]]>
[导入]OpenSource: 越软g工程http://www.tkk7.com/canonical/archive/2007/12/08/166189.htmlcanonicalcanonicalFri, 07 Dec 2007 18:58:00 GMThttp://www.tkk7.com/canonical/archive/2007/12/08/166189.htmlhttp://www.tkk7.com/canonical/comments/166189.htmlhttp://www.tkk7.com/canonical/archive/2007/12/08/166189.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/166189.htmlhttp://www.tkk7.com/canonical/services/trackbacks/166189.html    现在讲Y件工E的, 所谈论的多半是目工程, 卛_何在有限的时间内配置使用有限的资源在单个目中达到既定的目标. 传统? 在这一领域Z预测和计划的瀑布Ҏ曄占据L, 但是随着目的日益复杂化, 各种Z演化(evolution)思想的工E方法在实证中逐渐发展h. 在时I度更大的软g工程领域, 例如延展到Y件的不同版本以及多个怼目的工E中, 演化更是逐渐取得了无可置疑的dC. 但是, 从另一个方面说, 目前所有这些Y件工E方法所推崇的演化实际上都是非常有限? 它们通过q代(iteration)所能够描述的演化过E都只是片断性的, 例如一个项目中的演? 一个Y件品的演化, 最大的莫过于一整条软g产品U的演化. 所有这些演化过E都面着一个天然的屏障: 商业公司.在公司内? 知识或代码可以由开发h员携带到下一个项? 或者从一个小l传播到另外一个小l? 在新的基上l演化的q程. 但是核心的知识或者代码一般只能通过商业交易传达到其他公? q是一条非常受限制的途径. 而一个单个公司所开发的软g? 即是^台的? 如果只是内部使用, 受限于该公司所从事的业务领? 其所面的用检验也是非常有限的. 而且Zl济上的原因, 单个公司往往无力支撑多个实现同样功能的解x? 因而它們֐于消灭Y件中的多h? q有可能会进一步限制演化的q程.  
    开?OpenSource)软gY件演化创造了新的可能?商业友好的开源Y件可以被不同的公司自qq用于不同的业务, 因而可以参与到不同的局部演化过E中. 在应用的q程? 开源Y仉临着巨大的重构压?q往往是超了应用最q泛的封闭源码Y件包?, 有可能保持更快的演化速度. 而通过对开源Y件的回馈, 对开源Y件的改进可以传播到时I围跨度巨大的软g开发过E中. 而且Z源码的开放? 开发h员的知识交流也随之开放v? cL于Darwinq化? 我们可以说开源驱动了整个软g业界的共同进?co-evolution).
    多年? Eric Raymond在著名的文章"大教堂和市集"?http://263.aka.org.cn/Docs/c&b.html, 提出了开源的工程价? 但其所x的重点仍然只是单个Y件如何在开源的模式下演? 从今天的观点看来, q篇战斗檄文已经昑־有些局促了. 开源所造就的巨大演化空间远q超了软g工程所能够提供? 开源Y件现在已l在商业开发领域站E了脚跟,也渐渐超了单个公司能够控制的范? 可以说开源Y件的发展是无可逆{? 我们已经不会也不应该再回复到原先的封闭世界中.

canonical 2007-12-08 02:58 发表评论
]]>
关于JSFhttp://www.tkk7.com/canonical/archive/2007/07/29/133193.htmlcanonicalcanonicalSun, 29 Jul 2007 15:43:00 GMThttp://www.tkk7.com/canonical/archive/2007/07/29/133193.htmlhttp://www.tkk7.com/canonical/comments/133193.htmlhttp://www.tkk7.com/canonical/archive/2007/07/29/133193.html#Feedback7http://www.tkk7.com/canonical/comments/commentRss/133193.htmlhttp://www.tkk7.com/canonical/services/trackbacks/133193.html   JSF技术是一U双重的存在Q它首先是一U标准,然后也提供了一U缺省的实现。但是从q两斚wQ我都无法看到JSF的未来?br>   从设计上_强类型的视图模型对象层与Witrix的架构设计原则严重冲H。Witrix的基本架构是览器和后台服务器通过h显明语义的url实现两分Q这也是所谓REST风格的一U内在要求。隐蔽了链接的技术破坏了基本的web链模型. Z获得那么一点点l构控制能力, 做出q样的抽象是不合适的.JSF的配|模型承了structs的传l,仍然是那L冗长J杂。我们是否真的需要这些配|文Ӟq是希望像ROR那样在代码中直接完成一切?
   不能在标准的览器中预览. 可以说创造了一个JSF IDE的市? 但是q无疑是一个无聊的市场. 现在有一些备选的Ҏ, 如Facelets, 使得jsf可以采用属性语? 但是只要x仅仅Zq么一点小的修正所需要付出的开发量p以让人崩溃?br>   JSF提供了组件别的事g响应机制Q因此似乎是AJAX应用的理惛_所Q但从Witrixq_的开发实跉|看,JSF对于AJAX的用是受限制的Q有着很大局限性的Q组件事件响应ƈ不一定要采取JSF那种体系l构Q?br>   从实现角度上_Zjsp tag可以说是JSF的致命弱点之一. jsp tag从设计之始就一直是未经q实践考量Q其设计无法支撑复杂的控件架? 特别是早期JSF与标准的JSP tag不能互通实际上是明昄设计~陷, 而且性能问题是内|在该设计中? 现在虽经多个版本的不断补? 但是Z兼容? JSP Tag负担q重, 它始l是Z文本处理模型Q实际上不可能有什么本质性的q步. JSP tag模型q分孱弱必然造成JSF设计中大量处理过E堆叠到界面对象层,更加剧了JSF的模型复杂度和性能瓉?实际上根据Witrixq_中tpl模板技术的设计l验Q大量界面构E是可以在模板层以直观的方式完成的,而不需要借助视图模型对象?br>   所有问题的一个集中体现就是增加一个新的JSFlgl对不是一件^凡的事情Q如果有一天这个问题可以得到解冻I那时的JSF从思想和实C都必然和现在的JSF有着本质性的区别Q?br>

canonical 2007-07-29 23:43 发表评论
]]>
Hibernate动态化http://www.tkk7.com/canonical/archive/2006/07/23/59703.htmlcanonicalcanonicalSun, 23 Jul 2006 13:13:00 GMThttp://www.tkk7.com/canonical/archive/2006/07/23/59703.htmlhttp://www.tkk7.com/canonical/comments/59703.htmlhttp://www.tkk7.com/canonical/archive/2006/07/23/59703.html#Feedback8http://www.tkk7.com/canonical/comments/commentRss/59703.htmlhttp://www.tkk7.com/canonical/services/trackbacks/59703.html    在hbm定义文g?如果我们不指定name属?而是指定entity-name属?则我们可以将entity映射为Map, 而不是一个java实体c?
  <class
    entity-name="test.DynamicEntity"
    table="DYNAMIC_ENTITY"
  >...</class>
  此外, 也可以选择部分字D动态映到Map
  <class ...>
    <dynamic-component name="dynamicAttributes">
      <property name="foo" column="FOO"/>
      <property name="bar" column="BAR"/>
    </dynamic-component>
  </class>
在HQL语句中可以直接用o.dynamicAttributes.foo来访问foo属性,所有操作与普通属性相同?br />  Z实现hiberante映射模型的动态更斎ͼ我们首先需要实现sessionFactory的动态更新。目前hibernate的实现只允许从hbm文g重徏sessionFactory, xZ个sessionFactory替换原有的sessionFactory, 在用spring的情况下Q这需要对org.springframework.orm.hibernate3.LocalSessionFactoryBeanq行小的hack?br />  Z动态属性和普通属性同样对待,要求在操作实体对象属性的时候需要能够自动处理nested property, 即需要如下类似的ҎQentityDao.getProperty(entity,"dynamicAttributes.foo"), entityDao.setProperty(entity,"dynamicAttributes.foo", attrValue).
  Z使得应用E序自动处理新增属性,要求E序是meta驱动的:当实体对象增加了一个属性时Q只需要修改meta文gQ即可完成对于该属性的增删Ҏ汇ȝ普通应用需求?img src ="http://www.tkk7.com/canonical/aggbug/59703.html" width = "1" height = "1" />

canonical 2006-07-23 21:13 发表评论
]]>
关于Ruby DSLhttp://www.tkk7.com/canonical/archive/2006/07/16/58462.htmlcanonicalcanonicalSun, 16 Jul 2006 14:41:00 GMThttp://www.tkk7.com/canonical/archive/2006/07/16/58462.htmlhttp://www.tkk7.com/canonical/comments/58462.htmlhttp://www.tkk7.com/canonical/archive/2006/07/16/58462.html#Feedback2http://www.tkk7.com/canonical/comments/commentRss/58462.htmlhttp://www.tkk7.com/canonical/services/trackbacks/58462.html   首先QDSL的核心在于高效的表达语义Q而ƈ不在于是否接q自然语a。接q于自然语言q不意味着更加domainQ?因ؓ自然语言也是一U通用语言Q它未必能够比采用其他语法Ş式的语言更加有效的对domain事物q行描述。典型的有数学符号和化学分子式?br />   W二Q作为DSL, 紧凑的表辑Ş式是一斚wQ另一斚w是这U表辑Ş式的E_性,卛_何防止h们写ZW合DSL规范的语句。ruby语言的片断直接作为DSL无疑是一Unaive的解x案,我们可以L写出大量不同形式的ruby语句Q而它们在语义上是{h的(q意味着通过单元试也无法发现它们的不同Q,即h们不按照设计的DSL语法书写Q这造成DSL的解体?br />   作ؓ一UDSL构造语aQ其核心能力在于如何second class的domain中的概念Q非语言本n内置的概念)装到first class的表辑Ş式中。ruby作ؓ一U动态语aQ可以更加轻易对于自wmeta dataq行内省Q典型的如ruby中的ActiveRecord设计. 但是在我看来Q这U概忉|升能力在ruby的语法结构中也是有限的,原因恰在于ruby的语法太多样化了。实际上Q我更加看好xmll构的均一性?img src ="http://www.tkk7.com/canonical/aggbug/58462.html" width = "1" height = "1" />

canonical 2006-07-16 22:41 发表评论
]]>
about GWThttp://www.tkk7.com/canonical/archive/2006/05/19/47114.htmlcanonicalcanonicalFri, 19 May 2006 13:27:00 GMThttp://www.tkk7.com/canonical/archive/2006/05/19/47114.htmlhttp://www.tkk7.com/canonical/comments/47114.htmlhttp://www.tkk7.com/canonical/archive/2006/05/19/47114.html#Feedback3http://www.tkk7.com/canonical/comments/commentRss/47114.htmlhttp://www.tkk7.com/canonical/services/trackbacks/47114.htmlhttp://code.google.com/webtoolkit/
  最qgoogle发布了Google Web Toolkit(GWT)开发包Q这是一U用java语言开发AJAX应用的开发框架。从技术上看,GWTq没有什么新鲜之处,cM的概念在多年之前已l有各种试了,q些试从未真正吸引到够的注意。GWT的优势也许在于提供了一套模拟工P另外可能在屏蔽browser的兼Ҏ和bug斚w做得更好一些,但是真正的技术思想q没有什么突? Ruby On Rails同样是试囑ְruby语言直接映射到前台程? 但是它通过一个通用的prototype.js库最化了ruby语言和js语言之间的区?在概念上要比GWT的java2js的compiler概念要更加新颖一? (http://mir.aculo.us/stuff/COR_20060413_RailsAjax.pdf)
  对于web开发而言Q我总认发挥web的特Ԍ而不是把它约束到其他领域的开发模式上。js+dom+html文本所能做到的l构控制E度要远q超组件技术,我也从未发现学习java要比学习html要更加容易。也许对于某些对于web一无所知的java开发h员来_GWT有些意义Q也许GWT会特别适合于某些特定的领域Q但是作ZU通用的开发框Ӟ我ƈ不看好它?br />

canonical 2006-05-19 21:27 发表评论
]]>
AJAX and AJAH and MVChttp://www.tkk7.com/canonical/archive/2006/05/09/45295.htmlcanonicalcanonicalTue, 09 May 2006 14:56:00 GMThttp://www.tkk7.com/canonical/archive/2006/05/09/45295.htmlhttp://www.tkk7.com/canonical/comments/45295.htmlhttp://www.tkk7.com/canonical/archive/2006/05/09/45295.html#Feedback2http://www.tkk7.com/canonical/comments/commentRss/45295.htmlhttp://www.tkk7.com/canonical/services/trackbacks/45295.html  在服务器端生成页面片断的方式也称为AJAHQ表面上看v来它比AJAX要简易一些,是很多服务器端框架引入AJAX概念的乡间小径。但有趣的是在基于拉模式(pull mode)的服务器端MVC框架中,AJAH是在架构上比AJAX更加灉|的一U方式。在witrixq_的jsplet框架中,web讉K的基本Ş式如?
   /view.jsp?objectName=XXObject&objectEvent=XXEvent&otherArgs&tplPart=XXPart
其中objectName对应于后台的服务对象QobjectEvent参数映射到服务对象的ҎQview.jsp是对于后台对象进行渲染的模板面Q而tplPart参数可以指定只用模板的某一部分q行渲染。如果我们选择json.jsp或者burlap.jsp作ؓ渲染模板Q则可以退化到q回数据而不是内容的方式。在js中进行简单的装后我们可以通过如下方式q行q程调用Q?br />  new js.Ajax().setObjectName("XXObject").setObjectEvent("XXEvent").addForm("XXFormId").callRemote(callbackFunc);
   它对应的urlh?br />   /json.jsp?objectName=XXObject&objectEvent=XXEvent&...
对于同样的后C务处理,我们可以自由的选择渲染模板Q则可以很自然的得到更多的处理方式,例如q回javascript代码来实现对于前台的回调?br />

canonical 2006-05-09 22:56 发表评论
]]>
[导入]锐道doradohttp://www.tkk7.com/canonical/archive/2006/04/02/38732.htmlcanonicalcanonicalSun, 02 Apr 2006 06:57:00 GMThttp://www.tkk7.com/canonical/archive/2006/04/02/38732.htmlhttp://www.tkk7.com/canonical/comments/38732.htmlhttp://www.tkk7.com/canonical/archive/2006/04/02/38732.html#Feedback2http://www.tkk7.com/canonical/comments/commentRss/38732.htmlhttp://www.tkk7.com/canonical/services/trackbacks/38732.html http://www.bstek.com/
    上v锐道的Dorado框架L是一个基于构件技术的、面向B/S和多层架构体pȝweb应用开发^収ͼ 其前w称为Extra。从具体功能来看Q如果将其看作是一个全功能的web应用开发^収ͼ 那它现在的功能集昑־太单薄了一? 其主要部分还是提供了一些前台的界面控g, 其他如web框架部分,很像是struts的一个简化版Q没有什么特异之处?
    Dorado的技术特Ҏ大量采用ajax技术来实现前台控g. 其前后台交互采用了自定义的基于xml格式的rpc方式, 而数据绑定用了xml数据?例如
    <xml id="__datasetEmployee" >
    <records>
    <record isCurrent="true"  state="none" >
    <new>,~73~73~73~73~73,~68~68,~44~31~32,true,true,295113600000,2034.0,,</new>
    </record>
    </xml>
    record内部使用的是DoradoU有的编?解码规则, 大概是ؓ了压~数据量?
    从Dorado目前提供的界面来看还是比较丰富的,基本满了一般信息系l开发的需? 但是其可扩展性似乎ƈ不是很好. 它虽然号U是lg式开?但是其前台和后台引擎g都没有提供完善的lg模型支持, 只是实现了一些既定的界面lg而已.
    1. 其前台的js函数中存在着大量针对数据cd的switch语句,g其所能够支持的控件类型已l内|在前台引擎? 如果我们要增加一U新的界面组件大概需要在各处修改引擎代码, ~Z一U抽象机?
    2. 后台ViewModel模型g是想构造出一个Component架构? 但这个模型目前看h明显没有Echo2q样的组件模型精? g~Z一U一致的lg重组机制.  Dorado的ViewModel是有状态的, 通过RPC机制, 它实际上可以独立于系lweb层与前台控g交互.
    3. Dataset是Dorado中最重要的数据供体接? 从它所提供的方?getField,deleteRecord, insertRecord, movePrev, moveNext, getPageSize{可以看? q明显是l定C可分表格的数据模型? 实际上整个系l设计似乎都隐含假定了一个Table模型, 例如Validator接口中具有一个函? ViewField getField(), q里明确假定了validate只能针对单个字段q行, 而不是属于某个整体组件的.
    4. Dorado中所有组件的界面代码生成都是以程序方式进行的, 没有模板机制. 因而增加新的控件的实现? 需要在后台通过java代码输出一部分界面, 在前台通过js脚本动态更新界? 工作量相当大.
    5. Dorado中界面输出应该是通过Outputter接口来进?
      public interface Outputter{
        public String getStartOutput(HttpServletRequest req, Object o)throws Exception;
        public String getEndOutput(HttpServletRequest req, Object o) throws Exception;
      }
      q里一斚w与web层Ş成了l定Q另一斚w它必d内部完整的生成界面代码之后一ơ性传入response, q无疑加重了后台的内存压? 输出分成了StartOutput和EndOutput大概是ؓ了支持布局lg{容器类lg, 相当于是lg内部可以有一个洞, q与Jsp Tag模型是匹配的, 但是q种方式很难以高效率实现界面上的l构融合.
    7. Doradog没有直接提供lg的再装机制, 在现有组件中作局部修正往往需要通过代码方式来进?例如表格中的性别字段需要显C图片而不是文? 则需要在Column的onRefresh事g中写入下代码,
            if (record.getValue("sex")){
        cell.innerHTML = "<img src='images/man.gif'>";
        }
        else{
        cell.innerHTML = "<img src='images/woman.gif'>";
        }
    q明昑ַl不是可配置的内容了. 如果我所需要增加的代码是一个复杂的lg, q里很难进行处理了.
    6. Dorado的技术绑定在了IE览器上, 无法兼容其它览? q有些偏ȝ前的标准化方?

    目前的快速开发^台的一个共同特Ҏ集中在单表的CRUD(Create Read Update Delete)? 可以快速完成单表或M表的增删Ҏ. q本也是正确方向,毕竟目前pȝ开发中的大量工作都是重复性的单劳? 但是一般系l设计中Z支持单表操作而在建模的时候引入了对表格模型过强的依赖,  大大降低了系l的可扩展? 另外现在一般weblg框架的设计往往是模仿桌面开发领域的lg模式Q?希望提供完全黑箱式的lg调用方式, q其实是攑ּ了web开发的优势.  实际上借助于xml格式的规范性和单? 我们完全可以提供更加强大的结构组? q把lg装的能力开攄普通程序员.

canonical 2006-04-02 14:57 发表评论
]]>
[导入]同方ezOnehttp://www.tkk7.com/canonical/archive/2006/04/02/38731.htmlcanonicalcanonicalSun, 02 Apr 2006 06:53:00 GMThttp://www.tkk7.com/canonical/archive/2006/04/02/38731.htmlhttp://www.tkk7.com/canonical/comments/38731.htmlhttp://www.tkk7.com/canonical/archive/2006/04/02/38731.html#Feedback5http://www.tkk7.com/canonical/comments/commentRss/38731.htmlhttp://www.tkk7.com/canonical/services/trackbacks/38731.html    http://www.ezone.com.cn
    同方q个公司在我的印象中更像是个pȝ集成商,在Y件方面没有什么独特之处。不知道是否是待遇问题,我也未听说同Ҏ下招揽过什么Y仉手。同Ҏq两q? 在Y件^台方面花了一些气力,据说?0多个人,q了一两年Q将同方以前的项目进行提|开发了ezOneq_。现在同方各个事业部开发新目的时候好? 要求使用该^収ͼ不过可能是涉及到总部和各个部门分q问题Q下面的人未必有很大的应用积极性?br />     同方的特Ҏ做过大量目Q行业经验多Q所以ezOne中提供了很多行业lg。ezOne的一个核心部分是portal服务器,是基于Apache目l? 的Jetspeed修改而来Q应该是W合JSR168标准的,所的概念也正是应用集成。以前扫q一眼ezOne的代码,感觉质量一般,性能可能会有一 些问题,但编码还工整。同Ҏ有大量国家资源,应该不至于成为^C品开发商Q开发^台的目的大概q是降低自n开发的隑ֺ。其产品們֐于符合标准,中规 中矩Q大概很难有什么创C处。ezOne中很多基lg都是独立开发的Q例如存储层Q没有用hibernate{开源Y件?br />



canonical 2006-04-02 14:53 发表评论
]]>
[导入]U诺KA-2http://www.tkk7.com/canonical/archive/2006/04/02/38730.htmlcanonicalcanonicalSun, 02 Apr 2006 06:50:00 GMThttp://www.tkk7.com/canonical/archive/2006/04/02/38730.htmlhttp://www.tkk7.com/canonical/comments/38730.htmlhttp://www.tkk7.com/canonical/archive/2006/04/02/38730.html#Feedback7http://www.tkk7.com/canonical/comments/commentRss/38730.htmlhttp://www.tkk7.com/canonical/services/trackbacks/38730.htmlhttp://www.kenoah.com
   前两天和U诺的研发经理聊了一会,也简单看了一下他们的演示。因为比较匆忙,没有谈到什么实质性的内容Q只是有一个粗的印象。科诺目前的发展重点q是? 外的外包业务Q其|站上相关介l材料很,不过据说今年投入较大的资源在国内公司徏讑֒市场开拓上?br />     U诺产品的特Ҏ代码生成。经q可视化配置之后Q可以根据模板生成jsp源代码,E序员可以基于这些代码进行修攏V据说遵守一定的规则之后Q自动生成的? 码与手写代码是相互隔ȝQ自动生成的代码可以无限多次生成而不影响手写代码质量Q但我未看到演示。科诺生成的面只支持IE, 不支持Firefox{浏览器。大概是因ؓ其从事的主要是国外外包业务,其界面的观E度一般。虽然可以修攚w面模板来改变界面风格Q但从我实际看到的模 板代码而言Q重新写一套ƈ不太Ҏ?br />     U诺产品的功能大概是可以完成单表或者主从表的增删改查,q合一个或者多个业务流E。其工作引擎据说是W合WFMC规范的,但从实际操作上看Q似乎不 是一个通用的工作流引擎。至给我演C的时候,工作步骤的每一步,actor所能采取的操作是固定的Q如退回,通过{,g是ؓ审批定制的?br />     与普元EOS相比Q科诺在功能上还是要׃。在开发工具上Q也昑־要简单许多。与普元EOScM的是Q科诺的产品g也只是利用工h据现成的模板刉? 固定模式的代码,在设计思想斚wq没有什么本质性的H破Q与其宣传的lg思想相差甚远。如果要越自动生成的代码作一些事情,q些q_都无法提供什么有? 的支持。科诺所谓的业务lgg是对table的描qͼ其设计工具不太好,臛_我没有找C个汇总视图让我可以看到所有已l配|的字段属性。在讄? 杂字D|者汇dD|面,U诺的品也有很多限Ӟ不太灉|。在前台框架斚wQ科诺写了一个类gstruts的框Ӟ其他׃善可承了。流E方面的讄 被称为所谓的程lgQ运行时可以通过一个js库在界面上进行展现。不同的业务lg应该可以对应到同一程lgQ这大概是U诺所谓的lg重用了吧。开? 工程文g以xml格式q行存储Q看了一|相当复杂Q竟然还和SOAP有关p,不知道他们ؓ什么这么设计(W合标准?Q?br />     在科诺的另外一个印象是Q公叔R有不女性程序员在干zR看来至他们的产品可以由初U程序员掌握q满美国外包开发的需求?img src ="http://www.tkk7.com/canonical/aggbug/38730.html" width = "1" height = "1" />

canonical 2006-04-02 14:50 发表评论
]]>
[导入]再谈普元EOS中的数据ȝhttp://www.tkk7.com/canonical/archive/2006/04/02/38729.htmlcanonicalcanonicalSun, 02 Apr 2006 06:47:00 GMThttp://www.tkk7.com/canonical/archive/2006/04/02/38729.htmlhttp://www.tkk7.com/canonical/comments/38729.htmlhttp://www.tkk7.com/canonical/archive/2006/04/02/38729.html#Feedback2http://www.tkk7.com/canonical/comments/commentRss/38729.htmlhttp://www.tkk7.com/canonical/services/trackbacks/38729.htmlhttp://blog.sina.com.cn/u/1495516693在我的blog上留a,谈到Ҏ据ȝ的不同看? 我本人ƈ未用过普元EOS,所做的判断只是Z我个的W一印象, 很有可能是不准确? 不过, 目前我仍然坚持自己对于普元EOS的看?呵呵.
    
    1. EOS产生的xml描述文g中的大量条目都是EOS自n的结构要求,而与实际业务无关Q即EOS描述文g中的有效信息量密度很?
    衣风认ؓ条目q不是EOS自n的结构要求,而是业务对象的结构描q? q里我的看法是业务对象应该尽量通过领域(Domain)语言来描q? 领域信息的外在表象应该尽量是L?而不是展开? 应该量是抽象的而不是实现细节层面上?例如:
    <function class="test.MyFunctionProvider">
        <args>
            <arg>
                <name>argA</name>
                <value>3</value>
            </arg>
        </args>
    </function>
    以上信息可以描述一个方法调? q里的function, args, arg, name, value{标{讄都是解析器ؓ了理解该调用的语义而规定的l构元素,q些元素q不属于函数本n. 例如我们可以规定如下的调用格式来化描q文件而不损失信息,
    <function class="test.MyFunctionProvider">
        <arg name="argA">3</arg>
    </function>
    而在我们的工作流引擎? 业务操作的调用以装后的形式出现
    <BusinessA:DoWorkA argA="3"/>
    通过标签装之后, 我们在调用的时候所需要提供的信息是最化? 每一个涉及到的元素都是有着业务含义? 而将解析器本w的l构要求隐蔽在封装的标签定义?此后我们如果更换了实?而业务需求不? 则我们的调用处是不会受到影响?
    现在Zxml语法的文件格式很? 我们的工作流引擎也采用了xml描述. 但是我们的一个基本观Ҏ, xml配置文g解析器不应该直接理解文g中所有的标签, 卛_只需要理解自w的l构元素, 而ؓ引入Domain知识保留余地.
   
    2. 普元EOS中的l构g很难q行有效的扩展。而所谓的xmlȝ技术更加剧了这一?
    衣风认ؓ"正是XML作ؓ数据传递的ȝQ才使应用在数据层次上具有了较强的扩展能?。从面向对象的观点看, E序中普适性的基本基元是数据与行ؓ的集合体, 而程序模块之间的交互也绝不仅仅是通过数据来进? 而是往往呈现ZU数据与行ؓ的交l状? 普元的模型应该包含了大量发生紧密兌的局部元? 它们应该处在同一q程(状?I间? 直接讉K对象应该是最?最l济, 最完备的信息传递方? ?xml节点的表达能力远q超了普通的数据cdQ但充其量也不过是对现有数据的规整的树Ş表示Qƈ不具有动态计能力(甚至是最单的lazy evaluationQ?. 实际上对于所谓的ȝ, 最单的模型是一个可以动态管理的变量集合, 那么一个Mapp够了. 在集合中我们可以保存各种对象, 比如xml节点, 但是又不限于xml节点. 从徏模的角度上说, 把xml节点定义ZU集合元素我认ؓ是不合适的. 通过对象的成员函? 我们在对象图中可以包含大量的动态计信? 例如
     obj.getSomeCalculatedAttribute().getLazyLoadValue()
    q些动态语义在U数据含义的xmlȝ技术中不知道如何表?
    对象图表达数据关联的能力也强于树形结构的xml节点, 例如 obj.getRefObj().getRefObj() == obj, 不知道这L兌在普元EOS的数据ȝ中如何表?
    在ƈ发访问中如果需要同? 对于对象, 我们可以使用synchronized机制, 但是对于xml节点不知道如何才能有通用的处理方? 

canonical 2006-04-02 14:47 发表评论
]]>
[导入]普元EOShttp://www.tkk7.com/canonical/archive/2006/04/02/38728.htmlcanonicalcanonicalSun, 02 Apr 2006 06:45:00 GMThttp://www.tkk7.com/canonical/archive/2006/04/02/38728.htmlhttp://www.tkk7.com/canonical/comments/38728.htmlhttp://www.tkk7.com/canonical/archive/2006/04/02/38728.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/38728.htmlhttp://www.tkk7.com/canonical/services/trackbacks/38728.html     http://www.primeton.com/

    ? 元Y件公司是国内专业的中间g提供商,从国家得C不少投资Q做出来的东西也是相当的庞大。最q普元EOS的宣传和发展的势头都很盛。其宣传材料中屡ơ提 到“Y件的涅磐“这一用语Q这明显是一U危a耸听之DQ当然这在业内也不算什么新鲜的事情。按照EOS的宣传,"以图形化的构件组装方式“画”出来的软g 无论从结构上、Ş式上q是开发过E上都堪U简捯美的Y?。这一提法倒是别开生面。图形化与简z,与美竟然q存在着q样必然的联p,实在是一U创举?br />      从普元公开的资料来看,EOS的一个鲜明特征是全面Zxml描述Q即所谓的xml数据ȝ。表面上看v来,xmll构内置于系l内怸g很时,但实 际上QEOS产生的xml描述文g中的大量条目都是EOS自n的结构要求,而与实际业务无关Q即EOS描述文g中的有效信息量密度很低。这是一个危险的? 受EOS的xml描述本n可以看作是一U完全新的编E语aQ但q个语言g没有什么抽象能力和l合能力Q对于关联的表达能力也很弱(到处都是数字 id)。如果直接手工编写,那是一件要Mh的事情。只有通过集成开发环境的可视化界面,EOS才呈现出可理解的一面?br />      EOS的概念与Language Workbench是不同的Q其中的l构g很难q行有效的扩展。而所谓的xmlȝ技术更加剧了这一炏Vxml数据ȝ其实与面向过E编E类|只是q? E变成了serviceQ数据变成了xml节点而已。对象与单数据结构在l构表达上的本质差异在于对象通过成员函数可以装动态结构。虽然xml节点 的表达能力远q超了普通的数据cdQ但充其量也不过是对现有数据的规整的树Ş表示Qƈ不具有动态计能力(甚至是最单的lazy evaluationQ。׃动态计能力,意味着我们很难在系l中动态引入结构,E序中所操纵的结构都需要事前定义出来,q将极大的限制系l的可扩 展性。另一斚wQxml节点受限于自w格式,其描q关联的能力也要׃java对象l构本n。对象通过引用讉K相关对象Q其隐含意义是对象处于同一地址 Q状态)I间中,可以非常自然的保证对象的唯一性ƈ实现同步讉K。在跨越状态空间的边界Ӟxml表示是有意义的,因ؓ我们需要把所有的l构都暴露出来ƈ 加以描述(外在化)。而在状态空间内部,我们需要更加紧致有效的表述方式?br />      在具体的实现中, EOS暴露l程序员的xml操纵API相当的原始,使用h很繁琐。在前台展示面中,如果不用EOS的界面组Ӟ提取数据本n是一U不的困难? EOS的前台展C组件与后台的结合也比较弱,后台改变之后Q缺乏有效的手段来检ƈ保证前后台结构的同步性。所谓的前台构g层似乎只是提供了一些帮助函? 和功能固化的lgQƈ没有提供什么有效的利于l构抽象和结构重l的机制?br />      整个EOS的构架看h很象是一个monster, 我很难想象它的各个部分如何才能独立的Q深入的发展下去?img src ="http://www.tkk7.com/canonical/aggbug/38728.html" width = "1" height = "1" />

canonical 2006-04-02 14:45 发表评论
]]>
[导入]Ajaxl构分析http://www.tkk7.com/canonical/archive/2006/02/22/32012.htmlcanonicalcanonicalWed, 22 Feb 2006 12:33:00 GMThttp://www.tkk7.com/canonical/archive/2006/02/22/32012.htmlhttp://www.tkk7.com/canonical/comments/32012.htmlhttp://www.tkk7.com/canonical/archive/2006/02/22/32012.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/32012.htmlhttp://www.tkk7.com/canonical/services/trackbacks/32012.htmlAjax: A New Approach to Web Applications http://www.adaptivepath.com/publications/essays/archives/000385.php
Ajax(Asynchronous JavaScript + XML)q不是一个革命性的崭新概念Q也许根本就不存在突发的革命Q,它的技术基在多q之前就已经牢固的徏立v来了Q在概念层次上的探讨也早׃是一? 新鲜的话题,只是大规模的有深度的应用g是最q才开始的?br> 从广义上_web应用臛_涉及C个结构,
1. 后台以java语言表达的业务逻辑l构
2。前Chtml语言表达的界面表现结构?/p>

web开发很大一部分工作是建立q两个结构之间的关系。即我们需?br> html <--> java

? 们首先要意识到这两种l构之间q不一定是同构的,卛_台数据的l织方式与前台展现时的结构是不同的。同L数据可以对应于不同的展现l构。这也是所? MVC架构实现模型与视囑ֈȝ依据。传l上Q基于Model2模式的MVC框架中,q两U结构的映射只能在很_的_度上进行(x个页面的_度上)Q因 此妨了装和重用。ؓ了进行细_度的映,我们必须要拥有细_度的结构控制能力。而目前最强的l构控制能力存在于javascript/DHTML模型 之中Q在js中html的结构可以是一D늺性的文本(innerHTML和outerHTML), 可以是层U组l的节点QparentNode, childNodes), 也可以是按照keyl织h的Map(getElementById)。在不同的情形下Q我们可以根据需要选择不同的结构模型?br> ajax体系很直接的一个想法就是将所有关于界面表辑֒控制的结构都推到前台Q由控制力最强的js来控制后台数据模型与前台html模型之间的映?br> html <--> js <==> xml <==> java
在ajax 体系中,xml所扮演的角色是js与java之间的翻译通道Q它js中的l构与java中的l构对应hQ这U翻译比html/java之间的映要 单的多。其实它甚至可以是一U同构的映射Q可以用一U通用的方式来q行Q例如结合burlap与buffalo包的功能。结合webservice的一? 思想Qjs/java之间的映是可以在函数调用这U细_度上自动进行的Q从而我们最l可以在概念上完成html/java之间的细_度映射?/p>

canonical 2006-02-22 20:33 发表评论
]]>
[导入]代码复用(reusehttp://www.tkk7.com/canonical/archive/2006/01/23/29054.htmlcanonicalcanonicalMon, 23 Jan 2006 15:01:00 GMThttp://www.tkk7.com/canonical/archive/2006/01/23/29054.htmlhttp://www.tkk7.com/canonical/comments/29054.htmlhttp://www.tkk7.com/canonical/archive/2006/01/23/29054.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/29054.htmlhttp://www.tkk7.com/canonical/services/trackbacks/29054.html    代码复用包括两个斚wQ概念复用和实现复用。这两者在C++的虚拟函数设计中是合二ؓ一的,l果概念上的模糊往往造成l承机制的滥用。ؓ了复用我们往往? 基类中塞入过多的职责Qƈ在程序中刉了q多的层ơ。java的interface是纯_的概念复用机制Q实现方面的复用我们一般通过ImplscL? UtilscLq行Q即代码片断写为静态函数。一般应该避免在cM写特别多的帮助性成员函敎ͼ因ؓ成员函数隐含的通过成员变量相关着Q比静态函数要更加 难以控制?br>     cL一个整体的概念Q整体概念失效了Q类也就不存在了。从q一点上来说Q它未必是比静态函数更加稳定。概念与实现是两个不同层面的东西。实际上它们一般也 是多对多的关pR同一个概念可能换用多U不同的实现Q而同一D功能代码也可能在多个类中用?br>     代码复用的意义不仅仅在于减少工作量。实际上复用是对软g的一U真正的验,而测试仅仅是一U模拟的验而已。每一ơ复用都是对代码的一ơ拷问。在不断? 用中感受C同用环境中的各U压力,才能实现概念的不断精化ƈ保实现的正性?br>



canonical 2006-01-23 23:01 发表评论
]]>
关于DAO和Servicehttp://www.tkk7.com/canonical/archive/2006/01/23/29053.htmlcanonicalcanonicalMon, 23 Jan 2006 14:57:00 GMThttp://www.tkk7.com/canonical/archive/2006/01/23/29053.htmlhttp://www.tkk7.com/canonical/comments/29053.htmlhttp://www.tkk7.com/canonical/archive/2006/01/23/29053.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/29053.htmlhttp://www.tkk7.com/canonical/services/trackbacks/29053.html     E序开发的q程应该是从业务对象层开始的, q步纯技术性的函数调用剥离到外部的帮助cM, 同时我们会逐渐发现一些业务操作的特定l合也具有明的含义, Z调用的方? 我们会把它们逐步补充到service层中. 在一般的应用? 业务逻辑很难E_到可以抽象出接口的地? 即一个service接口不会对应于两个不同的实现, 在这U情况下使用接口往往也是没有必要?
    
    在用spring的情况下原则上应该避免用getBean的调用方? 应该量通过注入来获得依赖对? 但有时我们难免需要直接获取业务对? 在不使用接口的情况下可以采用如下方式

    class TaskService{
        public static TaskService getInstance(){
            return (TaskService)BeanLoader.getBean(TaskService.class);
        }
    }

    在程序中我们可以直接使用TaskService.getInstance()来得到TaskService对象.通过命名规范的约? 我们可以从类名推导出spring配置文g中的对象? 因而不需要用一个额外的编码字W串?



canonical 2006-01-23 22:57 发表评论
]]>
webE序中的scopehttp://www.tkk7.com/canonical/archive/2006/01/15/28130.htmlcanonicalcanonicalSun, 15 Jan 2006 14:35:00 GMThttp://www.tkk7.com/canonical/archive/2006/01/15/28130.htmlhttp://www.tkk7.com/canonical/comments/28130.htmlhttp://www.tkk7.com/canonical/archive/2006/01/15/28130.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/28130.htmlhttp://www.tkk7.com/canonical/services/trackbacks/28130.html     JBoss的Seam目http://www.jboss.com/products/seam 中引入了一U所谓declarative application state management的机?br>     http://blog.hibernate.org/cgi-bin/blosxom.cgi/Gavin%20King/components.html, 其中的关键是增加了business process和conversationq两个应用直接相关的scope, 它们都是可以Ҏ需要自由创建的. business process context使用jBPM支持long running的状态保? 而conversation context是对session使用的一U精l化, 与beehive目中的page flow所需的scope支持非常cM http://beehive.apache.org/docs/1.0m1/pageflow/pageflow_overview.html. 但目前seam中的scope支持仍是非常原始? 不支持嵌套的context, q意味着对于复杂应用无控制和管理能?

canonical 2006-01-15 22:35 发表评论
]]>
xpath selector vs. css selectorhttp://www.tkk7.com/canonical/archive/2006/01/08/27196.htmlcanonicalcanonicalSun, 08 Jan 2006 15:21:00 GMThttp://www.tkk7.com/canonical/archive/2006/01/08/27196.htmlhttp://www.tkk7.com/canonical/comments/27196.htmlhttp://www.tkk7.com/canonical/archive/2006/01/08/27196.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/27196.htmlhttp://www.tkk7.com/canonical/services/trackbacks/27196.html     问题是在一个复杂的界面控g? html节点本n的结构与界面展现l构q不是一致的,例如一个特定效果的Ҏ可能需要多个html元素互相嵌套才能够实? 因此xpath的相对\径选择能力往往z不上用?除非是提?a >http://www.backbase.com/? L界面抽象?, 而根据内容定位的方式q于灉|, 难以l护一个稳定的概念? 相比较而言, css的选择W所提供的节点定位方式要比xpath更加单直? 它的适用性也早已在大量的实践中得C证实. Zcss选择W实现behaviour机制是一U更加可行的Ҏ. 参见 http://prototype.conio.net/

canonical 2006-01-08 23:21 发表评论
]]>
[导入]UnitTest:语义校验http://www.tkk7.com/canonical/archive/2005/12/28/25795.htmlcanonicalcanonicalWed, 28 Dec 2005 14:34:00 GMThttp://www.tkk7.com/canonical/archive/2005/12/28/25795.htmlhttp://www.tkk7.com/canonical/comments/25795.htmlhttp://www.tkk7.com/canonical/archive/2005/12/28/25795.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/25795.htmlhttp://www.tkk7.com/canonical/services/trackbacks/25795.html   单元试随着agile的流行已l家L晓了Q这正反映了软g的一个本质特征:软g是Man-Made的,而h是不可靠的。Y件出错的高频率必然导致控? 间隔的羃短。我最早是在编写matlabE序的时候独立的发现了单元测试的作用。因为matlab是弱cd的,横纵矢量也不区分Q很Ҏ犯错误,我就为每 一个matlab函数~写了测试脚本,U定了命名规范ؓxxx_test.m, 在测试的时候通过 can_assert来做出判断而不是输出变量内容进行h工检查? 每次作了修改的时候,q行一下can_test_all.mp动搜索测试脚本ƈq行一遍?后来xp出现了, 我也W一ơ听说了单元试q回事,看来英雄所见略同吧 ^_^
   单元试可以看作是对~译器的补充。编译器只能q行语法查(形式Q,而单元测试可以进行语义检?内容Q,它其实维护了E序的一个语义框架。如果单元测 试程序编写出来了Q即使一行业务实C码也没编写,我们手中也已l拥有了一W宝늚财富Q因为程序的语义已经在某U意义下定下来了。重构一般是在维护单 元测试不变的情况下进行的。即我们发现在维护语义不变量的情况下Q系l具有相当的调整余地?br>    坚持单元试的另一个好处是它們֐于良好分ȝ模块Q因为高内聚低耦合的模块才更容易进行测试。ؓ了测试,我们会在不知不觉中在对象职责的分M投注更多 的心力。在witrixq_中,虽然ZEasyMock提供了mock支持Q在实际中却很少使用Q因为模块功能一般很独立Q不需要复杂的mock对象Q? 而对于一般的对象Qeclipse有代码生成功能,可以非常L的生成简单的试对象?br>    虽然JUnit非常行Q我们的单元试也是ZJUnitq行的,但是我们q是q行了一个简单的装Q将JUnit框架的特定要求与具体试代码剥离开来。具体的Q测试类?br>    test.UnitTestl承Q而不是从JUnit的TestCasel承。用Debug.check()来做判断Q而不是JUnit的assertEquals{?br>    class MyTest extends UnitTest{
      public MyTest(String caseName){ super(caseName); }

      public void testMy(){
          MyObject my = new MyObject();
          Object value = myObject.myFunc();
          Debug.check(value.equals("aa"));
          // 可以同时提供一个出错消?br>           Debug.check(value.equals("aa"),"myFunc return invalid : "+value);
      }

      public static void main(String[] args){
        // 不需要IDE或者其他外部的支持可以直接调用测试代码,会自动输出q行旉{?br>         UnitTest.exec(new MyTest("testMy"));
      }
   }



canonical 2005-12-28 22:34 发表评论
]]>
通过l承构造业务对象环?/title><link>http://www.tkk7.com/canonical/archive/2005/12/06/22796.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Tue, 06 Dec 2005 14:33:00 GMT</pubDate><guid>http://www.tkk7.com/canonical/archive/2005/12/06/22796.html</guid><wfw:comment>http://www.tkk7.com/canonical/comments/22796.html</wfw:comment><comments>http://www.tkk7.com/canonical/archive/2005/12/06/22796.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/canonical/comments/commentRss/22796.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/canonical/services/trackbacks/22796.html</trackback:ping><description><![CDATA[    现在很多设计中推崇接口和依赖注入(dependency injection)Q而不們֐于采用承机制来构造程序结构。但很多时候作ZU简便而廉L装Ҏ,l承仍然是不可或~的. 例如与一些Engine打交道的时?需要实现某些特定的接口. 在osworkflow? 我们需要实现FunctionProvider接口, <br>      interface FunctionProvider{<br>         void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException;<br>      }<br>     在Quartz中需要实现Job接口<br>       interface Job{<br>           public void execute(JobExecutionContext context) throws JobExecutionException;<br>       }<br>     q些接口是一U技术性的要求, 它们表示了代码生存所依赖的技术环? Z屏蔽q种对于外部引擎的依? 我们可以单的选择实现一个基c?<br>     abstract class AbstractFunction implements FunctionProvider,Runnable{<br>         Map transientVars;<br>         Map args;<br>         PropertySet ps;<br> <br>         public final void execute(Map transientVars, Map args, PropertySet ps){<br>             this.transientVars = transientVars;<br>             this.args = args;<br>             this.ps = ps;<br>             run();<br>         }<br> <br>         public Object getPersistVar(String name){<br>            return ps.getAsActualType(name);<br>         }<br> <br>         public void setPersistVar(String name, Object value){<br>            ps.setAsActualType(name,value);<br>         }<br> <br>         public void removePersistVar(String name){<br>            ps.remove(name);<br>         }<br>     }<br>     在派生类中我们只要用getPersistVar{函数就可以回避对于osworkflowҎ的PropertySetcȝ依赖Q而只在概念上需要一 个对象的持久化机Ӟ当我们把业务代码从osworkflowUL到其他工作流引擎的时候, 只需要改变一下基cd可.我们可以在基cM引入更加Ҏ的假 设,<br>     abstract AbstractBusinessFunction extends AbstractFunction{<br>         public BusinessObject getBusinessObject(){<br>             return transientVars.get("businessObject");<br>         }<br> <br>         public void commonBusinessOp(){ ... }<br>     }<br> <br>     AbstractBusinessFunction提供的可以是一个完整的业务对象环境Q 我们在派生类中的所有代码都可以是与业务直接相关的,而与具体 的技术实现无养I例如业务变量是存攑֜transientVars中还是存攑֜args中)<br> <br>     class BusinessFunction extends AbstractBusinessFunction{<br>         public void run(){<br>             BusinessObject bo = getBusinessObject();<br>             bo.methodA();<br>             commonBusinessOp();<br>         }<br>     }<br>     对于我们来说实际有意义的是在zcM所书写的代码,基类仅仅提供一个环境而已Q无论我们用Ioc注入业务变量q是从transientVars中主? 获取业务变量Q都是与我们的业务操作无关的Q 实际上在理论上我们希望整个基c都可以是注入的Q包括业务变量和业务操作Q,在泛型编E中q对应于所谓的 policy class. <br> <br> <img src ="http://www.tkk7.com/canonical/aggbug/22796.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/canonical/" target="_blank">canonical</a> 2005-12-06 22:33 <a href="http://www.tkk7.com/canonical/archive/2005/12/06/22796.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]tag技?/title><link>http://www.tkk7.com/canonical/archive/2005/12/02/22301.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Fri, 02 Dec 2005 14:59:00 GMT</pubDate><guid>http://www.tkk7.com/canonical/archive/2005/12/02/22301.html</guid><wfw:comment>http://www.tkk7.com/canonical/comments/22301.html</wfw:comment><comments>http://www.tkk7.com/canonical/archive/2005/12/02/22301.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.tkk7.com/canonical/comments/commentRss/22301.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/canonical/services/trackbacks/22301.html</trackback:ping><description><![CDATA[<p>    tag在国内javaC֌q不流行,q在很大E度上是因ؓjsp tag的设计失误造成的。但在整个开发业界内Qtag已经成ؓ一U广泛应用的技术。微软的dotNet服务器端极端依赖tag技术,而在览器端IE? behaviour, htc也独立的发展h。Longhorn的XAMLQ? Firefox的XUL无一例外的依赖于可自定义的tag。javaC֌的JSF, SiteMesh, Tiles {等Q不可尽数。有些h在前台通过lhtml原有元素增加自定义属性,然后通过javascript去解释的做法Q也是一Uelement enhance概念的变U。至于FreeMarkerq种模板语言Q明明类gtag技术,偏偏不采用xml语法Q简直是自找ȝ?br>     q里最关键的地方就是自定义tag可以实现抽象层次的提升,是一U类g函数装的机Ӟ从而实现概늚分离和明化。基于tag可以实现面元素的组? 化,加上xml语法的可理解性,表达能力以及无与伦比的集成能力,使得tag技术可以超VB{组件开发环境(x集成别h的组件代码难q是集成别h? xml描述文g难)。自定义tag提供的抽象能力不仅仅是面向对象的Q而且是类似AOP的,q些都极大的辅助了我们的思考和设计?/p> <p>    cocoon使用道技术也构造了某种tag机制Q但是它的效率很成问题。从数学上说多个处理函数 g, h, k可以通过函数l合(composition)构成新的函数f</p> <p>    f(data) = g * h * k(data) </p> <p>q是所谓函数式语言强大能力的源泉。cocoon处理的时候从k(data)开始,处理完毕之后调用h, 卛_数是从右向左l合的。如果我们保证处理函数满_l合律,则g*h*k可以预~译为f, 从而解x能问题Q这正是witrixq_中tpl技术所采用的方案?/p> <img src ="http://www.tkk7.com/canonical/aggbug/22301.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/canonical/" target="_blank">canonical</a> 2005-12-02 22:59 <a href="http://www.tkk7.com/canonical/archive/2005/12/02/22301.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> AjaxAnywherehttp://www.tkk7.com/canonical/archive/2005/11/23/21184.htmlcanonicalcanonicalWed, 23 Nov 2005 13:53:00 GMThttp://www.tkk7.com/canonical/archive/2005/11/23/21184.htmlhttp://www.tkk7.com/canonical/comments/21184.htmlhttp://www.tkk7.com/canonical/archive/2005/11/23/21184.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/21184.htmlhttp://www.tkk7.com/canonical/services/trackbacks/21184.htmlhttp://ajaxanywhere.sourceforge.net/index.html
    AjaxAnywhere利用JSP标签把Web面标注出可以动态装载的区域, 可以直接把Q何JSP面转化为AJAX感知lg而不需要进行复杂的Javascript~码.
    <script> ajaxAnywhere.getZonesToLoad = function(url){ return "countriesList"; } </script>
    <select size="10" name="language" onchange="ajaxAnywhere.submitAJAX();">
        <%@ include file="/locales_options_lang.jsp"%>
    </select>

    <aa:zone name="countriesList">

        <select size="10" name="country" >
            <%@ include file="/locales_options_countries.jsp"%>
        </select>

    </aa:zone>
   
   AjaxAnywhere的这U做法与witrixq_中的ajaxҎ有些cM, 例如
   
    <select onchange="new js.Ajax().setObjectEvent('changeLanguage').setParam(this).setTplPart('countriesList').replaceChildren('countriesList')"> ...</select>

    <div id="countriesList">
   <tpl:define id="countriesList">
       ....
   </tpl:define>
    </div>

    但是在AjaxAnywhere的方案中, 后台jsp面L要完整运行的, 它通过servlet filter机制~存所有的jsp输出, 而aa:zone标签则把自己的bodyContentq行后的l果保存在request的attribute? 最后servlet filterҎ调用参数军_q回那些zone的运行结? 而在witrixq_中的Ҏ? 只有指定的tplPart才会被运? 其他部分完全被忽? q种差异的根源在于Jsp Tag技术本w的局限? Jsp Tag的设计是非常原始? 基本上就是在字符串层面上q行操作, 在运行的时候缺乏对面l构强有力的控制. 实际? 在我看来, 所有基于jsp tag的技术都受制于jsp tag的先天的局限? 很难有深度的发展, 包括JSF技?
 

canonical 2005-11-23 21:53 发表评论
]]>
[导入]Quartz d调度http://www.tkk7.com/canonical/archive/2005/11/22/21011.htmlcanonicalcanonicalTue, 22 Nov 2005 09:55:00 GMThttp://www.tkk7.com/canonical/archive/2005/11/22/21011.htmlhttp://www.tkk7.com/canonical/comments/21011.htmlhttp://www.tkk7.com/canonical/archive/2005/11/22/21011.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/21011.htmlhttp://www.tkk7.com/canonical/services/trackbacks/21011.htmlquartz是一个高质量的Q务调度Y件包。其主要l成部分?

Scheduler接口: quartz的执行线E,它根据Trigger军_调度时刻Q根据JobDetail的说明实例化q运行Job

JobDetailc? 可持久化的Q务描qC息。Q务虽然分l,但是仅用作管理标C,d之间q无实质性关? 例如无法定义job chain?br>

Triggerc?d的调度策略。这里的特点是调度策略与d描述分开Q调度策略和d描述都可以分别在Scheduler注册Q然后再兌h。JobDetail与Trigger的关pL一对多?br>

JobDataMap: Q务的q行时可持久化状态信息从JobDetailcM分离出来

Job接口: d的执行代?br>

StatefulJob接口: 无状态Q务对应的JobDataMap可以认ؓ是只ȝ,而有状态的d在多ơ执行过E中保留对JobDataMap所作的修改,一个后果是有状态Q务无法被q发执行?br>

JobExecutionExceptionc? 可以通过JobExecutionException调整调度E序的下一步动?br> Calendar接口: 用于从trigger的调度计划中排除某些旉D,例如假期{?/p>

以上几个部分的交互关pd下:
class JobImpl implements Job{
    public void execute(JobExecutionContext context) throws JobExecutionException{
        JobDetail detail = context.getJobDetail();
        JobDataMap dataMap = detail.getJobDataMap();
        ...
    }
}

scheduler.addCalendar("myHolidays", holidayCalendar, false);
trigger.setCanlendarName("myHolidays");

JobDetail jobDetail = new JobDetail(jobName, jobGroupName, JobImpl.class);

scheduler.scheduleJob(jobDetail, trigger);

JobDetail可以讄如下属?
1. Durability: non-durable的Q务当不再与Q何active trigger兌的时候将会从scheduler中被自动删除?br> 2. Volatility: volatile的Q务在scheduler的两ơ启动之间不会被持久?br> 3. RequestsRecovery: 如果在执行过E中E序意外崩溃Q标Cؓ"request recovery"的Q务在scheduler重v之后会被再ơ执行,此时JobExecutionContext.isRecovering()q回true.

Trigger可以讄如下属?
1. misfireInstruction: 讑֮当trigger错过了触发时ȝ时候需要采取的处理{略

SimpleTrigger按照固定的时间间隔进行触?br> startTime, endTime, repeatCount, repeatInterval

CronTrigger按照日历间隔q行触发
seconds minutes hours day-of-month month day-of-week

在quartz内部QQuartzSchedulerThread按照旉序选择triggerQ没有Q务优先的概念), 然后在JobRunShell中运行Job?/p>

JobRunShell中的调用序如下:

TriggerListener.triggerFired
    Called by the Scheduler when a Trigger has fired, and it's associated JobDetail is about to be executed.

TriggerListener.vetoJobExecution
    Called by the Scheduler when a Trigger has fired, and it's associated JobDetail is about to be executed.

JobListener.jobToBeExecuted
    Called by the Scheduler when a JobDetail is about to be executed (an associated Trigger has occured).

Job.execute
    Called by the Scheduler when a Trigger fires that is associated with the Job.
 
JobListener.jobWasExecuted
    Called by the Scheduler after a JobDetail has been executed, and be for the associated Trigger's triggered(xx) method has

been called.

Trigger.executionComplete
    Called after the Scheduler has executed the JobDetail associated with the Trigger in order to get the final instruction

code from the trigger.

TriggerListener.triggerComplete
     Called by the Scheduler when a Trigger has fired, it's associated JobDetail has been executed, and it's triggered(xx)

method has been called.

SchedulerListener.triggerFinalized [if(trigger.getNextFireTime() == null)]
     Called by the Scheduler when a Trigger has reached the condition in which it will never fire again.

canonical 2005-11-22 17:55 发表评论
]]>
代码习惯http://www.tkk7.com/canonical/archive/2005/11/17/20214.htmlcanonicalcanonicalThu, 17 Nov 2005 03:55:00 GMThttp://www.tkk7.com/canonical/archive/2005/11/17/20214.htmlhttp://www.tkk7.com/canonical/comments/20214.htmlhttp://www.tkk7.com/canonical/archive/2005/11/17/20214.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/20214.htmlhttp://www.tkk7.com/canonical/services/trackbacks/20214.html     for(int i=0;i<myList.size();i++){
        otherList.get(i).getSomeVar().getName();
        otherList.get(i).getSomeVar().getValue();
    }
    q种做法有如下后?
    1. 代码冗长, Ҏ出错, 例如循环体中的某个i写成了j
    2. 函数调用l究是要耗费旉? 在一个@环体中的调用往往Ҏ能有可见的影响. 特别是当函数动态装载数据的时? 例如每次调用该函数都查询数据? q种不用时变量的Ҏ会为系l留下性能隐患.
    3. 一条很长的语句如果不是为流式调用而设计的, 则这U调用方式会影响到我们的调试工作. 例如 当某个中间步骤返回空指针? E序会抛出NullPointerException异常, 而我们得到的信息只是某一行存在空指针异常, 但是无法定位到具体是哪个步骤. 当某个中间步骤返回的g是null但也不是我们所期望的值的时? 我们同样难以诊断出具体出错的步骤. 使用临时变量会试提供便?br>       int i,n=myList.size();
      for(i=0;i<n;i++){
          MyVar var = otherList.get(i);
          var.getName();
          var.getValue();
          ...
      }
      在需要的时候我们可以在出错语句处加上断? 或者直接输出可疑的变量?
    4. 长语句不利于抽象出子函数. 例如在第二种方式中我们抽象出子函数的隑ֺ比第一U方式小
       void processVar(MyVar var){
           var.getName();
           var.getValue();
       }

    造成q些习惯的原因很耐hd, 我猜想缺乏抽象能力似乎是最基本的原? 毕竟为变量v一个名字也是最单的抽象步骤之一.



canonical 2005-11-17 11:55 发表评论
]]>
[导入]EasyCalendar:一l随机游?/title><link>http://www.tkk7.com/canonical/archive/2005/11/16/20142.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Wed, 16 Nov 2005 11:28:00 GMT</pubDate><guid>http://www.tkk7.com/canonical/archive/2005/11/16/20142.html</guid><wfw:comment>http://www.tkk7.com/canonical/comments/20142.html</wfw:comment><comments>http://www.tkk7.com/canonical/archive/2005/11/16/20142.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/canonical/comments/commentRss/20142.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/canonical/services/trackbacks/20142.html</trackback:ping><description><![CDATA[<p><font color="#000000" size="3">在时间u上定位一般比较麻烦,我们可以~写大量的get函数来得到特D时间点Q如 getFirstDayOfMonth(int year,int month), getFirstDayOfNextMonth(int year, int month)Q这不如采用如下正交化的式设计?br>EasyCalendar cal = </font></p> <font color="#000000" size="3">    new EasyCalendar().toYear(2001).toMonth(1).toFirstDayOfMonth().toFirstDayOfWeek();</font><img src ="http://www.tkk7.com/canonical/aggbug/20142.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/canonical/" target="_blank">canonical</a> 2005-11-16 19:28 <a href="http://www.tkk7.com/canonical/archive/2005/11/16/20142.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]数据仓库建模http://www.tkk7.com/canonical/archive/2005/11/15/19835.htmlcanonicalcanonicalTue, 15 Nov 2005 04:29:00 GMThttp://www.tkk7.com/canonical/archive/2005/11/15/19835.htmlhttp://www.tkk7.com/canonical/comments/19835.htmlhttp://www.tkk7.com/canonical/archive/2005/11/15/19835.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/19835.htmlhttp://www.tkk7.com/canonical/services/trackbacks/19835.html关系数据库的关键之处在于关系的分解,在数据库中只定义了数据之间的两两关系Q与应用? 关的更复杂的数据关系需要在q行旉过动态join来构造出来,卌些关pd存在E序中而不是数据库中。实际上Q关pL据库的一个隐含的假定是数据之间很 关联,而在实际应用中单表和M表也正是最常出现的情况。当一个应用频J需要大量表的连接操作的时候,往往意味着关系数据模型的失效,此时我们不得不 攑ּ数据的无冗余性,需要通过预连接来构造实例化视图(Material View)Q将数据之间的复杂关pd化ƈ明确定义出来? 在数据仓库里Q抽象的讨论star schema和snowflake schema哪个更优是一个毫无意义的问题? 应该聚合C么程度,需要根据数据应用的具体情况而定?br>    关系数据库本w定义的是数据之间的两两关系Q缺乏一些全局数据讉K手段。而数据仓库的一个基本概忉|数据I间Q即可以通过全局坐标来直接访问数据,而不? 通过两两q接来访问数据。在数据仓库中最重要的就是时间维度,因ؓq是所有数据所׃n的一个坐标维度。我们可以将两个发生在同一旉点上的数据直接ƈ列在 一P而无论它们之间是否定义了兌(relation)?br> 关系数据库的基本数据讉K模式如下Q?br> select 属性列?nbsp;           
 from 表A, 表B
 where 表A.data_id = 表B.id
 and 表B.attr = 'A'
 在数据仓库中 " from 表A, 表B where 表A.data_id = 表B.id "q一部分多个多个数据表和表之间的关联条件放在一起定义ؓ所谓的主题?br> ?表B.attr = 'A' q一部分׃where子句中分d来作为坐标条件?br>    在数据仓库中建立旉坐标有两U方式,对于发生在时间点上的事g我们直接建立点坐标,通过his_date字段来表C,而对于gl一D|间的状态数据,我们可以建立区间坐标Q通过from_date和to_date两个字段来表C?/font>

canonical 2005-11-15 12:29 发表评论
]]>
[导入]xml db vs RDBhttp://www.tkk7.com/canonical/archive/2005/11/15/19831.htmlcanonicalcanonicalTue, 15 Nov 2005 04:23:00 GMThttp://www.tkk7.com/canonical/archive/2005/11/15/19831.htmlhttp://www.tkk7.com/canonical/comments/19831.htmlhttp://www.tkk7.com/canonical/archive/2005/11/15/19831.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/19831.htmlhttp://www.tkk7.com/canonical/services/trackbacks/19831.html    关系数据库能够成功的另外一个重要原因是它采用^面表形式Q而应用中大量使用的正是^面表Q所以数据库表在很多时候是数据的最适表现Ş式,使用xml表达 只会增加不必要的复杂性。^面表的基本假设是所有条目的l构都是一LQ具有一个headerQ,而xml表示形式本n不存在这L假定Q因此很多时候无 法根据数据的shape来做有效的优化。当然xml schema{技术正在快速发展的q程中,当相应的元数据描q和使用技术逐渐成熟之后Qxml的处理方式会得到本质的提高?br>    xml技术是目前元语a的代表,它最重要的技术优势在于它是h与机器都能轻易理解的语言Q是人机׃n的信? 目前它ƈ不适合在应用程序中表达复杂的多l关联。特别是目前多数操纵xml的API都是面向文档的,所存取的数据类型都是字W串Q更造成了程序应用上的困 难?br>


canonical 2005-11-15 12:23 发表评论
]]>
[导入]jsp tag的七宗罪http://www.tkk7.com/canonical/archive/2005/11/15/19830.htmlcanonicalcanonicalTue, 15 Nov 2005 04:21:00 GMThttp://www.tkk7.com/canonical/archive/2005/11/15/19830.htmlhttp://www.tkk7.com/canonical/comments/19830.htmlhttp://www.tkk7.com/canonical/archive/2005/11/15/19830.html#Feedback0http://www.tkk7.com/canonical/comments/commentRss/19830.htmlhttp://www.tkk7.com/canonical/services/trackbacks/19830.html 引用:
jsp tag是服务器端的扩展标签机制Q它是一pdjava服务器端技术的基础。但其设计之初的几个重大~陷已经使得q种技术不堪重负? 

ҎdotNetq_我们可以知道Q需要一U后台标{机Ӟjsp tag是唯一的标准(JSF{机刉依赖于此)Q可它的设计l所有希望基于它开发的开发h员造成了巨大的困扰。实际上我对q个技术感到很失望Q当然我们提 Z相应的替代方案。在我们的开发框架中使用的是重新设计的一套与|络无关的xml动态标{机制。我的观ҎZjsp tag技术,无法开发出与dotNet的便L度相当的服务端技术,所以这是它作ؓ标准的罪q。jsp tag不应该是jsp的补充,它搭上了xmlq条大船Q应该去走自q路,而不应该成ؓ应用上的鸡肋?
引用:
1. jsp tag与jsp 模型紧密l定Q得业务逻辑很难抽象到tag中。而且q了jsp环境Q在jsp tag上的技术投资将一无是处? 

q里说业务逻辑可能是有些不妥,Ҏ引v误解。因为我的工作做在中间g层,所以我的原意是Zjsp tag开发一pd的扩展技术,比如~存{。我们的xml标签技术是与jsp模型无关的,在前台用于界面渲染,在后台用于工作流描述。而且很方便的可以与 其它xml技术结合,比如集成ant?

引用:
2. jsp tag的编码逻辑非常J琐, 特别是写loop和容器类标签的时候。在2.0之前不支持从tag本n产生tag更是应用上的主要障碍? 

q绝Ҏ个重大问题,试问多少己去开发jsp tag呢,多半是用用别人的成品。编制困隑օ实就是否定了界面元素的重用。很多h推崇Tapestry, 其实如果jsp tag技术方便一点,何必建立一个完全不同的模型呢?

引用:
3. 使用xml标签的属性直接映到对象属性的Ҏ造成tag对象是有状态的Q不得不通过丑陋的pool机制来解x能问题?
而且性能问题直接限制了大量小标签的用? 

q是一个现实的困难Q一个系l设计师必须考虑?

引用:
4. jsp tag是一U完全动态化的设计,大量可以在编译期q行的优化都无法q行Q基本上所有的q算都是在运行期发生Q限制了性能的提高? 

我们的xml标签技术是先编译再q行的,加上无状态设计,在性能上可以得到控制。我的朋友hotman_x是个C++和js高手Q在他的强烈要求下,我们的xml标签q增加了一个多ơ编译的机制?

引用:

5. 虽然最q的版本已经支持xml格式Q但对于xslt{的集成很不CQ例如现在无法用xslt对jsp文gq行界面布局?

最单的
<web:template src="test.tpl" xslt="layout.xslt" />
<web:mytag xdecorator="face.xslt">
...
</web:mytag>

引用:
6. jsp tag要求使用自定义标{֐Q而无法对已经存在的html标签q行enhance, 造成无法方便的在可视化编辑器中进行编辑? 

Tapestryp为它比较好。我们的xml标签机制也支持属性扩展?

引用:
7. EL表达式竟然不支持调用对象函数

很多人因此觉得OGNL比较好。我们的机制中是对EL做了一定的增强。我不喜ƢOGNL, q于复杂了?br>


canonical 2005-11-15 12:21 发表评论
]]>
[导入]JMX技?/title><link>http://www.tkk7.com/canonical/archive/2005/11/14/19738.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Mon, 14 Nov 2005 09:01:00 GMT</pubDate><guid>http://www.tkk7.com/canonical/archive/2005/11/14/19738.html</guid><wfw:comment>http://www.tkk7.com/canonical/comments/19738.html</wfw:comment><comments>http://www.tkk7.com/canonical/archive/2005/11/14/19738.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/canonical/comments/commentRss/19738.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/canonical/services/trackbacks/19738.html</trackback:ping><description><![CDATA[JMX在技术上的需求可以说是将理功能从功能性接口中分离出来?br> 例如一个缓存接?br> interface ICache{<br>      Object get(Object key);<br>      void put(Object key, Object value);<br> }<br> 但一个具体实现类可能有很多参数可以调_如缓存的最大尺寸等。这些可配置参数一般与具体实现紧密相关Q即与实例相养I而不直接涉及到所要实现的功能。例如实现类可以hsetMaxSize()和getMaxSize()Ҏ?br> ? 果这些配|方法在功能接口中定义,׃造成功能接口的臃肿和不必要的与实现方法之间的依赖。如果直接调用实现类的方法,只能使用reflectionQ? 但是java class作ؓ元数据所承蝲的信息量有限Q需要外部定义一个规范来补充信息。JMX是q样的一U规范?img src ="http://www.tkk7.com/canonical/aggbug/19738.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/canonical/" target="_blank">canonical</a> 2005-11-14 17:01 <a href="http://www.tkk7.com/canonical/archive/2005/11/14/19738.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://k67m.com" target="_blank">þþþùɫAVѹۿɫ </a>| <a href="http://cn-taoqigui.com" target="_blank">2019Ļ</a>| <a href="http://82nnn.com" target="_blank">޾ƷaĻ</a>| <a href="http://91packing.com" target="_blank">ɫվwww</a>| <a href="http://18888kj.com" target="_blank">պaëƬѹۿ</a>| <a href="http://trgod.com" target="_blank">Ƶ </a>| <a href="http://adcaes.com" target="_blank">þŮվ</a>| <a href="http://ybcin.com" target="_blank">պ</a>| <a href="http://eoeoyui.com" target="_blank">þۺϾžһ</a>| <a href="http://sao350.com" target="_blank">һ</a>| <a href="http://yongfu-sh.com" target="_blank">޹ľƷ</a>| <a href="http://hcdigi.com" target="_blank">ʵƵѹۿ</a>| <a href="http://tao-zhe.com" target="_blank">޾Ʒ޿</a>| <a href="http://fdhkauto.com" target="_blank">޾Ʒ</a>| <a href="http://102sds.com" target="_blank">99Ʒ߹ۿƵ</a>| <a href="http://46339cc.com" target="_blank">ձѹۿ</a>| <a href="http://zhaoxinwo.com" target="_blank">ƵƵ</a>| <a href="http://97aimeili.com" target="_blank">ȫ߲ëƬ</a>| <a href="http://da666f.com" target="_blank">ۺ޹һҳ</a>| <a href="http://ahjmdd.com" target="_blank">2022ھƷѸƵ</a>| <a href="http://shnisda.com" target="_blank">ŷ޴Ƭ </a>| <a href="http://6969aaa.com" target="_blank">òѸ</a>| <a href="http://0551dfcy.com" target="_blank">ձѲ</a>| <a href="http://lswqn.com" target="_blank">һһ60Ƶ</a>| <a href="http://www-7479.com" target="_blank">պƵһ</a>| <a href="http://my637.com" target="_blank">ëƬ100ѹۿ</a>| <a href="http://173ba.com" target="_blank">av߹ۿ</a>| <a href="http://hs969.com" target="_blank">smһ</a>| <a href="http://ee45987.com" target="_blank">av㽶ˬˬˬˬ</a>| <a href="http://726zh.com" target="_blank">ѿavһ</a>| <a href="http://86trader.com" target="_blank">ÿձƬ35</a>| <a href="http://6f2igoa4.com" target="_blank">Ļ</a>| <a href="http://2255325.com" target="_blank">޵Ӱѹۿ</a>| <a href="http://txtmp3.com" target="_blank">޹AV</a>| <a href="http://av520av.com" target="_blank">ѻɫappվ</a>| <a href="http://350725.com" target="_blank">ԴWWW</a>| <a href="http://k8h9.com" target="_blank">޳߹ۿ</a>| <a href="http://bobostrong31.com" target="_blank">˵վ</a>| <a href="http://wwwwmmmm.com" target="_blank">һ</a>| <a href="http://grjeans.com" target="_blank">Կ60Ƶ</a>| <a href="http://528676.com" target="_blank">רƵ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>