??xml version="1.0" encoding="utf-8" standalone="yes"?>a天堂在线资源,99re热这里只有精品视频,久久一区二区三区avhttp://www.aygfsteel.com/sean/category/36.htmlRead me, read Sean.zh-cnThu, 04 Aug 2011 02:57:40 GMTThu, 04 Aug 2011 02:57:40 GMT60学好~程Q从写作开始?/title><link>http://www.aygfsteel.com/sean/archive/2011/08/03/355717.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Wed, 03 Aug 2011 15:49:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2011/08/03/355717.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/355717.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2011/08/03/355717.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/355717.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/355717.html</trackback:ping><description><![CDATA[<p> 可能很多Z以ؓ(f)?dng)写作和编E能有什么关pR?/p> <p> 首先Q写作促(j)q我们思考。程序员每天的工作,不论是学?fn)新知识新技术、理解Y仉求、阅M?文档、设计框架、还是实C务逻辑Q都M开思考。相信很多h都有q这L(fng)体验: 对于某个设计或知识点Q你以ؓ(f)自己x(chng)楚了(jin)Q但真要让你解释l别人听Q你又会(x)觉得无从下手Q几轮过后回惛_初,之前所看到和相信的不过是错觉,当你完整的向其他{qC遍之后,你才是真正x(chng)白了(jin)。其实这个道理和书桌上放一只橡皮鸭/填充玩偶(然后向它讲述你的x(chng))的做法是盔R的Q只不过写作本n不光整理?jin)思\Q还留下?jin)文档,同时Q写作的q程也是不断加深印象、提升信?j)的q程Q可谓一丑֤得?/p> <p> 其次Q和写作一P~程的主要目的是与世界交,不论q个世界是指的机器的世界q是人的世界。要有效C机器世界交流Q你~写的代码必ȝ合一定的语法和范式,必须逻辑上讲得通,q样才有意义。而基本的写作训练可以让我们养成主动留意错别字、格式、拼写错误、逻辑错误的习(fn)惯。如C. A. R. Haore所_(d)我们宁要明显无错误的代码Q不要无明显错误的代码。这Ҏ(gu)癖是好程序员必须具备的修充R这也是Z么我看到有明显拼写错误的E序员简历时Q会(x)直接把他/她们拉黑。同样地Q我一直坚持认为,如果E序员写不出l构优良的纯文本文档Q那么我们也不必指望?她能够写Z雅的代码。除此之外,我们q可以再E微发散一? 开源项目那么多Q满类似需要的往(xin)往(xin)不止一个,Z么有的很成功Q有的却无h问|? d/灵魂人物的写作能力,不论是代码、文档、邮件还是PPTQ是很重要的分野。我怿Q改变(sh)界、媄(jing)响更多的人,是很多程序员梦寐以求的,而要做到q一点,M开写作?/p> <p> 最后,写作通常是程序员的短板,亦即最Ҏ(gu)低成本高?sh)出的地斏V我一直很不喜Ƣh为地l不同专业背景的(chung)上文U和理科的标{,仿佛(jng)他们之间没有交集似的。这样做的最大问题在我看来是一方天然地觉得另一方的知识对自己没价|以至于Ş成了(jin)cM"写作是文U生的菜"?~程是理U才要学的东?{谬误。就我的观察Q计机U班?gu)n的同学,往(xin)往(xin)文字表达能力不够强,可能多少和这U心(j)理暗C有兟뀂如此明昄短板Q如果能够引起广大程序员体的重视,肯在写作上持l投入,效果一定是惊h的?/p> <img src ="http://www.aygfsteel.com/sean/aggbug/355717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2011-08-03 23:49 <a href="http://www.aygfsteel.com/sean/archive/2011/08/03/355717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Scala解Hanoi?/title><link>http://www.aygfsteel.com/sean/archive/2009/11/23/303374.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Mon, 23 Nov 2009 11:20:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2009/11/23/303374.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/303374.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2009/11/23/303374.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/303374.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/303374.html</trackback:ping><description><![CDATA[<p>到处吹嘘Scala很长旉?jin),却一直没有在自己的blog上增加过M相关内容Q今天就来补一补。当?dng)Scala的基本特性就不多废话?jin),|上已经有相当多的资料,如果懒得googleQ只想看完本文,那么你只需要知道它是一门以JVM为目标运行环境的?rn)态编E语a(当然QScala官方也有.NET版,但已不是光?Q同时具备面向对象和函数式编E语a的特炏V本文将通过一个简单的CZQ展CScala的FP能力Q其中十分heavy的用C(jin)implicit隐式转换和模式匹配?/p> <p>代码是从guithub的gist上抄的,单改?jin)改Q原始代码见: <a target="_blank">http://gist.github.com/66925</a></p> <p> </p> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">import</span><span style="color: #000000; "> scala.reflect.Manifest<br />   <br /> def simpleName(m:Manifest[_]):String </span><span style="color: #000000; ">=</span><span style="color: #000000; "> {<br />   val name </span><span style="color: #000000; ">=</span><span style="color: #000000; "> m.toString<br />   name.substring(name.lastIndexOf(</span><span style="color: #000000; ">'</span><span style="color: #000000; ">$</span><span style="color: #000000; ">'</span><span style="color: #000000; ">)</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)<br /> }<br />   <br /> trait Num<br /> </span><span style="color: #0000FF; ">final</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> Succ[Pre</span><span style="color: #000000; "><</span><span style="color: #000000; ">:Num] </span><span style="color: #0000FF; ">extends</span><span style="color: #000000; "> Num<br /> </span><span style="color: #0000FF; ">final</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> _1 </span><span style="color: #0000FF; ">extends</span><span style="color: #000000; "> Num<br /> type _2 </span><span style="color: #000000; ">=</span><span style="color: #000000; "> Succ[_1]<br /> type _3 </span><span style="color: #000000; ">=</span><span style="color: #000000; "> Succ[_2]<br /> type _4 </span><span style="color: #000000; ">=</span><span style="color: #000000; "> Succ[_3]<br />  <br /> </span><span style="color: #0000FF; ">case</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> Move[N</span><span style="color: #000000; "><</span><span style="color: #000000; ">:Num,A,B,C]()<br /> <br /> implicit def move1[A,B,C](implicit a:Manifest[A], b:Manifest[B]) : Move[_1,A,B,C] </span><span style="color: #000000; ">=</span><span style="color: #000000; "> {<br />   System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Move from </span><span style="color: #000000; ">"</span><span style="color: #000000; "> </span><span style="color: #000000; ">+</span><span style="color: #000000; "> simpleName(a) </span><span style="color: #000000; ">+</span><span style="color: #000000; "> </span><span style="color: #000000; ">"</span><span style="color: #000000; "> to </span><span style="color: #000000; ">"</span><span style="color: #000000; "> </span><span style="color: #000000; ">+</span><span style="color: #000000; "> simpleName(b))<br />   </span><span style="color: #0000FF; ">null</span><span style="color: #000000; "><br /> }<br />  <br /> implicit def moveN[P</span><span style="color: #000000; "><</span><span style="color: #000000; ">:Num,A,B,C](implicit m1:Move[P,A,C,B], m2:Move[_1,A,B,C], m3:Move[P,C,B,A]) : Move[Succ[P],A,B,C] </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">null</span><span style="color: #000000; "><br />   <br /> def run[N</span><span style="color: #000000; "><</span><span style="color: #000000; ">:Num,A,B,C](implicit m:Move[N,A,B,C]) </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">null</span><span style="color: #000000; "><br />   <br /> </span><span style="color: #0000FF; ">case</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> Left()<br /> </span><span style="color: #0000FF; ">case</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> Center()<br /> </span><span style="color: #0000FF; ">case</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> Right()<br />   <br /> run[_3,Left,Right,Center]<br /> </span></div> <p> </p> <p>q段代码解决的是l典的汉诺塔问题Q通过一根中柱,左׃64个大依ơ叠加的圆盘全部Ud到右柱,要求整个q程中每ơ只能移动一个圆盘,且每个圆盘只能独立占据一Ҏ(gu)子或是叠加在比自w更大的圆盘?sh)?/p> <p>单分析一下就知道Q这是一个递归问题(FP的英雄特?Q?/p> <ul> <li>当只?个圆盘时Q不用通过中柱Q直接可以从左柱Ud到右柱;</li> <li>当有2个圆盘时Q将盘UdC柱,剩下的大盘移动到x(chng)Q再从中柱把盘Ud到右柱;</li> <li>当有3个圆盘时Q先Ud2个圆盘到中柱Q再Ud大盘到右柱,再移?个圆盘到x(chng)Q?/li> <li>...</li> </ul> <p>很容易发C个patternQ那是UdN(N>1)个圆盘,可以通过以下三个步骤Q?/p> <ol> <li>UdN-1个圆盘,从左柱到中柱Q?/li> <li>Ud剩下?个圆盘,从左柱到x(chng)Q?/li> <li>UdN-1个圆盘,从中柱到x(chng)?/li> </ol> <p>在解释代码之前,先说说Scala的implicit隐式转换Q这是一个非常powerful的ideaQ当Scala~译器发现类型不匚wQ它不会(x)直接failQ而是试从代码中指定的,在scope内的implicit转换定义Q来替换问题对象或表辑ּ以满类型要求,当然Qؓ(f)?jin)避免歧义,同一时刻Scala需要找到唯一的一个满x(chng)件的implicit定义?/p> <p>我们的代码首先定义了(jin)一个取得友好类名的Ҏ(gu)Q不LI它Q然后定义了(jin)一个正整数的序列,也不LI它?jin),你只需要当作他们是正整数就好,接触qFP的同学应该对此类定义不陌生,接下来定义了(jin)如下3个支持implicit传入参数的方法:(x)</p> <ol> <li>implicit def move1[A,B,C](implicit a:Manifest[A], b:Manifest[B]) : Move[_1,A,B,C]</li> <li>implicit def moveN[P<:Num,A,B,C]( implicit <br /> m1:Move[P,A,C,B], <br /> m2:Move[_1,A,B,C], <br /> m3:Move[P,C,B,A]<br /> ) : Move[Succ[P],A,B,C]</li> <li>def run[N<:Num,A,B,C](implicit m:Move[N,A,B,C])</li> </ol> <p>含义分别是:(x)</p> <ol> <li>当需要Move[_1,A,B,C]值时Q可以找我帮?我有个side-effectQ那是输出Ud指o(h))Q?/li> <li>当需要Move[Succ[P],A,B,C]Ӟ可以找我帮忙Q?/li> <li>q行我,我接受Move[N,A,B,C]cd的参数?/li> </ol> <p>单说明:(x)Scala用[]表示cd参数Q区别于Java?lt;>Q另外,Scala的类型声明在变量/函数定义之后。Move[_,A,B,C]的含义是通过CQ从AUd圆盘到B?/p> <p>我们来模拟运行一下,Z(jin)演示效果Q用一个中{复杂的数目Q?个圆盘,从LeftUd到Right?/p> <p>run[_3,Left,Right,Center]Q对应Move[Succ[_2],Left,Right,Center]Q于是展开成三个MoveQ?/p> <p>Move[_2,Left,Center,Right]即Move[Succ[_1],Left,Center,Right]<br /> Move[_1,Left,Right,Center]<br /> Move[_2,Center,Right,Left]即Move[Succ[_1],Center,Right,Left]<br /> </p> <p>然后l箋(hu)展开Move[_2,Left,Center,Right]和Move[_2,Center,Right,Left]Q得刎ͼ(x)</p> <p>Move[_1,Left,Right,Center]<br /> Move[_1,Left,Center,Right]<br /> Move[_1,Right,Center,Left]<br /> --------------------------<br /> Move[_1,Left,Right,Center]<br /> --------------------------<br /> Move[_1,Center,Left,Right]<br /> Move[_1,Center,Right,Left]<br /> Move[_1,Left,Right,Center]<br /> </p> <p>q个时候已l全部都匚wMove[_1,A,B,C]Q于是我们很Ҏ(gu)得到以下输出Q?/p> <p>Move from Left to Right<br /> Move from Left to Center<br /> Move from Right to Center<br /> Move from Left to Right<br /> Move from Center to Left<br /> Move from Center to Right<br /> Move from Left to Right<br /> </p> <p>希望本文能带lScala初学者一些感性认识和启发?/p> <p><br /> </p> <img src ="http://www.aygfsteel.com/sean/aggbug/303374.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2009-11-23 19:20 <a href="http://www.aygfsteel.com/sean/archive/2009/11/23/303374.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于~程语言的typing(一些基本概?http://www.aygfsteel.com/sean/archive/2009/09/28/296825.htmllaogaolaogaoMon, 28 Sep 2009 11:19:00 GMThttp://www.aygfsteel.com/sean/archive/2009/09/28/296825.htmlhttp://www.aygfsteel.com/sean/comments/296825.htmlhttp://www.aygfsteel.com/sean/archive/2009/09/28/296825.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/296825.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/296825.html 最q围观一本JavaScript的书c引发的争论Q一不小?j)碰C讲~程语言cdpȝ划分的帖子,回想起当q还在公司内部的Tech Session上主讲过q个话题Q不q只涉及(qing)到静(rn)?动态、强cd/q型,q没有这位仁兄ȝ的那么全面?br />
原文链接
http://www.reddit.com/r/programming/comments/63tnv/bruce_eckel_33104_im_over_it_java/c02qx55

不多废话Q直入正题:(x)

[l度一] Static vs Dynamic Typing
?rn)态类型和动态类型,区分的关键点为编译期或运行期定cdQ静(rn)态类型在~译期确定,动态类型在q行期确定?br /> ?rn)态类型代?Java、Scala、Haskell
动态类型代?Ruby、Python、Erlang

[l度二] Strong vs Weak Typing
强类型和q型,区分的关键点行时是否自动转换C实际cd不符的类型:(x)强类型要求手工类型{换,q型自动{换?br /> 强类型代?Java、Scala、Python
q型代?C、Assembly、JavaScript

[l度三] Latent (Implicit) vs Manifest (Explicit) Typing
隐式cd和显式类型,区分的关键点为是否要在源码中声明cdQ隐式类型不需要,昑ּcd需要?br /> 隐式cd代表 Haskell、Erlang、Python
昑ּcd代表 C、C++、Java

[l度四](mi) Nominal vs Structural Typing
名义cd和结构类型,区分的关键点为类型判定是Ҏ(gu)标称q是Ҏ(gu)内容Q名义类型根据标Uͼl构cdҎ(gu)内容?br /> 名义cd代表 C、C++、Java
l构cd代表 Haskell、Erlang、Python

关于JavaScript书籍的争论,L(fng)步如下网址Q?br /> 1- |友Hax?炮蘪"?http://www.javaeye.com/topic/474725
2- 周爱?aimingoo)的MSNI间 http://aimingoo.spaces.live.com/blog/
3- 火星帔RJE办事处相兛_ http://mars.group.javaeye.com/group/topic/14325



laogao 2009-09-28 19:19 发表评论
]]>
"?是如何变?å·̔"的?记UTF-8~码http://www.aygfsteel.com/sean/archive/2009/05/05/269045.htmllaogaolaogaoTue, 05 May 2009 11:24:00 GMThttp://www.aygfsteel.com/sean/archive/2009/05/05/269045.htmlhttp://www.aygfsteel.com/sean/comments/269045.htmlhttp://www.aygfsteel.com/sean/archive/2009/05/05/269045.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/269045.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/269045.html本来是手写的一张草E,清理台面的时候,正要扔,发现内容q有Ҏ(gu)思,q脆吧,开个随W记录一下,备忘Q说不定q能帮到别h?br />
在我们日常生zd工作中,其览含有中文的网站,时常?x)?f)q问题犯愁Q一些天生Unicode支持不到位的~程语言和Y件更是加重了(jin)q个现象。虽说已l是2009q了(jin)Q我们时不时q是能碰C些明显脑D的codeQ吐Z堆ؕ码,不论你用选什么字W集Q似乎都无法q原最初的中文。比?å·̔"Q或者同一个页面,无法用同一个字W集昄QQ何一U字W都臛_有一部分昄不正,不是q儿是那儿?br />
首先U普一下UTF-8。UTF-8是Unicode所有字W编码实CQ应用范围最q的一个,最大的特点是兼容ASCII码,在此基础上,通过1..4个byte来表C每一个Unicode字符。它是怎么做到的?其实很简单,看首个byteQ?br />00000000 ~ 01111111 : 0~127 (ASCII, 单个byte) 表示Unicode范围\u0000 ~ \u007F
11000000 ~ 11011111 : (2?打头Q所?个byte) 表示Unicode范围\u0080 ~ \u07FF
11100000 ~ 11101111 : (3?打头Q所?个byte) 表示Unicode范围\u0800 ~ \uFFFF
11110000 ~ 11110111 : (4?打头Q所?个byte) 表示Unicode范围\u10000 ~ \u10FFFF

除了(jin)单个byteq个caseQ其他情况下Q后l的byte均以10打头。这些打头的bitQ?0?10?110?1110Q都不作为具体编码的一部分参与真正Unicode~码的计。所?..4个byteQ其有效位数分别为:(x)7?1?6?1Q因此才有了(jin)\u007F、\u07FF、\uFFFFq样的(f)界|?个byte的空间还有富余?br />
有了(jin)q个基础知识Q我们就来具体看看这??字,是怎么被UTF-8表示的,以及(qing)Z么处理不当的代码?x)最l输?å·̔"?br />
"?字,用Unicode表示法,是\u5DF2Q按?个byte拆开成二q制表示Q?br />01011101 11110010
如果用UTF-8~码Q采?110???? 10?????? 10??????q个格式Q?号部分填入上q?1011101 11110010Q得?br />11100101 10110111 10110010 q样3个byte?br />
好了(jin)Q这个时候脑D代码出玎ͼ假如它不认识UTF-8Q那么他?x)看到这?个前后没有关联的byteQ在西欧Latin-1字符?即ISO 8859-1)中,它们分别表示"å"?·"?̔"q?个字W。如果把它们分别再按照UTF-8~码Q就成了(jin)Q?br />11000011 10100101 11000010 10110111 11000010 10110010
完美的UTF-8~码Q只不过Q这完全是假象,只能通过非常规手D|能恢复它原本的样子?br />



laogao 2009-05-05 19:24 发表评论
]]>
Dreaming in Code 是本好书http://www.aygfsteel.com/sean/archive/2009/03/02/257268.htmllaogaolaogaoSun, 01 Mar 2009 16:44:00 GMThttp://www.aygfsteel.com/sean/archive/2009/03/02/257268.htmlhttp://www.aygfsteel.com/sean/comments/257268.htmlhttp://www.aygfsteel.com/sean/archive/2009/03/02/257268.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/257268.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/257268.html周末׃(jin)一个下午和一个晚上把Scott Rosenberg的Dreaming in Code从头到尾看了(jin)一遍。最直接的感受是q本书把我之前很多记忆碎片串在了(jin)一P成ؓ(f)一个生动?完整"的故事,虽然书的内容本nl织的多还是有Ҏ(gu)?br />
dreaming_in_code.jpg

我本人对Chandlerq个目q不陌生Q之前出于对Python/wxWidget和开源本w的兴趣Q陆l用q几?.x的版本,一开始ƈ不是十分友好Q性能上也有问题,甚至?x)莫名的吃掉我机器上的数癑օQ或者上G?Q空间。后来的版本在性能和可用性上实提高?sh)(jin)不,但一直感觉这个项目缺必要的、以?qing)许多开源项目应有的momentum。Phillip J. Eby对Chandler开发h员(sh)懂Python的批评,当时我的印象也很深。而项目中出现的h物,包括Mitchell Kapor、Ted LeungQ也都在Chandlerq个范畴之外followq。其他细节包括:(x)Chandler和Cosmoq两个名U的由来、Chandler目l中x(chng)成员相寚w的比例、一些熟(zhn)的人物?qing)其观点QAlan Kay, Bill Joy, Frederick Brooks, Donald Knuth、Linus Torvalds, Ward Cunningham, Larry Wall, Guido van Rossum, Joel Spolsky, etc.Q、一些公司的分分和和以及(qing)人员?gu)动{等。感觉挺亲切的?br />
可能更重要、也更深ȝ原因是:(x)管书中一再提?There's no such thing as a typical software project, every project is different"Q我仍然深深的感觉到QChandler遇到的这些问题,其实也是我亲历的很多目的种U问题的一个羃影。对q些问题Q作者ƈ没有l出解决Ҏ(gu)Q其实谁也没有标准答案。Y件开发是一w常具有挑(xi)战性的工作Q也正是像我们这h热情、有涵养的专业h士生存的I间和h(hun)值所在?br />


laogao 2009-03-02 00:44 发表评论
]]>
Debt Metaphorhttp://www.aygfsteel.com/sean/archive/2009/02/22/256062.htmllaogaolaogaoSun, 22 Feb 2009 09:50:00 GMThttp://www.aygfsteel.com/sean/archive/2009/02/22/256062.htmlhttp://www.aygfsteel.com/sean/comments/256062.htmlhttp://www.aygfsteel.com/sean/archive/2009/02/22/256062.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/256062.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/256062.html以下是一D视频,W(xu)ard Cunningham针对Debt Metaphorq个隐喻的由来和Z对它的一些误解进行了(jin)澄清Q?br />


我最感兴的是Burdenq一D:(x)Cunningham解释_(d)l常看到有些开发团队,他们快速的开发出软g产品推向?jng)场Q不断的往(xin)里面d新的Ҏ(gu),在这个过E中Q不断的学习(fn)Q但从不把学到的东西、ȝ的经验教训应用回去,q就像是从银行借贷Q但从不想着有一天需要偿q(是不是有点像是在说引发这ơ次贷危机的国人的消费?fn)惯和观念?Q,到最后,你所有的收入都将用于偿还利息Q你的购买力也将降ؓ(f)零。映回软g开发的语境Q如果我们在一个较长的旉跨度内,开发一个YӞ不断的增加featureQ但从不回过头去整理和重构,把对q个软g和这些特性的新的理解和认知写回去Q那么最l这个Y件、这些feature不再会(x)有Q何实际的价|对它们做M事,都将p来多的时间和_֊Q开发进度也因此下降ؓ(f)零?br />



laogao 2009-02-22 17:50 发表评论
]]>
Python 3.0 Releasedhttp://www.aygfsteel.com/sean/archive/2008/12/04/244431.htmllaogaolaogaoThu, 04 Dec 2008 11:30:00 GMThttp://www.aygfsteel.com/sean/archive/2008/12/04/244431.htmlhttp://www.aygfsteel.com/sean/comments/244431.htmlhttp://www.aygfsteel.com/sean/archive/2008/12/04/244431.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/244431.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/244431.html?a target="_blank" title="http://www.aygfsteel.com/sean/archive/2008/10/04/232389.html" href="/sean/archive/2008/10/04/232389.html">Python 2.6发布两个月后QPython 3.0正式release?jin)?br />
Download: http://www.python.org/download/releases/3.0/
What's New:http://docs.python.org/whatsnew/2.6.html#python-3-0




laogao 2008-12-04 19:30 发表评论
]]>
Python 2.6 Releasedhttp://www.aygfsteel.com/sean/archive/2008/10/04/232389.htmllaogaolaogaoSat, 04 Oct 2008 13:29:00 GMThttp://www.aygfsteel.com/sean/archive/2008/10/04/232389.htmlhttp://www.aygfsteel.com/sean/comments/232389.htmlhttp://www.aygfsteel.com/sean/archive/2008/10/04/232389.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/232389.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/232389.html在国庆(jin)大假q几天,Python 2.6 (final)(zhn)然发布?jin),作?f)为Python 3000 (3.0)\?.x更新版,2.6的发布颇h里程式的意义?br />
Download: http://www.python.org/download/releases/2.6/
What's New: http://docs.python.org/whatsnew/2.6.html




laogao 2008-10-04 21:29 发表评论
]]>
[Tips] 使用Groovy处理邮g通知http://www.aygfsteel.com/sean/archive/2008/08/27/225118.htmllaogaolaogaoWed, 27 Aug 2008 10:55:00 GMThttp://www.aygfsteel.com/sean/archive/2008/08/27/225118.htmlhttp://www.aygfsteel.com/sean/comments/225118.htmlhttp://www.aygfsteel.com/sean/archive/2008/08/27/225118.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/225118.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/225118.html通过Groovy实现邮g通知Q其实是转发到ANTQ十分容易,先上代码Q?br />
 (tng)1 (tng)ant (tng)= (tng)new (tng)AntBuilder()
 (tng)2 (tng)
 (tng)3 (tng)def (tng)mail(subject, (tng)body, (tng)attachment (tng)= (tng)[dir:".",files:[]]) (tng){
 (tng)4 (tng) (tng) (tng) (tng) (tng)ant.mail(mailhost:"mail.com", (tng)mailport:"1025", (tng)user:"mailer", (tng)password:"123", (tng)subject:"${subject}") (tng){
 (tng)5 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)from(address:"nobody@mail.com")
 (tng)6 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)to(address:"nobody@mail.com")
 (tng)7 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)message("${body}")
 (tng)8 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)attachments() (tng){
 (tng)9 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)if (tng)(attachment.files) (tng){
10 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)fileset(dir:"${attachment.dir}") (tng){
11 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)attachment.files.each (tng){
12 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)include(name:it)
13 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
14 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
15 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
16 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
17 (tng) (tng) (tng) (tng) (tng)}
18 (tng)}
19 (tng)
20 (tng)attachment (tng)= (tng)[dir:"/tmp", (tng)files:["some.properties","some.sql"]]
21 (tng)mail("Test (tng)mail (tng)message (tng)at (tng)${new (tng)Date()}", (tng)"This (tng)is (tng)a (tng)test (tng)message.", (tng)attachment)
22 (tng)

q个单的例子很好的展CZ(jin)如下GroovyҎ(gu):(x)
1- Groovy脚本可以不需要定义Q何classQ方法定义和实际调用也可以؜在一P十分手?br />2- 定义变量不需要指定类型,只要赋值即可,不过q行期依然是强类型?br />3- Ҏ(gu)参数可以有默认倹{?br />4- List和Map的构建直接在语义层面提供支持Q如[a:1,b:2]和[1,2]?br />5- GString使得我们可以方便的在String中引用变量甚x(chng)表达式,?${a.b.c}"?${new Date()}"?br />6- 逻辑判断在true/false基础上有所扩展Q[]Q?个元素的ListQ和null均做false处理?br />7- Closure支持Q方便我们在外围代码处“当场”指定处理逻辑Q省M(jin)大多数在Java中需要匿名内部类来处理的ȝ(ch)Q如attachment.files.each { .... }Q只有一个传入参数时Q可直接用it指代?br />8- 与ANT的无~集成,以及(qing)对Builder模式的良好支持,使得我们可以写出上述初看上去有些不可思议的代码?br />
P.S. 虽然Groovy自己已经bundle?jin)ANTQ可以直接用其中的l大多数功能Q不qؓ(f)?jin)调用ANT的mail taskQ还需要将ANT发行版中带有的ant-javamail.jar以及(qing)JavaMail API对应的jar包(可以从Sun|站下蝲Q加到classpath。如果你的JDK版本低于6.0Q还需要activation.jar?br />



laogao 2008-08-27 18:55 发表评论
]]>
[Tips] "When ANT is not enough"升?- Groovy to the rescue!http://www.aygfsteel.com/sean/archive/2008/08/25/224246.htmllaogaolaogaoMon, 25 Aug 2008 11:38:00 GMThttp://www.aygfsteel.com/sean/archive/2008/08/25/224246.htmlhttp://www.aygfsteel.com/sean/comments/224246.htmlhttp://www.aygfsteel.com/sean/archive/2008/08/25/224246.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/224246.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/224246.html 前一随W?/a>提到目前计划pȝ学习(fn)Python和GroovyQ有什么比实际使用更好的学?fn)途径呢?1q多以前Q我曄?a target="_blank" title="http://www.aygfsteel.com/sean/archive/2007/06/18/124859.html" href="/sean/archive/2007/06/18/124859.html">另一随W?/a>提到Q当ANT不够用时Q可以用JRuby+AntwrapQ这是一个可行的Ҏ(gu)Qƈ且经q了(jin)长期实战的考验。不qGroovy可以做的更好Q感兴趣的朋友可以和Antwrap版对照一下)(j)Q?br />
 (tng)1 (tng)#!/usr/bin/env (tng)groovy
 (tng)2 (tng)
 (tng)3 (tng)ant (tng)= (tng)new (tng)AntBuilder()
 (tng)4 (tng)root (tng)= (tng)":pserver:cvsuser:password@10.10.10.1/cvsrepo/SampleProduct"
 (tng)5 (tng)
 (tng)6 (tng)def (tng)checkout() (tng){
 (tng)7 (tng) (tng) (tng) (tng) (tng)ant.cvs(cvsroot:root,command:"checkout (tng)-A","package":".",dest:"cvsoriginal",compressionlevel:"9")
 (tng)8 (tng)}
 (tng)9 (tng)
10 (tng)def (tng)update() (tng){
11 (tng) (tng) (tng) (tng) (tng)ant.cvs(cvsroot:root,command:"update (tng)-A (tng)-d","package":".",dest:"cvsoriginal",compressionlevel:"9")
12 (tng)}
13 (tng)
14 (tng)def (tng)compile(project) (tng){
15 (tng) (tng) (tng) (tng) (tng)ant.javac(srcdir:"cvsoriginal/$project/src",destdir:"cvsoriginal/$project",target:"1.5",encoding:"GBK")
16 (tng) (tng) (tng) (tng) (tng)ant.copy(todir:"cvsoriginal/$project") (tng){
17 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)fileset(dir:"cvsoriginal/$project/src") (tng){
18 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)exclude(name:"**/*.java")
19 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
20 (tng) (tng) (tng) (tng) (tng)}
21 (tng) (tng) (tng) (tng) (tng)ant.jar(destfile:"build/$project.jar",basedir:"cvsoriginal/$project",manifest:"MANIFEST.MF") (tng){
22 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)exclude(name:"src/**")
23 (tng) (tng) (tng) (tng) (tng)}
24 (tng)}
25 (tng)
26 (tng)// (tng)to (tng)actually (tng)call (tng)your (tng)target
27 (tng)checkout (tng)root
28 (tng)

代码更紧凑,与Java的集成更无缝。只需要简单的培训Q有Java基础的朋友就能上手,不必再额外学?fn)和习(fn)惯Ruby的语法,不用gem installQ也不用去monkey-patch个别文g来集成和打包Ant、Antwrap和JRubyQ只需要一个groovy-all-x.x.x.jar加上自己的脚本即可轻松搞定?br />
[2008-08-26 19:25:00 更新] l过实际环境试Q原来JRuby(1.1)+Antwrap需?4分钟完成的构建,改用Groovy(1.5.6)后,仅需?6分钟Q对于需要经常处理构建的目和品来_(d)q?分钟q是相当可观的?br />



laogao 2008-08-25 19:38 发表评论
]]>
08q秋季学?fn)计?/title><link>http://www.aygfsteel.com/sean/archive/2008/08/20/223139.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Tue, 19 Aug 2008 16:33:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2008/08/20/223139.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/223139.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2008/08/20/223139.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/223139.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/223139.html</trackback:ping><description><![CDATA[ <br />从开始专?j)学习(fn)Java到现在,已经7q了(jin)Q非常幸q的Q在q?q中Q除?q的“半工半诠Z和1q的.NET目Q篏U有5q都是从事的JavaZ的应用开发,应该_(d)Java伴随我走q了(jin)从入行到站稳脚跟最关键的几q。从某种意义上讲Q我应该感谢Java?br /><br />然而,随着旉的推U,接触到的不同的东西越来越多,自己对不同问题的看法和解决问题的思\来成熟,Java虽然是全能型的语aQ也变得来无法满x(chng)常工作和׃的需要,在一些特定的场合Q也发别扭Q有时我甚至?x)怀念学生时代的Pascal/Delphi和后来的C/C++。回q头ȝ自己Q从刚入行时的Java fanboiQ到现在q样一个pragmatist和purist的结合体Q是多么有趣的{变?br /><br />在过ȝ2q多Q除?jin)Java?NETQ陆陆箋(hu)l接触到q有q简单用经历的~程语言Q有bash、PL/SQL、JavaScript、PHP、Perl、Ruby/JRuby、Scala、Python/Jython、Groovy{等Q不q都没有pȝ的学?fn)过Q基本就是拿来主义,什么好用用什么,解决手里的问题(sh)ؓ(f)丅R?br /><br />也许是工作性质的原因,日常要处理的非技术性Q务越来越多,留给具体~程的时间现在一天比一天少Q编E带来的乐趣和解x(chng)术问题带来的快感Q就昑־十分珍贵。所以我下定军_(j)一定要pȝ的学?~2U和Java/.NET不同的编E语a。一开始这个选择q不Ҏ(gu)Q我曄q?a target="_blank" title="http://twitter.com/laogao/statuses/853718837" >半调侃式的和一个朋友讲Q“Python, Ruby, Scala, Groovy, 一个都不能?/a>Q经q一D|间的权衡之后Q还是比较自然的作出?jin)最后的选择QPython和Groovy?br /><br />Pythonq个选择其实q不难,留意Pythonq门语言Q其实说h也有差不?q了(jin)Q它完全W合“和Java/.NET不同的编E语a”这个条Ӟ而且应用面很q,也十分成熟,功能也非常强大,加上大量现成的类库,能够胜Q很多不同cd的编EQ务。基本上q是一个不用Q何思想斗争的选择?br /><br />Groovyq个选择相对没有那么直接Q至在我真正用Groovy上手做一些东西之前,对它q没有特别的感觉Q甚臌疑它存在的h(hun)|因ؓ(f)有Jython和JRuby的选择Qؓ(f)什么一定要Groovy呢?到最q开始接触GroovyQ才逐渐?jin)解到它的出w(Groovy的作者受到Python的启发,不过后来Groovy发展的越来越接近RubyQ,和它在“兼容”Java代码的前提下为Java语言带来的巨大的表达力提升。对于有Java基础的h而言QGroovy十分Ҏ(gu)上手Q而且可以帮助我们化很多繁杂的dQ比如自动构建和自动化测试,而这正是我目前需要处理的?br /><br />最后简单说说其他几个落选的原因Q除?jin)时间有限之外?j)Q?br />bash - 目前掌握的基本够用,发现不够Ӟ完全可以用Python代替?br />PL/SQL - 基本很少使用?jin),偶尔需要维护,今后深入用的Z(x)也不多?br />JavaScript - 对“网”版的编E语a可能有天生的偏见Q尤其是作ؓ(f)Java fanboiQ当然对它“盗用”Javaq个名字是有意见的?br />PHP - 用的Z(x)很少Q而且q于quick&dirtyQ不是我喜欢的风根{?br />Perl - 虽然功能强大Q但是感觉语法有些terseQ不是很适应Q能处理的Q务,基本上Python也可以?br />Ruby - 语法和设计理念还是有一些认同,但是对Unicode的支持和部v环境的支持都q(sh)是很让h信服Q另外,拿孟岩的话说QRuby是一门魔q语aQ我不喜Ƣ过于魔qȝ东西Q而更?fn)惯具体直接的代码?br />Scala - 也是一门和Javaq_关系密切的语aQ不q有些“学院派”,函数式编E固然是亮点Q但短期内看不到太多的学?fn)h(hun)倹{?br /><br />所以,lg所qͼ最后再点一下题Q?8q秋季的学习(fn)计划是:(x)pȝ学习(fn)Python和Groovy?br /><br /><br /><img src ="http://www.aygfsteel.com/sean/aggbug/223139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2008-08-20 00:33 <a href="http://www.aygfsteel.com/sean/archive/2008/08/20/223139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Djangol于?.0?/title><link>http://www.aygfsteel.com/sean/archive/2008/06/17/208682.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Tue, 17 Jun 2008 10:14:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2008/06/17/208682.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/208682.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2008/06/17/208682.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/208682.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/208682.html</trackback:ping><description><![CDATA[ <br />或许多少和Python/Djangoq个C֌的h们比较内敛、慢条斯理、喜Ƣ埋头做事有养IDjango一直以来版本号更新都很保守Q到现在q是0.96。什么时候才?.0q个问题被h提v无数ơ,q让很多对它有兴的朋友处于长期的观望之中。眼睁睁看着隔壁Rails如火如荼的都出到?.1.0QDjangol于要有动作?jin)?x)<br /><br /><a target="_blank" title="http://code.djangoproject.com/wiki/VersionOneRoadmap" >http://code.djangoproject.com/wiki/VersionOneRoadmap</a><br /><br />Ҏ(gu)q䆾U\图,今年7月,Django?x)推?.0的第一个alpha版本Q接下来?月会(x)有两ơbeta和一ơrcQ如果一切顺利的话,让许多h望眼Ʋ穿的Django 1.0有望于今年9月正式同大家见面?br /><br /><br /><img src ="http://www.aygfsteel.com/sean/aggbug/208682.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2008-06-17 18:14 <a href="http://www.aygfsteel.com/sean/archive/2008/06/17/208682.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[新闻] JRuby 1.1.2 发布http://www.aygfsteel.com/sean/archive/2008/05/28/203452.htmllaogaolaogaoWed, 28 May 2008 04:08:00 GMThttp://www.aygfsteel.com/sean/archive/2008/05/28/203452.htmlhttp://www.aygfsteel.com/sean/comments/203452.htmlhttp://www.aygfsteel.com/sean/archive/2008/05/28/203452.html#Feedback1http://www.aygfsteel.com/sean/comments/commentRss/203452.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/203452.htmlJVM下的Ruby语言实现JRuby发布1.1版的W二个升U版1.1.2Q这个版本最主要x(chng)的仍然是性能Q值得一提的包括Q?br /> 1- 启动旉大大~短?br /> 2- YAML标记解析速度提高100x以上?br /> 3- Ҏ(gu)调用在性能、线E和栈深度等斚w的增强?br />4- 其他bug?br />
主页: http://jruby.codehaus.org/
下蝲: http://dist.codehaus.org/jruby/




laogao 2008-05-28 12:08 发表评论
]]>
[新闻] JRuby 1.1发布http://www.aygfsteel.com/sean/archive/2008/04/05/190985.htmllaogaolaogaoSat, 05 Apr 2008 15:01:00 GMThttp://www.aygfsteel.com/sean/archive/2008/04/05/190985.htmlhttp://www.aygfsteel.com/sean/comments/190985.htmlhttp://www.aygfsteel.com/sean/archive/2008/04/05/190985.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/190985.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/190985.htmlJVM下的Ruby语言实现JRuby正式发布1.1版,q个版本最主要x(chng)的是性能Q除此之外,值得一提的包括Q?br />1- 支持Ruby代码~译成Java Bytecode?br />2- Onigurumaq个Ruby 1.9标配的正则库UL到Java?br />3- 重构q的IO实现?br />4- 更低的内存消耗?br />5- 修复大量其他兼容性问题?br />
主页: http://jruby.codehaus.org/
下蝲: http://dist.codehaus.org/jruby/




laogao 2008-04-05 23:01 发表评论
]]>
[Tips] ULOracle数据库到PostgreSQL的要?/title><link>http://www.aygfsteel.com/sean/archive/2008/03/11/185510.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Tue, 11 Mar 2008 15:04:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2008/03/11/185510.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/185510.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2008/03/11/185510.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/185510.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/185510.html</trackback:ping><description><![CDATA[ <br />最q尝试把一个Oracle数据库,q同构徏在这个数据库上的Java应用UL到PostgreSQL环境。在ULq程中,ȝ?jin)一些要点,一斚w作ؓ(f)W记备忘Q一斚w也给有类gQ务需要处理而又无从下手的朋友作为参考?br /><br />1- 首先是准备PostgreSQL环境。有条g的话Q最好是找一台空闲的PCZ为测试服务器Q安装Linux或BSDQ然后从源码~译最新的PostgreSQL 8.3.0。编译时Q通过configure指定--with-perl?-with-python以支持PL/Perl和PL/Python。因为绝大多数Linux发行版都已自带Perl和PythonQ不必额外安装?br /><br />2- 如果是Windows环境Q又需要Perl和PythonQ则必须额外安装QPython的话Q可以方便的扑ֈ2.5 for Windows的安装包QPerl的话Q推荐ActivePerlQ相寚w?ch)一点,Z(jin)后面用到的一些便利的功能利加蝲QPerl版本量?.8.8?br /><br />3- 创徏数据库和用户。通过initdb初始化数据目录,配置postgresql.conf指定LIP、端口等{信息,配置pg_hba.conf指定讉K权限Q通过pg_ctl -D <数据目录> -l <日志文g> start启动postmasterQ然后createdb、createuser创徏数据库和用户。数据库建好之后Q就可以createlang -d <数据库名> [plperl|plperlu|plpython|plpythonu]开启PL/Perl和PL/Python。具体命令行参数可通过各命令加--help查看?br /><br />4- 安装PostgreSQL客户端pgAdminIIIQ最新版?.8.2Q有条g的话Q也可以下蝲源码自己~译?br /><br />5- 安装Oracle客户端,需要在PostgreSQL同一台机器,以便Perl用于q接数据库的DBI和Oracle驱动DBD::Oracle模块利安装。如果是Windows上的ActivePerlQ则可以通过ppm install DBD-OracleQ如果是Linux/BSDQ则可以通过CPAN来安装,如perl -MCPAN -e shellq入CPAN ShellQ通过install <模块?gt;或force install <模块?gt;安装DBI和DBD::Oracle?br /><br />6- 数据库的ULQ可以选择ora2pg来帮忙,目前的版本是4.7。ora2pg是一个用于读取Oracle数据库schema、数据,q生成PostgreSQL脚本或直接导入PostgreSQL数据库的Perl工具。用法很单,是通过.conf文g指定数据库连接信息包括NLS_LANG、需要导出导入的schema、table、view、data{等Q然后执行一个pl脚本。这是目前相Ҏ(gu)较成熟的一个方案,但是遇到schema复杂、约束较强的数据库,需要手工处理的地方q是不少。徏议不要直接写入PostgreSQLQ而是生成SQL脚本Q验证无误后再执行。ora2pg默认?x)把Oracle中名U的大写转换成小写,因ؓ(f)PostgreSQL在解析SQLӞ除非""括v来,默认都是转成写。schema、table、view、sequence、data{等Q基本用ora2pgQ加上一些手工调整即可搞定。至于function、stored procedure{,q是手工UdQ偷不得懒。除?jin)ora2pgQ其实也可以配置DBI-LinkQ将Oracle数据库挂到PostgreSQL数据库作Zl独立的"schema"Q然后用create table xxx as select ... from ...q样的语法来倒表和数据。PostgreSQL的contrib包也附带有一个dblinkQ不q是q接其他PostgreSQL数据库的Q如果需要连接非PostgreSQLQ? q是考虑DBI-LinkQQ何可以通过Perl的DBI接口讉K的数据库Q都能linkqPostgreSQL?br /><br />7- 接下来就是Java应用本n?jin),我这ơ移的这个应用是Spring+iBatis架构的,很多SQL语句都是明文Q好在DAO层的基础部分(CRUD)的SQLMap是工兯动生成,且都是符合ANSI SQL92标准的,不需要修改即可用。其余的高查询SQLQ需要调整的地方不少Q一些常见的修改列D如下Q?br /><br />i. SELECT出来的columnQ包括子查询Q,如果有别名,必须加ASQ比?select null as some_column from some_table;<br />ii. PostgreSQL没有dual表,cMselect 0 from dual的语句,写成select 0卛_;<br />iii. DECODE函数需要重构成(case when some_column = 'some_value' then 'some_other_value' when ... then ... else 'some_default_value' end ) as some_column;<br />iv. NVL()函数QPostgreSQL中相对应的是coalesce()Q其实几乎所有主DBMS都支持coalesceQ包括OracleQ这才是标准写法;<br />v. 比较日期Q在PostgreSQL中,使用date_trunc('day', SOME_DATE) = date_trunc('day', #enteredDate#)q样的写法,其中'day'位置可选字D包括有year、month、week、hour、minute、second{等;<br />vi. SYSDATEQ对应到PostgreSQL是current_timestampQ可以根据需要用current_date;<br />vii. ROWNUMQ通常我们用ROWNUM都是Z(jin)限制查询出来的记录数QPostgreSQL没有q个关键字,需要改成在SELECT语句最后添?LIMIT语句Q如LIMIT 100;<br />viii. (+)q样的外q接写法需要调整ؓ(f)SQL标准?table1 [LEFT|RIGHT|FULL] OUTER JOIN table2 ON (...);<br />ix. CONNECT BY ... START WITH ... 递归查询可以参?http: //www.postgresql.org/docs/8.3/static/tablefunc.html 的connectby()函数.<br /><br />最后再多提一点,PostgreSQL自带的过E语a是PL/pgSQLQ在PostgreSQL上写functionQ除?jin)用plpqsqlQ还支持sql、plperl(u)、plpython(u){等。如果你对SQL天生q敏Q看cMPL/pgSQL的代码都很吃力,别说是写?jin),你完全可以用你喜Ƣ的语言来表辑և数和存储q程的逻辑。有?jin)PL/PythonQ你q怕什么呢Q你几乎能做M事?br /><br />[更新 20080313] 把JDBC驱动的部分漏掉了(jin)Q移植Java应用Ӟ除了(jin)改SQLQ还需要拿PostgreSQL的JDBC驱动攑ֈclasspath下面Q如WEB-INF/libQ然后修Ҏ(gu)据库q接URLQ改成jdbc:postgresql://<ip>:<port>/<dbname>卛_?br /><br />[更新 20080323] ULschema和数据时Q比ora2pg更方便的一U方式是利用EnterpriseDB的Migration ToolQ将Oracle的JDBC驱动ojdbc14.jar拯到EnterpriseDB安装路径下的jre/lib/ext下后Q启动Developer Studio卛_建立Oracleq接Q选中schema后,可以通过右键Online Migrationschema、数据、函数包{等一ơ性通通导入EnterpriseDB。如果要l箋(hu)往(xin)"U?PostgreSQLU,从EDB做backupQ然后到PostgreSQL下做restoreQ这样会(x)丢掉函数包,因ؓ(f)毕竟EDB在PostgreSQL基础上做?jin)相当改造以和Oracle兼容Q不q函数包之类q是手工UL较稳妥?br /><br /><br /><img src ="http://www.aygfsteel.com/sean/aggbug/185510.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2008-03-11 23:04 <a href="http://www.aygfsteel.com/sean/archive/2008/03/11/185510.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[新闻] Sun Hires Python Expertshttp://www.aygfsteel.com/sean/archive/2008/03/05/183819.htmllaogaolaogaoTue, 04 Mar 2008 16:07:00 GMThttp://www.aygfsteel.com/sean/archive/2008/03/05/183819.htmlhttp://www.aygfsteel.com/sean/comments/183819.htmlhttp://www.aygfsteel.com/sean/archive/2008/03/05/183819.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/183819.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/183819.html在JRuby得到Sun的认可ƈ成功发布1.0Q已l向1.1q进之时Q比Ruby应用更广、更早出现JVMq行版本的Python也终于得C(jin)Sun的重视:(x)

http://www.eweek.com/c/a/Application-Development/Sun-Hires-Python-Experts/

管Sun官方的说法是他们?x)更多的应用和扶持native版的PythonQ相信一直饱受冷落的JythonQ也多少?x)从中受益吧?br />



laogao 2008-03-05 00:07 发表评论
]]>
[新闻] Grails正式发布1.0?/title><link>http://www.aygfsteel.com/sean/archive/2008/02/07/179425.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Thu, 07 Feb 2008 02:47:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2008/02/07/179425.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/179425.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2008/02/07/179425.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/179425.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/179425.html</trackback:ping><description><![CDATA[ <br />春节期间真是好事不断啊,l?a target="_blank" title="http://www.aygfsteel.com/sean/archive/2008/02/07/179424.html" href="/sean/archive/2008/02/07/179424.html">PostgreSQL 8.3正式release</a>后,Grails也如U发?.0版。作为受到Ruby on Rails启发开动的"Groovy版Rails"目Q它在设计哲学上和RailsQ包括JRuby版的RailsQ有着很大的不同,Rails是从头开始用Ruby完整实现从表现层到ORM所有功能,而Grails则是利用JavaC֌现有的成熟开源框Ӟ如Spring、Hibernate{,在此基础上整合出一套完整的Web应用框架Q有点类似Pylons和Django的区别?br /><br />?a target="_blank" title="http://www.aygfsteel.com/sean/archive/2008/01/27/178036.html" href="/sean/archive/2008/01/27/178036.html">之前一随W?/a>也提到过Q和其它在JVM中运行的动态语a如Jython、JRuby不同的是QGroovy对于有Java基础的h们来_(d)学习(fn)曲线几乎是^的,上手很快Q如果你同时也熟(zhn)Spring和Hibernate{,那么Grails更是不二之选?br /><br />官网: <a target="_blank" title="http://grails.codehaus.org/" >http://grails.codehaus.org/</a><br />Release Notes: <a target="_blank" title="http://grails.org/1.0+Release+Notes" >http://grails.org/1.0+Release+Notes</a><br />下蝲: <a target="_blank" title="http://grails.codehaus.org/Download" >http://grails.codehaus.org/Download</a><br /><br /><br /><img src ="http://www.aygfsteel.com/sean/aggbug/179425.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2008-02-07 10:47 <a href="http://www.aygfsteel.com/sean/archive/2008/02/07/179425.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[新闻] 开源数据库P(yng)ostgreSQL正式发布8.3?/title><link>http://www.aygfsteel.com/sean/archive/2008/02/07/179424.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Thu, 07 Feb 2008 02:04:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2008/02/07/179424.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/179424.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2008/02/07/179424.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/179424.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/179424.html</trackback:ping><description><![CDATA[ <br />l过1?日和1?8日两轮RC后,PostgreSQL 8.3l于在本月初正式发布?jin)。该版本有很多功能和性能上的重大提升Q包括全文搜索、新的数据类?XML、ENUM、UUID{?、ƈ发autovacuum、异步提交等{,以及(qing)对Windowsq_更好的支持,如SSPI和VC++{?br /><br />官方声明: <a target="_blank" title="http://www.postgresql.org/about/news.918" >http://www.postgresql.org/about/news.918</a><br />Release Notes: <a target="_blank" title="http://www.postgresql.org/docs/8.3/static/release-8-3.html" >http://www.postgresql.org/docs/8.3/static/release-8-3.html</a><br />各版本功能对? <a target="_blank" title="http://www.postgresql.org/about/featurematrix" >http://www.postgresql.org/about/featurematrix</a><br />下蝲: <a target="_blank" title="http://www.postgresql.org/ftp/" >http://www.postgresql.org/ftp/</a><br /><br /><br /><img src ="http://www.aygfsteel.com/sean/aggbug/179424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2008-02-07 10:04 <a href="http://www.aygfsteel.com/sean/archive/2008/02/07/179424.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[链接] ?x)JavaQ学GroovyQ这里有很好的介绍/演示 http://www.aygfsteel.com/sean/archive/2008/01/27/178036.htmllaogaolaogaoSun, 27 Jan 2008 09:14:00 GMThttp://www.aygfsteel.com/sean/archive/2008/01/27/178036.htmlhttp://www.aygfsteel.com/sean/comments/178036.htmlhttp://www.aygfsteel.com/sean/archive/2008/01/27/178036.html#Feedback2http://www.aygfsteel.com/sean/comments/commentRss/178036.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/178036.html如果你有一定的Java基础Q想快速的尝动态语a的味道,Groovy是个自然的过渡选择。今天无意中看到一介lGroovy的文章,很短Q也很有,从一个典型的JavaE序开始,一步一?Groovy?Q最l改造成一个完整的GroovyE序Q?br />
http://java.dzone.com/news/java-groovy-few-easy-steps


如果你对当下动态语a的现状有所?jin)解Q那你多半已l知道能在JVM中运行的动态语aQ远不止Groovy一U,那么什么理׃(x)让你选择Groovy而非Jython、JRuby或者其他类似的语言呢?W者认Z要还是编码习(fn)惯和风格QGroovy是这些语a中最接近Java的。Jython和JRuby都是从其他成功的动态语a"UL"q来Q带有明昄Python、Ruby语法特征和习(fn)惯。选择Jython或者JRuby的朋友,我想大都是原本就有Python或者Ruby的基Q舍不得Python和Ruby的一些很方便的语法和~码风格/?fn)?哲学Q或者干脆就是ؓ(f)?jin)将Python和Ruby世界的一些框架引入到Java中,或者说是让Python/Ruby应用能够更好的利用Javaq_已有的资源。如果你在动态语a上没有这斚w的需求,只是Z(jin)让你的Java应用更动态,选择Jython或者JRuby只能是凭I增加学?fn)难度。要知道QPython和Ruby都是很有特点、很有个性的语言Q其实Java又何不是)(j)Q要从Java的思维和哲学,转向Python/Ruby的思维和哲学,q不是那么容易做到和做好的?br />



laogao 2008-01-27 17:14 发表评论
]]>
Django: Up and Runninghttp://www.aygfsteel.com/sean/archive/2007/11/28/163589.htmllaogaolaogaoTue, 27 Nov 2007 16:57:00 GMThttp://www.aygfsteel.com/sean/archive/2007/11/28/163589.htmlhttp://www.aygfsteel.com/sean/comments/163589.htmlhttp://www.aygfsteel.com/sean/archive/2007/11/28/163589.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/163589.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/163589.html到现在Q已l有近半年没有写过技术文章了(jin)Q手痒痒Q于是拿Django来说事,希望最l的产出能够做成一个简短易懂的Django快速v步,让初ơ接触Django的朋友能够在最短的旉内了(jin)解Django的基本概念和l构?br />
Django是用Python实现的一个基于MVC的web应用框架Q类似Ruby世界的Ruby on Rails。如果你是通过Google搜到q篇文章Q那么说明你已经对Django有所耳闻Qƈ且愿意了(jin)解更多Django相关的信息。我在这里就不多? 话Ruby vs Python或者Rails vs DjangoQ直奔主题?br />
在写q篇文章Ӟ最新的CPython版本?.5.1QDjango版本?.96Q如无特别说明,本文所有介l和CZ均以此环境ؓ(f)准?br />
0- 在开始之前,首先当然是安装一个基本能用的开发环境?br />
如果你的操作pȝ是Linux或者其他类UnixpȝQ很可能已经预装?jin)PythonQ可以在命o(h)行执行python -V查看Python版本。如果你是Windows操作pȝQ或者想试不同版本的PythonQ那么可以到http://www.python.org/下蝲相应的安装包q行安装?br />
有了(jin)Python以后Q到http://www.djangoproject.com/下蝲DjangoQ解压以后,cd到解压出来的目录Q执行python setup.py install?br />
Z(jin)能够做出一个基本的多层web应用Q还需要安装一个数据库Q如果没有特别喜好和偏向Q推荐PostgreSQLQ可以在http://www.postgresql.org/扑ֈ合适的版本下蝲和安装?br />
我们q缺一个数据库驱动Q在http://www.initd.org/pub/software/psycopg/可以扑ֈ用于q接PostgreSQL的psycopg2Q安装方法类似Django?br />
1- django-admin.py startproject

所有环境OK以后Q我们开始动手把玩DjangoQ首先找一个干净的目录,执行
$ python django-admin.py startproject hello

上面q行命o(h)?x)新Z个hello子目录,包含以下文gQ?br /> __init.py__: 表示该目录存放PythonE序
manage.py: 提供Django目相关的管理操?br /> settings.py: 相当于该Django目的全局讄
urls.py: 用于配置URL映射Q基本上是通过正则表达式指定不同URLq应的viewҎ(gu)相应

2- manage.py runserver

x(chng)我们已经搭v?jin)一个基本的Django目框架Q执?br /> $ python manage.py runserver
命o(h)行会(x)提示?000端口q行一个开发用的web serverQ{到浏览器?a href="http://localhost:8000/" target="_blank">http://localhost:8000/卛_看到It worked!的提CZ息。你也可以指定端口号Q方法是python manage.py runserver XXXX?br />
3- settings.py

接下来我们做一个完整的从model/数据库到view/template的例子。修改settings.py:
DATABASE_ENGINE (tng)= (tng)'postgresql_psycopg2'
DATABASE_NAME (tng)
= (tng)'hello' (tng)# (tng)Your (tng)db (tng)name
DATABASE_USER (tng)= (tng)'postgres' (tng)# (tng)Your (tng)db (tng)user
DATABASE_PASSWORD (tng)= (tng)'********' (tng)# (tng)Your (tng)db (tng)password
DATABASE_HOST (tng)= (tng)''
DATABASE_PORT (tng)
= (tng)''

INSTALLED_APPS (tng)
= (tng)(
 (tng) (tng) (tng) (tng)
'django.contrib.auth',
 (tng) (tng) (tng) (tng)
'django.contrib.contenttypes',
 (tng) (tng) (tng) (tng)
'django.contrib.sessions',
 (tng) (tng) (tng) (tng)
'django.contrib.sites',
 (tng) (tng) (tng) (tng)
'hello', (tng)# (tng)Our (tng)new (tng)project
) (tng)

4- models.py

新徏models.py:
from (tng)datetime (tng)import (tng)datetime
from (tng)django.db (tng)import (tng)models

class (tng)Book(models.Model):
 (tng) (tng) (tng) (tng)isbn (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
= (tng)models.SlugField(maxlength=20)
 (tng) (tng) (tng) (tng)title (tng) (tng) (tng) (tng) (tng) (tng) (tng)
= (tng)models.CharField(maxlength=200)
 (tng) (tng) (tng) (tng)author (tng) (tng) (tng) (tng) (tng) (tng)
= (tng)models.CharField(maxlength=200)
 (tng) (tng) (tng) (tng)description (tng)
= (tng)models.TextField(blank=True,null=True)
 (tng) (tng) (tng) (tng)published (tng) (tng) (tng)
= (tng)models.DateTimeField(default=datetime.now)
q里我们从django.db.models.Modell承我们的modelcBookQ同时还用到?jin)models中现成的字段c,? SlugField、CharField、TextField、DateTimeField{。大家比较陌生的恐怕是SlugFieldQ这个基本上cM CharFieldQ不q增加了(jin)其内定w要符合URL要求的限制条件?br />
执行下面的命令测试数据库脚本的生?
$ python manage.py sql hello
应该看到如下输出l果:
BEGIN;
CREATE TABLE "hello_book" (
"id" serial NOT NULL PRIMARY KEY,
"isbn" varchar(20) NOT NULL,
"title" varchar(200) NOT NULL,
"author" varchar(200) NOT NULL,
"description" text NULL,
"published" timestamp with time zone NOT NULL
);
COMMIT;

认无误后可以通过下面的命令提交到数据?
$ python manage.py syncdb
光?x)要求我们创Z个管理员账号Q如果暂时不打算做admin面Q可以蟩q?br />
5- views.py

model有了(jin)之后Q接下来我们可以开始画视图?jin)。由于篇q和旉有限Q我仅简单介l一下Django的templateQ然后实C个最基本的图书清单页面?br />
首先定义图书清单的URLQ在urls.py?
from (tng)django.conf.urls.defaults (tng)import (tng)*

urlpatterns (tng)
= (tng)patterns('hello.views',
 (tng) (tng) (tng) (tng)(r
'^hello/books/$', (tng)'book_list'),
)
含义为hello/books/q个URI资源对应的相应viewҎ(gu)为hello.views.book_list?br />
新徏templates目录Q然后新建books.html:
<html (tng) (tng)xmlns="http://www.w3.org/1999/xhtml" (tng)lang="zh-cn" (tng)xml:lang="zh-cn">
<head>
<title>{{ (tng)title|escape (tng)}}</title>
</head>
<body>
<h2>{{ (tng)title (tng)}}</h2>
<table (tng)border="1">
 (tng) (tng)
<tr><th>ISBN</th><th>书名</th><th>作?/span></th><th>出版日期</th></tr>
 (tng) (tng){% (tng)for (tng)book (tng)in (tng)books (tng)%}
 (tng) (tng)
<tr>
 (tng) (tng) (tng) (tng)
<td>{{ (tng)book.isbn (tng)}}</td>
 (tng) (tng) (tng) (tng)
<td>{{ (tng)book.title (tng)}}</td>
 (tng) (tng) (tng) (tng)
<td>{{ (tng)book.author (tng)}}</td>
 (tng) (tng) (tng) (tng)
<td>{{ (tng)book.published (tng)}}</td>
 (tng) (tng)
</tr>
 (tng) (tng){% (tng)endfor (tng)%}
</table>
</body>
</html>
Django模板的语法是{{}}表示引用Q{%%}表示代码Q用v来也很直观,甚至支持UNIX风格的filterQ如q里的{{ title|escape }}?br />
新徏views.py:
from (tng)hello.models (tng)import (tng)*
from (tng)django.shortcuts (tng)import (tng)render_to_response

def (tng)book_list(request):
 (tng) (tng) (tng) (tng)title (tng)
= (tng)'Book (tng)List'
 (tng) (tng) (tng) (tng)books (tng)
= (tng)Book.objects.all()
 (tng) (tng) (tng) (tng)
return (tng)render_to_response('books.html', (tng){'title' (tng): (tng)title, (tng)'books' (tng): (tng)books})
最l页面上的内容,通过title和books两个参数传递给tempate(books.html)处理?br />
修改settings.py:
TEMPLATE_DIRS (tng)= (tng)(
 (tng) (tng) (tng) (tng)
'/opt/PROJECTS/Django/hello/templates/',
)
指定templates目录位置Q注意需要用绝对\径和'/'Q无论是Unixq是Windowspȝ?br />
我们手工造一些数据之后,可以通过http://localhost:8000/hello/books/讉K我们用Django实现的这个简单页面了(jin)?br />
6- What's next

通过上面的简单介l,怿哪怕是初次接触Django的朋友,也能够对Django有一个初步的认识。其实Djangoq不隑֭Qƈ且随着学习(fn)的深入,你一定能发现更多的惊喜,不论是来自Django本nQ还是Python?qing)其庞大的第三方cd?br />
如果有时_(d)试一下Django的admin pagesQ即为我们的model提供自动化、网化的增删改查操作。启用方法如下:(x)

修改models.py (增加class Admin):
from (tng)datetime (tng)import (tng)datetime
from (tng)django.db (tng)import (tng)models

class (tng)Book(models.Model):
 (tng) (tng) (tng) (tng)isbn (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
= (tng)models.SlugField(maxlength=20)
 (tng) (tng) (tng) (tng)title (tng) (tng) (tng) (tng) (tng) (tng) (tng)
= (tng)models.CharField(maxlength=200)
 (tng) (tng) (tng) (tng)author (tng) (tng) (tng) (tng) (tng) (tng)
= (tng)models.CharField(maxlength=200)
 (tng) (tng) (tng) (tng)description (tng)
= (tng)models.TextField(blank=True,null=True)
 (tng) (tng) (tng) (tng)published (tng) (tng) (tng)
= (tng)models.DateTimeField(default=datetime.now)
 (tng) (tng) (tng) (tng)
class (tng)Admin:
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
pass

修改settings.py和urls.pyQ加入admin支持:
[settings.py]
INSTALLED_APPS (tng)= (tng)(
 (tng) (tng) (tng) (tng)
'django.contrib.auth',
 (tng) (tng) (tng) (tng)
'django.contrib.contenttypes',
 (tng) (tng) (tng) (tng)
'django.contrib.sessions',
 (tng) (tng) (tng) (tng)
'django.contrib.sites',
 (tng) (tng) (tng) (tng)
'django.contrib.admin',
 (tng) (tng) (tng) (tng)
'hello',
)
[urls.py]
urlpatterns (tng)= (tng)patterns('hello.views',
 (tng) (tng) (tng) (tng)(r
'^hello/books/$', (tng)'book_list'),
 (tng) (tng) (tng) (tng)(r
'^hello/admin/', (tng)include('django.contrib.admin.urls')),
)

Note:
# Z(jin)成功q行admin pagesQ需要首先执行python manage.py syncdb admin以创建django_admin_log表?br /> # 如果前面跌?jin)创建管理员步骤Q简单的Ҏ(gu)可以删掉auth_user表,然后python manage.py syncdb重徏?br />
按照我们urls.py的配|,admin pages可以通过http://localhost:8000/hello/admin/讉K。Enjoy!




laogao 2007-11-28 00:57 发表评论
]]>
[Tips] When ANT is not enough, JRuby to the rescue!http://www.aygfsteel.com/sean/archive/2007/06/18/124859.htmllaogaolaogaoSun, 17 Jun 2007 16:39:00 GMThttp://www.aygfsteel.com/sean/archive/2007/06/18/124859.htmlhttp://www.aygfsteel.com/sean/comments/124859.htmlhttp://www.aygfsteel.com/sean/archive/2007/06/18/124859.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/124859.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/124859.html 随着目来大Q你的ANT脚本变得来臃肿,来依赖antcontrib来实现构建逻辑Q不x(chng)弃对构徏q程和出做_的控Ӟ恨不得自己写ANT TaskQ?br />
{一{,在你考虑转向Maven或者真正卷赯子开始研IANT Task的API之前Q先听我向你推荐Ruby/JRuby。相信我Q也许这才是你真正需要的?br />
在我看来构徏脚本最主要的要求是表达能力和控制能力,表达能力是我们应该能够很方便的告诉它我们要它做什么,而控制能力是我们告诉它如何去做,除了(jin)必要? 构徏命o(h)的参数、依赖关pM外,它应该能够理解我们其他一些特D要求。在目相对单时QANT的XML格式?脚本语言"能够比较好的表达构徏者的? 求,臛_比纯Java的方式更加简单清晎ͼ于是几乎从它诞生之日成为Java领域当仁不让的头h建工兗但是ANT也有它不够用的时候,其在控制能 力上Qؓ(f)?jin)实现实际用中来复杂越来越_的对构徏q程和出的要求QANT的用者们开始对ANTq行扩展Q最具媄(jing)响力?非官?扩展可能是 antcontrib?jin),很多实际Java目的构建文件中我们都能够找到它的媄(jing)子。但是一堆taskdef?variable>之类的夹杂在ANT脚本里,怎么看怎么觉得别扭Q也严重影响构徏脚本的可L?br />
我发现我需要的是一个具有完整功能脚本语a来写我的构徏逻辑Q一斚w它要_单,我需要清晰的表达我的意图Q另一斚w当我需要的时候它要够强大来帮我实现_的控制。我自然而然惛_Ruby?br />
׃Ruby是一个功能完整的工具Q完全自己写Ruby脚本来调用Java自己的构建工具如javac、jar{等q不可能,但是既然已经有h做了(jin)? 子,我们拿来用就是了(jin)Q大不了(jin)自己再改装一下,也少C弯\。时下比较流行的解决Ҏ(gu)有Buildr、Raven、Rant和AntwrapQ它们各有特 点,大家可以Ҏ(gu)需要进行选择?br />
我最l选了(jin)其中最"轻量"的AntwrapQ原因嘛Q我不想学新的APIQ我已经熟?zhn)ANT常用的TaskQ而且我希望尽可能多的自己控制构徏的过E和? 出。Antwrap最能够满我的需要。而前不久JRuby刚刚发布?.0版,q样一来Ruby和Java的跨界引用变得更加容易,Ruby的实现自? 选择?jin)JRuby?br />
安装JRuby和Antwrap相当Ҏ(gu)Q只要把下蝲的jruby-bin-1.0.tar.gz/.zip解压到本圎ͼ保JAVA_HOME? CLASSPATH的配|,然后gem install Antwrap (选择Java? 卛_。ؓ(f)?jin)顺利加载AntwrapQ需要在CLASSPATH中包含ANT的ant.jar和ant-launcher.jar?当然Q如果想更加方便 的share你的成果Q可以把ant的文件拷贝到jruby目录下,在jruby的启动脚本加入必要的export/set命o(h)Q然后打包,q样别h只要 从你提供的zip包解压出来即可用?

Z(jin)l大家一个直观的感觉QD个简单的例子(貌似BlogJava没有提供对Ruby代码的默认支持,大家就看吧)Q?br />
 (tng)1 (tng)require (tng)'rubygems'
 (tng)2 (tng)gem (tng)'Antwrap'
 (tng)3 (tng)require (tng)'antwrap'
 (tng)4 (tng)
 (tng)5 (tng)@ant=AntProject.new(:name=>"SampleAntwrapBuild", (tng):basedir=>".")
 (tng)6 (tng)@cvsroot=":pserver:cvsuser:password@10.10.10.1/cvsrepo/SampleProduct"
 (tng)7 (tng)
 (tng)8 (tng)def (tng)cvscheckout
 (tng)9 (tng) (tng) (tng) (tng) (tng)@ant.cvs(
10 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):cvsroot=>"#{@cvsroot}", (tng)
11 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):command=>"checkout (tng)-A", (tng)
12 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):package=>".", (tng)
13 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):dest=>"cvsoriginal", (tng)
14 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):compressionlevel=>"9")
15 (tng)end
16 (tng)
17 (tng)def (tng)cvsupdate
18 (tng) (tng) (tng) (tng) (tng)@ant.cvs(
19 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):cvsroot=>"#{@cvsroot}", (tng)
20 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):command=>"update (tng)-A (tng)-d", (tng)
21 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):package=>".", (tng)
22 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):dest=>"cvsoriginal", (tng)
23 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):compressionlevel=>"9")
24 (tng)end
25 (tng)
26 (tng)def (tng)compile(project_name)
27 (tng) (tng) (tng) (tng) (tng)@ant.javac(
28 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):srcdir=>"cvsoriginal/#{project_name}/src", (tng)
29 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):destdir=>"cvsoriginal/#{project_name}", (tng)
30 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):target=>"1.5", (tng)
31 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):encoding=>"GBK")
32 (tng) (tng) (tng) (tng) (tng)@ant.copy( (tng) (tng) (tng) (tng):todir=>"cvsoriginal/#{project_name}") (tng)do
33 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)fileset(:dir=>"cvsoriginal/#{project_name}/src") (tng)do
34 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)exclude(:name=>"**/*.java")
35 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)end
36 (tng) (tng) (tng) (tng) (tng)end
37 (tng) (tng) (tng) (tng) (tng)@ant.jar(
38 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):destfile=>"build/#{project_name}.jar", (tng)
39 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):basedir=>"cvsoriginal/#{project_name}", (tng)
40 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):manifest=>"MANIFEST.MF") (tng)do
41 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)exclude(:name=>"src/**")
42 (tng) (tng) (tng) (tng) (tng)end
43 (tng)end
44 (tng)
45 (tng)# (tng)to (tng)actually (tng)call (tng)your (tng)target
46 (tng)if (tng)ARGV.empty?
47 (tng) (tng) (tng) (tng) (tng)puts (tng)"Usage: (tng)jruby (tng)#{$0} (tng)[target]"
48 (tng)else
49 (tng) (tng) (tng) (tng) (tng)eval (tng)ARGV[0]
50 (tng)end
51 (tng)

可以看到几乎都是我们熟?zhn)的ANT TaskQ只是更加紧凑更加灵z,一旦掌握了(jin)最最基本的Ruby语法Q用它写出功能强大的构徏脚本可以说是分分钟搞定?br />



laogao 2007-06-18 00:39 发表评论
]]>
[Tips] 在Linux环境下调整Eclipse中树(wi)状列?GtkTreeView)的显C密?/title><link>http://www.aygfsteel.com/sean/archive/2007/06/09/123109.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Sat, 09 Jun 2007 14:46:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2007/06/09/123109.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/123109.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2007/06/09/123109.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/123109.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/123109.html</trackback:ping><description><![CDATA[ <br /> 如果你在Windows和Linux两个q_下都使用qEclipseQ那么你一定注意到Windows下Eclipse目列表的显C比Linux? 紧凑许多。对于做开发的朋友来讲Q在屏幕上同时看到的信息L希望可能多Q尽可能全,在这一点上目前的GNOMEq不能让我们十分满意Q它的GTK+? 件本w和控g之间的间隙占掉了(jin)不少本来很有限的屏q空_(d)其当屏q分辨率不是特别高的时候?br /><br /> Linux版的Eclipse默认使用GTK+2.0的控Ӟ所以在默认的情况下Q会(x)和其他GTK应用E序Q如OpenOffice.orgQ一L(fng)Z U不够密实的感觉。当?dng)q和GNOME的设计哲学不无关p,不过q不是本文主旨,׃深入讨论?jin),q入正题讲讲如何调整Eclipse?wi)状列表的显C密 度?br /><br /> ZGTK+2.0的程序在启动时会(x)到用L(fng)home目录找GTK+2.0的配|文Ӟ即~/.gtkrc-2.0QUbuntu下默认没有这个文Ӟ需要我们自己创建。打开你习(fn)惯的~辑器,加入如下代码Q?br /><br /> style "eclipse" {<br />  (tng) font_name="Sans 8"<br />  (tng) GtkTreeView::vertical-separator=0<br />  (tng) GtkTreeView::horizontal-separator=0<br /> }<br /> class "GtkTreeView" style "eclipse"<br /><br /> 重启Eclipse应该p看到效果?jin)。如果你惛_得更dQ对所有常用的GTK+2.0控g都开刀的话Q可以这样写Q?br /><br /> style "gtkcompact" {<br />  (tng) font_name="Sans 8"<br />  (tng) GtkButton::default_border={0,0,0,0}<br />  (tng) GtkButton::default_outside_border={0,0,0,0}<br />  (tng) GtkButtonBox::child_min_width=0<br />  (tng) GtkButtonBox::child_min_heigth=0<br />  (tng) GtkButtonBox::child_internal_pad_x=0<br />  (tng) GtkButtonBox::child_internal_pad_y=0<br />  (tng) GtkMenu::vertical-padding=1<br />  (tng) GtkMenuBar::internal_padding=0<br />  (tng) GtkMenuItem::horizontal_padding=4<br />  (tng) GtkOptionMenu::indicator_size=0<br />  (tng) GtkOptionMenu::indicator_spacing=0<br />  (tng) GtkPaned::handle_size=4<br />  (tng) GtkRange::trough_border=0<br />  (tng) GtkRange::stepper_spacing=0<br />  (tng) GtkScale::value_spacing=0<br />  (tng) GtkScrolledWindow::scrollbar_spacing=0<br />  (tng) GtkExpander::expander_size=10<br />  (tng) GtkExpander::expander_spacing=0<br />  (tng) GtkTreeView::vertical-separator=0<br />  (tng) GtkTreeView::horizontal-separator=0<br />  (tng) GtkTreeView::expander-size=8<br />  (tng) GtkTreeView::fixed-height-mode=TRUE<br />  (tng) GtkWidget::focus_padding=0<br /> }<br /> class "GtkWidget" style "gtkcompact"<br /><br /><br /><img src ="http://www.aygfsteel.com/sean/aggbug/123109.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2007-06-09 22:46 <a href="http://www.aygfsteel.com/sean/archive/2007/06/09/123109.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[阅读] JRuby, Groovy, and Swinghttp://www.aygfsteel.com/sean/archive/2007/02/21/100322.htmllaogaolaogaoWed, 21 Feb 2007 12:03:00 GMThttp://www.aygfsteel.com/sean/archive/2007/02/21/100322.htmlhttp://www.aygfsteel.com/sean/comments/100322.htmlhttp://www.aygfsteel.com/sean/archive/2007/02/21/100322.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/100322.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/100322.html 以下是一l相互关联、按旉先后排列?blog文章Q主要探讨是Swing存在的问题(sh)?qing)动态语a如JRuby/Groovy能否帮我们解决Swing的问题:(x)

JRuby can save Swing
JRuby cannot save Swing
Groovy can save Swing

挺有的Q推荐大家有I一诅R?br />



laogao 2007-02-21 20:03 发表评论
]]>
[阅读] What's XML really good for?http://www.aygfsteel.com/sean/archive/2007/02/21/100302.htmllaogaolaogaoWed, 21 Feb 2007 06:31:00 GMThttp://www.aygfsteel.com/sean/archive/2007/02/21/100302.htmlhttp://www.aygfsteel.com/sean/comments/100302.htmlhttp://www.aygfsteel.com/sean/archive/2007/02/21/100302.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/100302.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/100302.html http://www-128.ibm.com/developerworks/java/library/x-xjavaforum1.html

真正让XML发光的用途是什么?写配|文Ӟ数据交换Q数据存储?




laogao 2007-02-21 14:31 发表评论
]]>
[闲侃DRY] Don't Repeat Othershttp://www.aygfsteel.com/sean/archive/2007/01/30/96806.htmllaogaolaogaoTue, 30 Jan 2007 15:09:00 GMThttp://www.aygfsteel.com/sean/archive/2007/01/30/96806.htmlhttp://www.aygfsteel.com/sean/comments/96806.htmlhttp://www.aygfsteel.com/sean/archive/2007/01/30/96806.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/96806.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/96806.html http://www.alittlemadness.com/?p=76

今天dq篇文章Q原来和我想?/a>一?/a>Q不qDROq个提法的提法比我提炼的要更好,呵呵?br/>



laogao 2007-01-30 23:09 发表评论
]]>
[闲侃DRY] 自制框架 vs. 开源框?/title><link>http://www.aygfsteel.com/sean/archive/2007/01/26/96071.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Thu, 25 Jan 2007 16:32:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2007/01/26/96071.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/96071.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2007/01/26/96071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/96071.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/96071.html</trackback:ping><description><![CDATA[<br/> <p>接着<a href="http://www.aygfsteel.com/sean/archive/2007/01/22/95424.html" target="_blank">上一?/a>的思\聊。既然我们可以把开发者社看作一个整体,copy-paste别h的blog文章是在违背DRY的精,其实所?重造轮?道理也是一P既然别h都已l做?jin)相同的事情Qƈ且把它开源了(jin)Qƈ且你看了(jin)它的代码以后Q觉得做得不错,Z么还要自p?j)去实现同样的功能呢Q自己来实现能给你带来什么好处呢Q?/p> <p>我可以列举一些我认ؓ(f)可能?x)让我们选择自己来做的理?</p> <p> <ol> <li>我比其他人更?jin)解我们自己的需求?/li> <li>自己实现h更容易,代码量更,也更好用?/li> <li>我是做技术的Q能够DIYQ就DIYQ这h能体现我的h(hun)倹{?/li> </ol> </p> <p>q些理由有它的道理,但是我们有必要仔l掂量掂?</p> <p> <ol> <li>我比其他人更?jin)解我们自己的需求。这是Y件开发中很常见的一个误区,客户的需求难以把握,随着旉的推U,我们自己的技术层面的需求实际上也在不断变化Q开源的框架往(xin)往(xin)l历?jin)更多的考虑和验证,q且有一热?j)的l护者帮你做bug-fix和升U,甚至我们自己可以成热?j)h中的一员?/li> <li>自己实现h更容易,代码量更,也更好用。一开始确实是q样的,开源的框架Z(jin)满不同的需要,往(xin)往(xin)需要比我们自己写代码要更加复杂和冗余,但是自制框架意味着我们自己定义的接口规范,q个接口规范能不能够在整个项目周期保持稳定暂且不谈,q接口实现的再单,目中其他h也需要时间去理解和消化,然后C一个定义好的调用方式,今后新加入的工程师也需要学?fn)这个接口规范。开源框架则做得更好Q一斚w在这个项目中U篏和学?fn)到的知识,可以直接用在其他采用同一框架的项目中Q另一斚w新加入的人如果有q该开源框架的开发经验,上手旉可以~短?/li> <li>我是做技术的Q能够DIYQ就DIYQ这h能体现我的h(hun)倹{我必须承认Q我本h׃w经历过q样的情c(din)在卛_l束的这个项目中Q我甚至自己DIY?jin)一个简易的.NET报表引擎Qؓ(f)的是甩开Crystal Reports。一开始能够DIY报表引擎的想法让我兴奋得睡不着觉,最l前后花?天很满意的完成了(jin)设计和开发,q交付报表开发h员重L表。可是真正用?jin)一D|间之后,基本的需求满了(jin)Q基本的可扩展性也具备Q但是缺可视化设计器、更灉|的公式、更丰富的报表元素,基本上就定型?jin),没有人有旉和精力再ȝ护它?/li> </ol> </p> <p>在很多开发团队,大家l常在一赯论具体的技术和设计Q这很有必要Q有时也不可避免。但是也许Joel Spolsky说的对,软g设计很难Q但是比设计软g更难的,是同整个team一赯计Y件。做技术的Q对于自׃(jin)解、掌握、做q、尝试过的东西,对于自己熟?zhn)和信ȝ东西Q多多少有些偏袒,而对于新的、自׃?jin)解、不熟?zhn)的东西,则难免?j)存疑虑。这难怪很多设计讨Z(x)最l很难达成一致。这个时候,要么由技术上的最高权威直接拍板,定下来是什么就是什么,要么分歧双Ҏ(gu)多方各自陈述Q然后由目外部的实体进行独立仲裁?/p> <p>我看好开源框Ӟ其是那些经q考验q泛被采用的框架Q因为相比自制框Ӟ它们有着更大的优ѝ?/p> <br/> <img src ="http://www.aygfsteel.com/sean/aggbug/96071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2007-01-26 00:32 <a href="http://www.aygfsteel.com/sean/archive/2007/01/26/96071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Tips] &lt;abbr&gt;: 一个有的HTML标签http://www.aygfsteel.com/sean/archive/2007/01/25/96069.htmllaogaolaogaoThu, 25 Jan 2007 15:23:00 GMThttp://www.aygfsteel.com/sean/archive/2007/01/25/96069.htmlhttp://www.aygfsteel.com/sean/comments/96069.htmlhttp://www.aygfsteel.com/sean/archive/2007/01/25/96069.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/96069.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/96069.html

如果你用Firefox或Operaq且看到?a href="http://www.aygfsteel.com/sean/archive/2007/01/25/96060.html" target="_blank">上一随W?/a>?abbr title="What You See Is What You Get">WYSIWYGq一个词Q你可以看到它下面是用一串点标注出来的,如果你鼠标?zhn)停在上面Q会(x)有工hC?What You See Is What You Get"。HTML源代码是:

<abbr title="What You See Is What You Get">WYSIWYG</abbr>

可惜微Y的IEq不能正renderq个tagQ尽它是标?X)HTML的一部分?/p>


laogao 2007-01-25 23:23 发表评论
]]>
[链接] ASP.NET?六大|状"http://www.aygfsteel.com/sean/archive/2007/01/25/96060.htmllaogaolaogaoThu, 25 Jan 2007 15:01:00 GMThttp://www.aygfsteel.com/sean/archive/2007/01/25/96060.htmlhttp://www.aygfsteel.com/sean/comments/96060.htmlhttp://www.aygfsteel.com/sean/archive/2007/01/25/96060.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/96060.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/96060.html

http://www.garrettdimon.com/archives/aspnet-vs-front-end-architecture

该文作者细C(jin)他在使用ASP.NETq行开发的q程中遇到的6点不爽的地方Q主要都集中在前台架构上Q包括大量内联的风格标签、不同浏览器生成不同面代码、失败的标记设计、缺乏语意一致性、服务器端label和客L(fng)label的脱节、服务器端ID和客L(fng)IDp{等。尤其当你想使用标准的CSSQ构建数据结构和表现分离的清晰页面时QASP.NET的一些默认的内部处理可以让你对ASP.NETZq样做完全无语。比较有的是本文后面的回复Q其中有不少与楼d病相怜的|友Q还有来自微软员工的为ASP.NET辩护的声韟?/p>

我一直对MS在很多设计思\和决定上?j)存疑虑Q不明白Z么MS是要自成风格搞自己那一套蹩脚的所?规范"?标准"Q似乎在鼓励大家follow一个ƈ不清晰、多有些؜杂无章的设计架构Q其实ؓ(f)?jin)方便它实现更cool?abbr title="What You See Is What You Get">WYSIWYG开发工兗就拿今天来_(d)本来我们目定义好所有模块都按BO和UI分开QBO里面的类和UI里面的类各施其责Q原则上UI依赖BOQ而不是反q来Q按照我的理解和期望QW(xu)indows.Forms命名I间应该是由UI层来依赖Q而非BO层。很昄Q因为我们的form都放在UI层,肯定是依赖Windows.Forms?jin),而我们尽可能把所有业务逻辑代码攑ֈBO层。但是ؓ(f)?jin)?f)时实C个文本文件Ş式的logQ因为我们的业务逻辑代码都在BO层,所以ؓ(f)?jin)记录有意义的logQ我们的log逻辑自然而然只能攑֜BO层。但是一个基本的获取E序q行路径的方法属于System.Windows.Forms.Applicationc,让我们不得不using System.Windows.Froms。这其实q好Q我们也怸应该强求Windows.Forms一定就是只针对UI上的应用。问题是你每天都在面对类似的情况Q每天都或多或少在和.NET API和框架其他部分在打架Q当你?NET的API旉久了(jin)Q自然而然你就被它带到它的那一套思\中,你的设计也就自然而然跟着它走?jin),业务逻辑和UI逻辑交织在一P当你回过头来x(chng)层次理清理顺已经成ؓ(f)Mission:Impossible。因为抛开MS推荐的方式,自己实现一套自认更清晰的架构,相较"官方"的blueprint设计Q代价实在有些高?/p>

所以虽然我没有真正开发过ASP.NETQ尤其是2.0版,但我很能理解他们遇到的尴?/p>


laogao 2007-01-25 23:01 发表评论
]]>
Learn to be defensivehttp://www.aygfsteel.com/sean/archive/2007/01/25/95819.htmllaogaolaogaoWed, 24 Jan 2007 16:03:00 GMThttp://www.aygfsteel.com/sean/archive/2007/01/25/95819.htmlhttp://www.aygfsteel.com/sean/comments/95819.htmlhttp://www.aygfsteel.com/sean/archive/2007/01/25/95819.html#Feedback1http://www.aygfsteel.com/sean/comments/commentRss/95819.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/95819.html 作ؓ(f)开发者,我们必须要学?x)defensive programmingQ尤其是对要求高可靠性和无h职守的企业应用中,需要特别留意我们的设计和编码,必须可能做到够defensive?br/>
什么是defensive programmingQD个大安看过的例子:(x)

String str = ...
if ("".equals(str)) {}

在这里我们不写str.equals("")而是反过来,是Z(jin)防止出现不必要的NPE ?NullPointerException?br/>
q行期异常是最最需要特别关照的一U非正常状况Q除?jin)像上面q类要求我们采用相对较好的编码习(fn)惯之外,Z(jin)减少q行期异常的发生Q通常也需要用try-catch代码块来把我们相对脆弱,或者需要格外保护的逻辑包v来,对于外部传进来的参数Q一定要assert它们的合法性,即assert它们是否能够安全的被后面的逻辑所使用?br/>
通常意义上,defensive programming主要cover的是避免不必要的q行期异常发生。我们可以更q一步,更广义的q用defensive programming的核?j)思想Q在企业应用中,除了(jin)q行期异常,对于有些看似严重的极端的错误Q如|络时Q连接丢失,数据库提交失败等情况Q需要我们具体问题具体分析,q所有checked exception都一定需要我们去一一catch然后处理。更多的时候,其当开发无守的后台E序Q我们可以采取重试、报告、修改外部数据等方式处理Q能够自行解决的Q就不要动不动就报错Q或{待用户认Q不能自行解决的Q则要及(qing)时报告ƈ停止q行Q避免更大的错误发生?br/>
举个相对具体的例子,两个异构的系l,通过一个中间层的消息^台相互发送消息,通信协议采用最基本的socket方式Q这三个pȝ随时都可能出现宕机或链接中断的情c(din)ؓ(f)?jin)保证数据的完整性,我们拿其中一个需要发送和接收消息的系l来l说Q?br/>
一个可能的实现方式是:(x)该系l所有要发送的消息保存到数据库Q给它一个初始状态;另一个独立进E从数据库按照时间先后拿出消息,更新拿出的这条消息的状态ؓ(f)处理中,q尝试发送消息;成功后根据需要,更新消息状态ؓ(f)成功发送或者直接删除,如果遇到p|或异常,消息恢复为初始状态,U程sleep一D|_(d)然后再次试Q多ơ尝试或者尝试跨度超q一定时间范_(d)则停止处理,向管理员汇报Q通过邮g、短信等途径Q。对于接收到的消息,同样是先存入数据库,然后再由后箋(hu)的进E用cM的方式取出ƈ处理。如果程序崩溃,可以自动重新启动Q应用或整个服务器)(j)。这样不哪一D通信U\出现故障或阻塞,或者宕机,pȝ都可以一步一个脚华ͼ保dd而自动的执行Qƈ且忠实记录下有h(hun)值的状态信息,出现问题时管理员可以很直观的看到在哪个环节出现故障,从而快速找到问题关键ƈ有效解决?br/>
Defensive programming可以让我们的应用更健壮,在保证数据正性、完整性的前提下,面对困难也能更加独立自主。和defensive programming相关的话题我惛_家如果感兴趣Q可以展开更多更深入的探讨Q这里只是给大家做个介绍性的铺垫Q能抛砖引玉当然更好?br/>



laogao 2007-01-25 00:03 发表评论
]]>
[闲侃DRY] 开?/title><link>http://www.aygfsteel.com/sean/archive/2007/01/22/95424.html</link><dc:creator>laogao</dc:creator><author>laogao</author><pubDate>Mon, 22 Jan 2007 15:22:00 GMT</pubDate><guid>http://www.aygfsteel.com/sean/archive/2007/01/22/95424.html</guid><wfw:comment>http://www.aygfsteel.com/sean/comments/95424.html</wfw:comment><comments>http://www.aygfsteel.com/sean/archive/2007/01/22/95424.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sean/comments/commentRss/95424.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sean/services/trackbacks/95424.html</trackback:ping><description><![CDATA[<br/> DRYZ物?DRY是Don't Repeat Yourself的羃写,不要重复自己Q这是一Y件开发中的重要原则,或者至是一个很好的?fn)惯。同L(fng)数据、逻辑Q我们应该尽量避免在代码、配|文件、数据库中重复,如果实在没有其他更好的办法,也应该尽可能不要手写q些重复的内宏V?br/> <br/> 既然是闲侃,我想没必要那么一本正l,索性天马行IZ把,惛_哪儿写到哪儿吧?br/> <br/> 一直不?fn)惯用桌面版RSS阅读器,最q又从Newsgator回到?jin)熟?zhn)的BloglinesQ由于工作忙Q经q几周的U篏QKeep New的条目数过500。唉Q又Ơ下一堆的阅读债。几l删减,订阅的RSS Feed源还是有80个之多?br/> <br/> 一直在犹U要不要取消BlogJava的综合区RSS订阅Q一斚w舍不得,毕竟自己在BlogJava安家Q怎么说也得捧一下场Q而我也需要持l了(jin)解这个圈子的人眼下都在做些什么想些什么;另一斚wQ实在有些难以忍受无C做删减,原封不动照搬照抄其他|站内容的blog文章Q其中不我早已从其他渠道看到过Q或者没什么特别的内容Q整D|D늚代码Q这L(fng)文章看了(jin)是一句话Q头痛?br/> <br/> 当然?jin),别h怎么写blogQ我无权q涉Q但是我是不是可以在q里呼吁一下,引用其他|站内容Q能不能不要整篇照脓(chung)Q要么给个链接,让大家自己去看,要么适当的引用你认ؓ(f)最有h(hun)值的D落或句子,或者适当l出自己的见解和评论Q否则很难让别h怿你的诚意和动机,q是对原文作者、你的读者、以?qing)你自己L(fng)的尊重?br/> <br/> 换个角度来看问题Q如果我们把软g开发社区看作一个整体,而我们就是这个整体中的一员,那么原封不动的拷贝粘贴这个整体中另外一个个体的文章内容Q又何尝不是在广义上与DRY背道而驰Q既然互联网l我们大家提供了(jin)分n信息的便利,Z么我们自׃懂得ȝ护这个本该服务于我们自己的环境呢Q?br/> <br/> <br/> <img src ="http://www.aygfsteel.com/sean/aggbug/95424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sean/" target="_blank">laogao</a> 2007-01-22 23:22 <a href="http://www.aygfsteel.com/sean/archive/2007/01/22/95424.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʡ</a>| <a href="http://" target="_blank">ʯ</a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank">괨</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ֺ</a>| <a href="http://" target="_blank">߰</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">彧</a>| <a href="http://" target="_blank">˷</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͭ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ܿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ξ</a>| <a href="http://" target="_blank">dz</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>