Flicker1985's Blog

Everything should be made as simple as possible, but not simpler.

统计

2011年7月21日

多ruby版本环境下no such file to load解决办法

  今天下午在配置ruby开发环境时,发现一个非常trick的问题---当我们启动rails环境时会报no such file to load : iconv。

       因为我们的开发环境比较复杂,而且是基于一个legacy的系统,所以我们需要多个ruby版本。在这种情况下rvm自然成为了我们的首选目标。我当时的情况就是我需要2个不同的ree(ruby enterprise edition),一个是1.8.7-2010.02,另外一个是1.8.7-2011-03。刚开始的时候只要后面这个版本在启动rails时报no such file to load, 后来在我一怒之下卸载了rvm,然后重新安装之后发现两个版本同时报no such file to load, 当时我一下子就瞎菜了。

  休息了一下子,我google了一下发现我应该是缺少了libiconv这个组件,下载之后

  tar xzvf libconv.tar.gz

      cd libconv-1.31.1

      ./configure --prefix=/usr/local/

      make && make install

     安装了之后,

      ls /usr/local/include/ | grep 'iconv.h' 

  检查安装是否成功。安装了iconv的组件,但是它此时还是一个系统的组件,我们的ruby并无法直接调用它。要让ruby能够直接调用它我们就需要对这个组件生成一个ruby能够调用的wrapper。此时,我们需要进入到我们的ruby源代码目录下的ext(在rvm安装的ruby应该是在~/.rvm/src/ree-1.8.7-2010.02/source/ext)目录中,在这个目录你能够看到很多东西,这些东西都是ruby对os中不同组件的调用的代码。这里我们需要的是iconv,我们就进入到iconv目录中,然后执行:

 ruby extconf.rb --with-iconv-dir=/usr/local/ #如果你的liconv不是安装在默认路径,这里需要指明你的libconv的安装目录,否则生成的make文件是无效的

   make && make install

这里有一个点要特别注意就是,在执行这些脚本之前确定你的ruby版本,如果你进入到了ree-1.8.7-2010.02的ext/iconv去调用ree-1.8.7-2011.03去执行编译,显然是不work的。

 其他的类似错误报no such file to load:zlib或者ssh,解决方法都是一致的。


 刚开始的时候觉得,为什么这些ext目录的东东不在ruby开始编译时就检查系统依赖,然后直接编译,如果没有这些依赖直接报错。后来想了想,似乎并不是所有情况下我们都需要这ext,所以用到时候再编译似乎也是有道理的,因为这些东西毕竟不是core,只是ext嘛。     

  


  


posted @ 2011-07-21 23:56 Fei He 阅读(214) 评论(0) 编辑

2011年5月29日

TDD需要debugger吗?

  昨天和一个同事一起pair的tdd的时候,有一个测试一直红着,我只好开了debugger来调试。这时候对面的8x,笑嘻嘻的说:

  ”tdd开debugger就是tdd的耻辱!“

真的如此吗?我们首先回顾一下tdd是的节奏red/green/refactor:

  • Red - Write a little test that does'n work, and perhaps doesn't even compile at first.
  • Green  -  Make the test work quickly, committing whatever sins neccessary in the process.
  • Refactor  -  Eliminate all the duplication created in merely getting the test to work.

我们不得不开debugger的原因是因为我们不能很快的让我们的测试通过,那么怎么样才能让我们的测试很快的通过呢?很简单

  Expected Error

如果你的测试能得到expected error,那么你自然能够很快的解决这个这个expected error;反之如果你的测试得到是一个unexpected error,你又怎么能够很快的让你的测试通过呢?而这个时候,你往往都会求助于debugger。而要让我们的每一步测试都得到一个expected error,只需要保证separate concern,也就是说你的每一步测试都只有一个关注点, 即

  Verify One Condition Per Test

能做到这一点基本上就能保证你的每一步测试都得到一个expected error。而在我们实际的开发中,如果我们采取Inside-out的策略还好,而对于Outside-in的策略我们的测试往往就会被有很多”噪音“。举个例子,比如我们要测试一个service的某一个功能,而这个功能依赖与另外一个repository的一个保存或者更新的功能,采用inside-out的方式,你会先写这个repository的测试,然后在写service的测试,这种情况下你很容易保持测试的独立性;反之,对于outside-in你就需要先写service的测试,而这个时候你的repository根本还没有实现,而此时你service的测试必然被这个没有实现的repository所干扰。这种情况下,为了隔离这种”噪音“,stub就出现了。本来想说mock,但是我发现很多人还不能清楚的明白mock,stub,fake,dummy之间的区别,为了不干扰这篇文章的主题,以后另起一篇吧(写博客也要separate concern)。

  TDD需不需要debugger,并不是否定debugger的作用,只是希望我们不要过分依赖debugger。而你我都知道,在我们的开发过程中debug的时间经常会超过我们写代码的时间,这是一件非常tricky的事情(也许有些人已经习惯了)。尽管现在的还不能完全说我不用debugger,但我已经在努力了,那么你呢?

posted @ 2011-05-29 00:34 Fei He 阅读(1326) 评论(40) 编辑

2011年5月26日

快速开发新浪微博的firefox插件(下)

  上篇主要讲了讲firefox插件的机制,接着我们来看快速开发一个firefox插件中我面临的第二个问题----Oauth授权(开始开发的时候只是想着快速开发完成,当然授权这块最快的方案自然就是basic auth,但是新浪微博6月1号以后就不支持basic auth了。)。

  Oauth的官网上说是这样描述它的用途:

    An open protocol to allow secure API authorization in a simpleand standard method from desktop and web applications.

在Oauth的官网上对Oauth有详尽的描述以及不用语言对于Oauth的实现,对于我的开发我需要了解的其实非常简单.

首先对于Oauth有三个url是必须了解的:

  • Request Token URL
  • User Authorize URL
  • Access Token URL

另外,我们还需要了解针对这些URL相应的一些参数:

  • oauth_consumer_key
  • oauth_consumer_secret
  • oauth_signature_method
  • oauth_signature
  • oauth_timestamp
  • oauth_nonce
  • oauth_version

具体这些URL和参数有什么作用呢?我们结合新浪微博来说。对于开发一个新浪微博的应用,你必须在新浪微博申请一个app key和app key secret, 有了它们我们就可以开始了。新浪的Oauth是这样一个流程:

  1. 第一次你需要做的是Request Token URL,对于新浪微博就是http://api.t.sina.com.cn/oauth/request_token。接着就是请求的参数了,这个时候你需要把你申请的app key作为oauth_consumer_key, 而把你的app key secret作为oatu_consumer_secret。oauth_signature_method就是你的加密算法,oauth支持 HMAC-SHA1, RSA-SHA1, PLAINTEXT这三种算法,而新浪微博指定需要HMAC-SHA1,所以对与oauth_signature_method我们这里就是HMAC-SHA1了。oauth_timestamp就是请求的时间戳,这个时间戳的范围是现在1970 00:00:00 GMT的秒数,而且每次请求的时间戳必须大于上次的。oauth_nonce就是随机生成的一个字符串,就是为了防止重复请求。oauth_version现在只能是1.0。最后我们需要对所有参数使用oauth_signature_method指定的加密算法加密作为oauth_signature。对于请求的参数,我们有两种绑定方式:Get: 拼URL;Post: 放在Http heads里。 有了URL和参数我们就可以发起我们的请求。当新浪微博接受我们的请求检查合法后,会返回给我们一个未授权的oauth_token和oauth_token_secret,因为我们还没有获得用户的授权。
  2. 有了上一步的请求返回的oauth_token和oauth_token_secret,在进行下一步请求之前我们需要根据我们应用的类型决定我们下一步的策略。如果我们是一个web应用,我们有自己的域名我们就可以选择使用callback_url的方式,但是我要做得是一个firefox插件这种方式显然不合适,那么我只有选择使用verify PIN的方式了。确定了这个,我们请求User Authorize URL(对于新浪微博就是http://api.t.sina.com.cn/oauth/authorize)。这次的参数和上次的参数还是有一些小小的差别的:首先,我们这次需要用上次请求返回的oauth_token作为oauth_consumer_key, 使用返回的oauth_token_secret作为oauth_consumer_secret,oauth_signature_method不变,oauth_timestamp根据这次请求的时间重新生成,oauth_nonce重新生成,oauth_version不变,而oauth_signature根据这次的参数生成。在User Authorize过程中,我们要加一个参数callback_url。因为我们采用verify PIN的方式,所以这个参数我可以指定为xml。因为这一步就用户授权,那么我们自然还是要输入我们需要访问的新浪微博账号的用户名和密码,分别作为userId, passwd。新浪微博接收到我们的User Authorize请求检查合法后,会以xml格式返回给我们一个oauth_verifier,证明我们的应用获得了用户的授权。
  3. 有了oauth_verifier, 加上我们第一步获得oauth_token和oauth_token_secret,其他参数还是按照前面的规则(这次不需要oauth_callback)构成我们的参数,我们来请求Access Token URL(对于新浪微博就是http://api.t.sina.com.cn/oauth/access_token)。 这一次新浪微博会返回access_token和access_token_secret, 我们授权就通过了。而这个access_token和access_token_secret当我们以后请求新浪微博API时,会作为oauth_consumer_key和oauth_consumer_secret出现。比如我们要发送微博,新浪微博发送微博的API是http://api.t.sina.com.cn/statuses/update.json。这时我们还是按照前面的规则组织参数(以access_token作为oauth_consumer_key, access_token_secret作为oauth_consumer_secret),同时加上参数status,值为我们需要发送的内容就OK了。

到这一步,我们还不算完,因为我们需要在firefox的插件中调用新浪微博的oauth。我们都知道javascript直接调用新浪微博的API是跨域请求,这是不被允许的。而我们通常解决跨域请求的方式主要就是:Jsonp, flash,iframe。这里面我们唯一可以尝试是jsonp,而jsonp是需要server端也就是新浪微博配合的,而实际上新浪微博是不支持jsonp的。那是不是我们没有办法了呢?

  @mozilla.org/xmlextras/xmlhttprequest;1

查看了MDN的文档,发现firefox自己的Xmlhttprequest可以,而且可以指定同步还是移步,然后在callback方法里解析返回参数。具体如何实现MDN。

ps:这个插件的代码是作为一个其他应用的一部分,这涉及其他人的劳动,有兴趣可以发站内信或邮件我会单独发一份(只包含firefox插件部分)给你。

posted @ 2011-05-26 22:57 Fei He 阅读(1530) 评论(1) 编辑

2011年5月24日

快速开发新浪微博的firefox插件(上)

     在开发这个插件之前,自己对javascript的使用也就是web page中简单的操作dom,而对于firefox插件开发一无所知,OAuth连听都没有听过。所以对于我眼前要干得事情我有两个难点,第一就是firefox的插件机制,第二就是了解OAuth。
  
     firefox的插件机制

     对于一个firefox插件来说,我们首先需要了解的它的组织结构。打开一个firefox插件工程,你一般会看这么几个元素:chrome文件夹,defaults文件夹,chrome.manifest, install.rdf。

  我们先从install.rdf说起,相比从文件名你就明白了这个文件是要干什么的。没错,这个文件就是firefox插件的安装文件。



     
    
        flashcard@gmail.com
        0.7
        2
        flashcard
        Post the selected word to Sina weibo.
        https://feihe.cnblogs.com
				chrome://flashcard/skin/icon.png
        
        Fei He

        
            
                {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
                3.0
                4.0.*
            
        
    

里面也就是对于你的firefox插件的一些描述信息,其中比较关键的两个<em:id>, 在根节点description下的<em:id>是你的firefox插件的id,也就是说这个东西必须唯一(至少在你的firefox所有插件中唯一),另一个位于<em:targetApplication>的<Description>下的<em:id>则是firefox的id,这个是不能修改的。再就是<em:minVersion>和<em:maxVersion>,它们用来描述你的firefox插件对于firefox版本的兼容性。

    接着我们来了解defaults,一句话defaults就是你的firefox插件的preferences的default设置。

 对于一个firefox插件最核心的部分就是chrome.manifest和chrome文件夹。chrome.manifest有点像.NET的project文件,基本上就是对于整个firefox插件所有元素的位置信息,而firefox本身就是通过这个这个manifest来定位具体的元素。那么一个firefox插件会包含那些元素呢?打开chrome.manifest你就一目了然了。

overlay		chrome://browser/content/browser.xul    chrome://flashcard/content/overlay.xul
content		flashcard	chrome/content/flashcard/
skin	flashcard	classic	chrome/skin/classic/flashcard/


locale	flashcard	en-US	chrome/locale/flashcard/en-US/
style	chrome://global/content/customizeToolbar.xul	chrome://flashcard/skin/skin.css

这里面的结构基本都是行结构的,每一个行的头就是具体的firefox插件元素名称,而后面的是告诉firefox去那个位置查找这个元素。而这其中包含了这么几个元素:

  • overlay: 指向你的firefox插件的一个UI元素,包括contextmenu,toolbar,navigator bar之类。在上面的manifest中你看我这里指向了一个后缀名是xul的文件,其实它的全称是Xml User Interface。顾名思义就是使用xml的格式来描述UI。





    
    
        
    

    
    
    
    
    
        
        
    

上面是我用的一个overlay.xul, 我这里是给firefox的contextmenu加了一个新的menuitem,并使用separator和原有的menuitems分隔起来。这里的文件名是可以随意取的,那是你起的名字必须在chrome.manifest中应用。到这里很多人好奇,那么你加的menuitem相应的行为在那里呢?细心的你也许发现我这个xul中引用了一些javascript,而对于我们menuitem,firefox提供了2中方法去关联行为:第一种就是在control的oncommand中直接指定control的行为;第二中是javascript中使用document.getElementByID来获取control从而绑定行为:

    

	document.getElementById("menuitem_flashcard_add").addEventListener("click", function(event){}, false);
并且,我也在这个文件中指定了css文件。其实对于xul文件中javascript和css的使用和html都基本一致。
  • content: 就是你的firefox插件的核心,包括javascript脚本和XUL
  • skin:即使皮肤,你可以在给你的插件做不同的皮肤,我的mainifest中指定了我使用classic的皮肤,所以我在skin文件夹下就应classic的文件夹来对应。
  • locale:国际化,对于我们firefox插件中需要需要国家化的UI control, 我们可以使用它的label属性,同时在chrome.manifest中指定的culture文件夹下定义dtd文件来对应,例如: overlay.xul中的control定义:
            
    

    dtd文件的定义:
    它们之间使用control的label属性关联,而overlay.xul具体和chrome.manifest指定culture文件夹下的那个dtd文件关联,你可以看到在我的overlay.xul中有这么一句定义:
  • style: 也就是overlay的一些样式,比如css。

 你的firefox插件有了UI,也有了相应的行为和样式,那么你还需要什么呢?需要存储,也就是你需要存储一些preferences信息或者其他的比如我这里我需要存储新浪微博中用户授权通过之后获得的Oauth_token的相关信息。firefox对于存储提供了很多方式,你可文件存贮在特殊位置,或者使用sqlite这种肖的文件数据库。另外一种最简单的也就是我采用的就是preferences的存贮。对于firefox插件,你可以在你的install.rdf中注明你的preference文件,这样你可以让用户使用的preference文件做一些设置,并保存。而我这里我指希望使用preferences来存贮,所以我并不希望用户看到它,那么我就不需要在install.rdf中注明。

preference文件也是一个xul文件,所以你也可以应用javascript和css,来对于你的preference中的control进行行为的绑定和样式的渲染。我这里的preference如下:





	
	
		
		
	

而这其中的preferences节点中的内容便是用来做preference存贮的,你可以像我一样通过
Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("Sina.WeiBo.")

来获得所有name前缀为Sian.Weibo的preference,然后调用它的getCharPref('oauth.access_token')来获取值,或者通过setCharPref('oauth.access_token')设置值,对于preference,MDN上有详细的API介绍。对于在preference中引用javascript比较tricky的一点就是如果在你preference中使用prePanel,那么javascript的引用代码一定要在prePanel后面,否则你的prePanel就什么都看不到了。

最后一点,有些时候也许你希望你的firefox插件在完成某些行为之后给用户一个notification,在firefox3中你可以使用普通的notification或者alert,而在firefox4中你可以使用popupNotification,效果非常炫,而且还可以指定图片和相应的action,使得用户在得到这个notification之后可以做进一步的行为。示例如下:

			PopupNotifications.show(gBrowser.selectedBrowser, "flashcard-add",
			        '"'+ selectedWord +'" 已经成功加入你的单词本',
			        null, 
					{
						label: "确定",
						accessKey: "D",
						callback: function() {
						}	
					},
					[
						{
							label: "Reset",
							accessKey: "R",
							callback: function() {
								Browser.Preferences.clearUserPref("oauth.access_token");
								Browser.Preferences.clearUserPref("oauth.access_token_secret");
							}	
						},
					]);
而指定图片则要在css中
.popup-notification-icon[popupid="flashcard-add"] {
	list-style-image: url("chrome://flashcard/skin/icon.png");
}
这里是我在快速开发一个firefox插件中获得知识,如果你希望更详细的知识还是需要参考MDN。写到这里发现篇幅有点长,还是决定分为上,下两篇。下篇来讲Sina WeiBo的Oauth授权机制。

posted @ 2011-05-24 21:45 Fei He 阅读(2159) 评论(3) 编辑

2011年4月27日

大项目的思考

  引言:进入现在这个我们内部的大项目已经两个多月了。现在回想起进入项目前一位前辈的话:“大项目有大项目的问题,但大项目也有很多东西可学“,自己此时深表赞同。二个月的时间,自己从刚来前两周的观察学习,到现在的基本融入,在这个过程中自己有了很多的想法和思考。

  为什么测试这么难写?

  tdd的开发实践保证了代码的可测试性,那么当tdd的t变的非常难写的时候是不是现有的代码已然变的可测试性非常的差呢?其中一些非常典型的场景就是

  • test的setup太难,而造成这个的一个主要原因就是贫血的model和万能的service。因为model没有行为,所以很多时候可以通过测试model来完成的测试,却不得不通过测service来完成,而万能的service做的事情又太多,需要依赖的东西也太多,而这个时候你本来一个简单的测试就为了setup这个service的依赖而变成一个巨型的测试。
  • 你总有做behavior verification的冲动,而behavior verification本身就是邪恶的。记得《xUnit test pattens》这本书说到,”任何需要白盒测试的时候,往往都是代码设计的问题“。
  • Assert太多了,一个简单的测试却要有一堆的assert语句。问题很简单,被测试的对象承担了太多了职责。
  • 脆弱的测试,这里我看到了有两个原因:第一,共享的fixture;第二,想当然的assert,比如你只是想assert这个collection有没有你要的那个instance,因为你想当然的认为此时collection里只有一个instance,造成后人对于这个collection加入另一个不同instance依然会break你的测试。

  Kent Beck说过,当你的测试出现问题,退后一步往往就是一个设计问题。

  项目初期设计framework好吗?

  很多人开发人员迷恋framework,迷恋framework设计的优雅以及对于开发的便利。我曾经也是其中一员,但是现在我站在了这个观点的对立面。

  首先,项目初期的时候framework的设计在大部分都是猜测,刚开始的时候这些猜测大部分都很准,因为这个时候距离是framework的设计者可以看到了,这就如同你站在原地,你能看到10外的东西,随着项目时间的增长,这个距离也在增长,在加上中间需求的一些变更就如同一个小弯,这时候的位置已经不是framework的设计者所能看到的距离了。这个时候framework对于开发限制开始突出,而开发人员碍于修改framework成本太高,很多时候被framework所牵制。既然我们只能看到10米外的东西,那么我们为什么要做100米外的设计呢?

  其次,framework的设计思想也会随着项目人员的进进出出,项目进度的压力,大家都没有实践仔细的去看framework。framwork的设计思想变的不再清晰,大家开始按照自己的对于framework的理解来写代码,后来着更不理解framework,会照那些前面未必正确的理解的代码来书写。

  构建环境

   一个稳定而快速的构建环境对于团队的开发效率和开发人员的心情影响非常的大。想象一下下面两种情况:

  1. 如果你每次提交代码都让build变红,而你花了几个小时检查之后发现问题出在构建环境上,你是什么心情?
  2. 如果你每次提交代码测试都要跑2个小时,你会选择多久提交一次代码呢?

   个人理解的解决方案就是讲build环境也版本管理,理想的情况下新修改build脚本导致构建环境不稳定,可以快速的revert到上一个版本的构建环境。

  团队!团队!

  一个团队是不仅是在维护一份源代码,更重要的是维护这个项目所承载的知识。而这些知识不应该只记在某些关键人物的脑中,应该记在所有团队成员的脑中,更不应该只记录在文档之中。而这知识包括:

  1. 架构设计的知识:架构设计的知识只有进入所有开发人员的脑中,才能得到正确的实现。因此架构设计不应该只从技术角度考虑,也应该从团队知识传递的角度考虑。一个100的设计,而团队成员只能理解30分,那你觉的最后的软件是多少分呢?
  2. 所谓的局部知识:很多时候,一些开发人员觉得我做的东西只有我一个人在做(比如build脚本),所以我可以选我熟悉的东西就好。而这种所谓局部知识的想法非常不可取,因为当你有这个想法的时候就意味着你变成这个项目的瓶颈。
  3. 固定角色:在团队中固定角色就意味着划定了各个角色的边界,而每个角色对于自己角色外的东西已然不是外面的世界很精彩。这个时候很多时候它做得决定都是基于自己的角色,而不是整个团队的角度

posted @ 2011-04-27 23:36 Fei He 阅读(4773) 评论(28) 编辑

2011年4月17日

初窥Ruby Metaprogramming

摘要: 接触了一段时间得ruby on rails,深深被ror的magic,powerful,elegantly所折服,同时也对ruby这个神奇的语言本身产生了很大的好奇心,而其中最神奇的莫过于ruby 的 Metaprogramming。Classes are open 我们先看一段代码:class String def say_hello p "Hello!" endend"Fred".say_hello这里我们看到我们reopen了String这个build-in的class,而且添加了一个新的方法say_hello(.NET 3.5中通过扩展方法也实现阅读全文

posted @ 2011-04-17 21:14 Fei He 阅读(1150) 评论(4) 编辑

2011年4月16日

敏捷在路上(二)迭代开发和用户故事

摘要: 引言:在上一篇中,我聊到了敏捷可以通过小步前进来最大程度的减少浪费。接着我们来聊聊敏捷是如何小步前进的。 在瀑布式开发中我们的步子迈的太大了,导致我们首先无法快速应对变化,其次我们需要付出很大的代价来应对变化。而敏捷迭代开发则可以让我们小步的往前走,以一种增量式的模式来进行开发。那么敏捷迭代中迭代的是什么呢?我觉得迭代的交付可工作的软件。 首先,我们看看敏捷迭代大致的流程:首先和用户讨论需求,定义系统的personas,并将用户需求划分成一个个的用户故事和用户一起将所有的用户故事按照关联和优先级划分到一个个的迭代之中保证在每个迭代都可以交付给用户可工作的软件接着我们展开每个过程。而在第一个过.阅读全文

posted @ 2011-04-16 00:42 Fei He 阅读(1683) 评论(3) 编辑

2011年4月14日

敏捷在路上 (一)为什么敏捷

摘要: 前记 对于敏捷软件开发,听说已久。最近刚刚开始走上敏捷的路上,所以记下自己一路上感受和收获。 为什么我们要采用敏捷软件开发呢?这也许是所有刚开始接触“敏捷”这个概念的第一个问题,那我们就从第一个问题开始我的旅程。通常我们在开发中引入一些新的实践无非就两个原因,要么就是我们现有的开发模式有问题,要么就是这个新的开发模式更有效率。那么我们首先可以回顾一下我们现在被大多数团队采用的瀑布式开发。 在瀑布式开发中我们有开发过程分为一下几个阶段:分析,设计,实现,测试。其中每一个阶段的产出作为下一个阶段的输入。而这里隐含了两个假设:当我进入设计阶段的时候,我假设我的分析是正确的并且不会再变化。当我进入实.阅读全文

posted @ 2011-04-14 22:26 Fei He 阅读(1226) 评论(8) 编辑

2011年3月28日

Transaction Scripts vs Domain Model

摘要: 最近和一些朋友在闲聊之中发现不少人对于Transaction Scripts的认同和对于Domain Model的不理解都让我非常的诧异。所以就有了这篇文章。 首先,什么是Transaction Scripts,什么又是Domain Model呢?据我所知这两个概念都是Martin Flower在《Patterns of Enterprise Application Architecture》中提出来的,指的是两种对于Domain Logic的组织方式。具体的定义如下: Transaction Scripts是指: “Organizes business logic by produces .阅读全文

posted @ 2011-03-28 23:33 Fei He 阅读(1118) 评论(9) 编辑

2011年3月2日

软件开发学习呓语

摘要: 问题 我们会加入很多不同类型的软件开发项目,每个项目的需求不同,但当我们将需求转化为计算机的实现,却会发现我们总是会遇到些熟悉的问题,例如:transcation,security,concurrence,communication,persistence,presentation等等呢。所了解和熟悉我们需要解决的问题非常重要技术方案 对于企业级软件开发之中遇到的问题的解决方案就是才是技术解决方案。而技术解决方案的选择依赖与对需求的理解和对现有技术的了解。比如对于persistence的选择我们有orm,table-mapping等,而对于cross cutting的处理我们往往会选择AOP,阅读全文

posted @ 2011-03-02 22:19 Fei He 阅读(83) 评论(0) 编辑