感觉挺有趣的,就转过来给大家看了。

紧耦合
  从前,在南方一块奇异的土地上,有个工人名叫彼得,他非常勤奋,对他的老板总是百依百顺。但是他的老板是个吝啬的人,从不信任别人,坚决要求随时知道彼得的工作进度,以防止他偷懒。但是彼得又不想让老板呆在他的办公室里站在背后盯着他,于是就对老板做出承诺:无论何时,只要我的工作取得了一点进展我都会及时让你知道。彼得通过周期性地使用“带类型的引用”(原文为:“typed reference” 也就是delegate??)“回调”他的老板来实现他的承诺,如下:

class Worker {
public void Advise(Boss boss) { _boss = boss; }
public void DoWork() {
Console.WriteLine(“工作: 工作开始”);
if( _boss != null ) _boss.WorkStarted();
Console.WriteLine(“工作: 工作进行中”);
if( _boss != null ) _boss.WorkProgressing();
Console.WriteLine("“工作: 工作完成”");
if( _boss != null ) {
int grade = _boss.WorkCompleted();
Console.WriteLine(“工人的工作得分=” + grade);
}
}
private Boss _boss;
}
class Boss {
public void WorkStarted() { /* 老板不关心。 */ }
public void WorkProgressing() { /*老板不关心。 */ }
public int WorkCompleted() {
Console.WriteLine(“时间差不多!”);
return 2; /* 总分为10 */
}
}
class Universe {
static void Main() {
Worker peter = new Worker();
Boss boss = new Boss();
peter.Advise(boss);
peter.DoWork();
Console.WriteLine(“Main: 工人工作完成”);
Console.ReadLine();
}
}

接口
  现在,彼得成了一个特殊的人,他不但能容忍吝啬的老板,而且和他周围的宇宙也有了密切的联系,以至于他认为宇宙对他的工作进度也感兴趣。不幸的是,他必须也给宇宙添加一个特殊的回调函数Advise来实现同时向他老板和宇宙报告工作进度。彼得想要把潜在的通知的列表和这些通知的实现方法分离开来,于是他决定把方法分离为一个接口:

interface IWorkerEvents {
void WorkStarted();
void WorkProgressing();
int WorkCompleted();
}
class Worker {
public void Advise(IWorkerEvents events) { _events = events; }
public void DoWork() {
Console.WriteLine(“工作: 工作开始”);
if( _events != null ) _events.WorkStarted();
Console.WriteLine(“工作: 工作进行中”);
if(_events != null ) _events.WorkProgressing();
Console.WriteLine("“工作: 工作完成”");
if(_events != null ) {
int grade = _events.WorkCompleted();
Console.WriteLine(“工人的工作得分=” + grade);
}
}
private IWorkerEvents _events;
}
class Boss : IWorkerEvents {
public void WorkStarted() { /* 老板不关心。 */ }
public void WorkProgressing() { /* 老板不关心。 */ }
public int WorkCompleted() {
Console.WriteLine(“时间差不多!”);
return 3; /* 总分为10 */
}
}

委托
  不幸的是,每当彼得忙于通过接口的实现和老板交流时,就没有机会及时通知宇宙了。至少他应该忽略身在远方的老板的引用,好让其他实现了IWorkerEvents的对象得到他的工作报告。(”At least he'd abstracted the reference of his boss far away from him so that others who implemented the IWorkerEvents interface could be notified of his work progress” 原话如此,不理解到底是什么意思 )
  他的老板还是抱怨得很厉害。“彼得!”他老板吼道,“你为什么在工作一开始和工作进行中都来烦我?!我不关心这些事件。你不但强迫我实现了这些方法,而且还在浪费我宝贵的工作时间来处理你的事件,特别是当我外出的时候更是如此!你能不能不再来烦我?”
  于是,彼得意识到接口虽然在很多情况都很有用,但是当用作事件时,“粒度”不够好。他希望能够仅在别人想要时才通知他们,于是他决定把接口的方法分离为单独的委托,每个委托都像一个小的接口方法:

delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted();
class Worker {
public void DoWork() {
Console.WriteLine(“工作: 工作开始”);
if( started != null ) started();
Console.WriteLine(“工作: 工作进行中”);
if( progressing != null ) progressing();
Console.WriteLine("“工作: 工作完成”");
if( completed != null ) {
int grade = completed();
Console.WriteLine(“工人的工作得分=” + grade);
}
}
public WorkStarted started;
public WorkProgressing progressing;
public WorkCompleted completed;
}
class Boss {
public int WorkCompleted() {
Console.WriteLine("Betterhttp://www.cnblogs.com/Images/dot.gif");
return 4; /* 总分为10 */
}
}
class Universe {
static void Main() {
Worker peter = new Worker();
Boss boss = new Boss();
peter.completed = new WorkCompleted(boss.WorkCompleted);
peter.DoWork();
Console.WriteLine(“Main: 工人工作完成”);
Console.ReadLine();
}
}

静态监听者
  这样,彼得不会再拿他老板不想要的事件来烦他老板了,但是他还没有把宇宙放到他的监听者列表中。因为宇宙是个包涵一切的实体,看来不适合使用实例方法的委托(想像一下,实例化一个“宇宙”要花费多少资源…..),于是彼得就需要能够对静态委托进行挂钩,委托对这一点支持得很好:

class Universe {
static void WorkerStartedWork() {
Console.WriteLine("Universe notices worker starting work");
}
static int WorkerCompletedWork() {
Console.WriteLine("Universe pleased with worker's work");
return 7;
}
static void Main() {
Worker peter = new Worker();
Boss boss = new Boss();
peter.completed = new WorkCompleted(boss.WorkCompleted);
peter.started = new WorkStarted(Universe.WorkerStartedWork);
peter.completed = new WorkCompleted(Universe.WorkerCompletedWork);
peter.DoWork();
Console.WriteLine(“Main: 工人工作完成”);
Console.ReadLine();
}
}

事件
  不幸的是,宇宙太忙了,也不习惯时刻关注它里面的个体,它可以用自己的委托替换了彼得老板的委托。这是把彼得的Worker类的的委托字段做成public的一个无意识的副作用。同样,如果彼得的老板不耐烦了,也可以决定自己来激发彼得的委托(真是一个粗鲁的老板):
// Peter's boss taking matters into his own hands
if( peter.completed != null ) peter.completed();
  彼得不想让这些事发生,他意识到需要给每个委托提供“注册”和“反注册”功能,这样监听者就可以自
己添加和移除委托,但同时又不能清空整个列表也不能随意激发彼得的事件了。彼得并没有来自己实现这些功能,相反,他使用了event关键字让C#编译器为他构建这些方法:

class Worker {
//http://www.cnblogs.com/Images/dot.gif
public event WorkStarted started;
public event WorkProgressing progressing;
public event WorkCompleted completed;
}

  彼得知道event关键字在委托的外边包装了一个property,仅让C#客户通过+= 和 -=操作符来添加和移除,强迫他的老板和宇宙正确地使用事件。

static void Main() {
Worker peter = new Worker();
Boss boss = new Boss();
peter.completed += new WorkCompleted(boss.WorkCompleted);
peter.started += new WorkStarted(Universe.WorkerStartedWork);
peter.completed += new WorkCompleted(Universe.WorkerCompletedWork);
peter.DoWork();
Console.WriteLine(“Main: 工人工作完成”);
Console.ReadLine();
}

“收获”所有结果
  到这时,彼得终于可以送一口气了,他成功地满足了所有监听者的需求,同时避免了与特定实现的紧耦合。但是他注意到他的老板和宇宙都为它的工作打了分,但是他仅仅接收了一个分数。面对多个监听者,他想要“收获”所有的结果,于是他深入到代理里面,轮询监听者列表,手工一个个调用:

public void DoWork() {
http://www.cnblogs.com/Images/dot.gif
Console.WriteLine("“工作: 工作完成”");
if( completed != null ) {
foreach( WorkCompleted wc in completed.GetInvocationList() ) {
int grade = wc();
Console.WriteLine(“工人的工作得分=” + grade);
}
}
}

异步通知:激发 & 忘掉
  同时,他的老板和宇宙还要忙于处理其他事情,也就是说他们给彼得打分所花费的事件变得非常长:

class Boss {
public int WorkCompleted() {
System.Threading.Thread.Sleep(3000);
Console.WriteLine("Betterhttp://www.cnblogs.com/Images/dot.gif"); return 6; /* 总分为10 */
}
}
class Universe {
static int WorkerCompletedWork() {
System.Threading.Thread.Sleep(4000);
Console.WriteLine("Universe is pleased with worker's work");
return 7;
}
http://www.cnblogs.com/Images/dot.gif
}

  很不幸,彼得每次通知一个监听者后必须等待它给自己打分,现在这些通知花费了他太多的工作事件。于是他决定忘掉分数,仅仅异步激发事件:

public void DoWork() {
http://www.cnblogs.com/Images/dot.gif
Console.WriteLine("“工作: 工作完成”");
if( completed != null ) {
foreach( WorkCompleted wc in completed.GetInvocationList() )
{
wc.BeginInvoke(null, null);
}
}
}

异步通知:轮询
  这使得彼得可以通知他的监听者,然后立即返回工作,让进程的线程池来调用这些代理。随着时间的过去,彼得发现他丢失了他工作的反馈,他知道听取别人的赞扬和努力工作一样重要,于是他异步激发事件,但是周期性地轮询,取得可用的分数。

public void DoWork() {
http://www.cnblogs.com/Images/dot.gif
Console.WriteLine("“工作: 工作完成”");
if( completed != null ) {
foreach( WorkCompleted wc in completed.GetInvocationList() ) {
IAsyncResult res = wc.BeginInvoke(null, null);
while( !res.IsCompleted ) System.Threading.Thread.Sleep(1);
int grade = wc.EndInvoke(res);
Console.WriteLine(“工人的工作得分=” + grade);
}
}
}

异步通知:委托
  不幸地,彼得有回到了一开始就想避免的情况中来,比如,老板站在背后盯着他工作。于是,他决定使用自己的委托作为他调用的异步委托完成的通知,让他自己立即回到工作,但是仍可以在别人给他的工作打分后得到通知:

 public void DoWork() {
http://www.cnblogs.com/Images/dot.gif
Console.WriteLine("“工作: 工作完成”");
if( completed != null ) {
foreach( WorkCompleted wc in completed.GetInvocationList() ) {
wc.BeginInvoke(new AsyncCallback(WorkGraded), wc);
}
}
}
private void WorkGraded(IAsyncResult res) {
WorkCompleted wc = (WorkCompleted)res.AsyncState;
int grade = wc.EndInvoke(res);
Console.WriteLine(“工人的工作得分=” + grade);
}

宇宙中的幸福
  彼得、他的老板和宇宙最终都满足了。彼得的老板和宇宙可以收到他们感兴趣的事件通知,减少了实现的负担和非必需的往返“差旅费”。彼得可以通知他们,而不管他们要花多长时间来从目的方法中返回,同时又可以异步地得到他的结果。彼得知道,这并不*十分*简单,因为当他异步激发事件时,方法要在另外一个线程中执行,彼得的目的方法完成的通知也是一样的道理。但是,迈克和彼得是好朋友,他很熟悉线程的事情,可以在这个领域提供指导。
  他们永远幸福地生活下去……

前段时间帮朋友做的网站Logo设计方案,也不知道现在网站做的怎么样了,祝他们好运。

http://www.felixwoo.com/wp-content/uploads/attachments/200603/06_112016_yohologoshow.jpg

Yahoo! UI Library
http://developer.yahoo.net/yui/index.html
The Yahoo! User Interface Library is a set of utilities and controls, written in JavaScript, for building richly interactive web applications using techniques such as DOM scripting, HTML and AJAX. The UI Library Utilities facilitate the implementation of rich client-side features by enhancing and normalizing the developer's interface to important elements of the browser infrastructure (such as events, in-page HTTP requests and the DOM). The Yahoo UI Library Controls produce visual, interactive user interface elements on the page with just a few lines of code and an included CSS file. All the components in the Yahoo! User Interface Library have been released as open source under a BSD license and are free for all uses.

script.aculo.us
http://script.aculo.us/
The Web is changing. The 30-year-old terminal-like technology it was originally is gradually giving way to new ways of doing things. The power of AJAX allows for rich user interaction without the trouble that has bugged traditional web applications. Building upon the wonderful Prototype JavaScript library, script.aculo.us provides you with some great additional ingredients to mix in.

Prototype JavaScript Framework
http://prototype.conio.net/
Prototype is a JavaScript framework that aims to ease development of dynamic web applications. Featuring a unique, easy-to-use toolkit for class-driven development and the nicest Ajax library around, Prototype is quickly becoming the codebase of choice for web application developers everywhere.

http://openrico.org/
http://www.rubyonrails.com/
http://www.mochikit.com/

http://www.felixwoo.com/wp-content/uploads/attachments/200602/23_213044_logo.gif

http://pages.google.com/
在线编辑、发布,就像写文档一样简单,100M空间

我也做了一个Google Page,呵呵http://felixwoo.googlepages.com/

ThinkPad T43 71U

http://www.felixwoo.com/wp-content/uploads/attachments/200602/19_102636_000021541.jpg

几天前,美ABC台20多年前播放的一部情景喜剧《成长的烦恼》(Growing Pains)推出季完整DVD。本套DVD中,除了包括第一季22集完整节目外,还有一集为该套DVD发行作的重聚节目。节目中,20多年过去已经和观众们心中的印象有了很大差别的五位主坐在一起,畅聊当年拍摄时的精彩轶事。
http://www.felixwoo.com/wp-content/uploads/attachments/200602/19_102218_temp.jpg

  在sql server 2000中,要实现显示某一页,就返回那一页数据的效果的方法实在不尽人意.网上很多通用的分页存储过程,但看着就头大.如果使用我前面提到的使用in,not in,top来进行返回特定页,特殊的限制又会比较多(比如ID要递增).现在Sql Server 2005中提供了一个函数ROW_NUMBER(),可以使自定义分页变得简单许多.
我们先来看看ROW_NUMBER()是干什么的.执行下面这段SQL语句:
SELECT [ReportID],[UserName], [ReportID],
[TimeStart], [TimeEnd],ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo
FROM [ExecutionLog]
执行结果如下图所示:
http://www.felixwoo.com/wp-content/uploads/attachments/200601/21_221728_.jpg
很简单,ROW_NUMBER() 就是生成一个顺序的行号,而他生成顺序的标准,就是后面紧跟的OVER(ORDER BY ReportID).现在,你看到了自定义分页的影子了吗?:)下面,我们看看怎么具体应用这个RowNo进行分页.
现在,假设我每一页的数据是10条,我们就可以使用如下所示的SQL语句返回指定页的数据:
@"
SELECT TOP 10 *
FROM
(
SELECT top 10 [InstanceName], [UserName], [ReportID],
[TimeStart], [TimeEnd],ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo
FROM [ExecutionLog]
) AS A
WHERE RowNo > " + pageIndex*10
pageIndex就是我们需要数据的页数.很简单,不是吗?并且,这种方式几乎没有什么限制,因为他相当于对于任何检索,都生成了一个新的排序列.我们就可以使用该列进行自定义分页.

Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads
http://msdn.microsoft.com/library/default.asp?url=/msdnmag/issues/03/02/multithreading/toc.asp

使用 Enterprise Library (2006年1月版) 只改设置文件切换数据库
http://blog.joycode.com/ghj/archive/2006/02/09/71245.aspx

(翻译)怎么在ASP.NET 2.0中使用Membership
http://lovecherry.cnblogs.com/archive/2005/12/05/291092.html

冬天到了,送给大家8种系围巾的方法。

http://www.felixwoo.com/wp-content/uploads/attachments/200512/12_142553_2.jpg

  所有人都知道Google有多酷,但外界并不清楚,它为什么能像永动机一样持续创新。

  陆陆续续的,一些关于它的奇特管理方式流传到外界:所有新雇员能得到100美元装修自己的小格子;所有员工有20%的私人时间,做自己想做的创新;比如公司里有一张ideas mailing list,所有人都可以提供建议,或者用脚投票……这都只是增加了我们对它的好奇。

  最近一期Forbes有篇文章,叫Google thinks small,算是Google神话的最新诠释。文章不长,但很精彩,做些summary罢。

  文章开头就说,Google的CEO Eric Schmidt在2001年进入这公司的时候就发现,这里所有人都厌恶官僚制,喜欢把事儿放桌面上讨论明白:关于一个决策,所有人都会有备而来,在会上舌灿兰花。而当决策做出,没有人会更多废话。

  而且,这里的官方语言不是“我想……”,而是“数据说明……”。与我们熟知的多数商业大亨不同,Google的决策者们不相信本能,他们不会像George Soros一样在做出错误投资决策时后背疼,也不会像Alan Greenspan对自己的宏观调控策略不自信时胃酸。他们只相信数字:因为Google的产品都可以即时检测用户反应,所以也可以立即决定一条产品线的命运。一个项目有10%的认同,OK;有20%的认同,NB。失败的小组则立即解散,所有人进入其他小组。

  创意-成果(ideas-and-data),这就是Google的生存法则。

  这确保了公司的灵活性。Google同时进行着上百个项目,每个项目都只有极少人参与,比如Google旗下的交友网站Orkut只有3名全职员工,页面改版活科学调研则调用不过6个人,即使与Comcast合作收购AOL这样的大事件,也只有极少人参与。通常一个软件在6周内就能完成测试版。

  同时它提高了经理层的效率。我们通常所知道的管理常识是,一个有效的管理者应该管7个人,在Google,经理们可以管20人甚至40人,难怪李开复要招50名关门弟子。当然,经理们并不具备太多特权,除了极少人享用个人办公室,连李开复也要与另外两个人共用小格子。

  每周初,所有Google员工都要写下5行文字,记录下自己上周都做了什么,贴到内部论坛上。在这家公司里,不要轻易说哪个想法太傻,或者太大,相反Google愿意刺激员工思考,比如让大家畅想在太空建一200英里高的电梯。

  毫无疑问,确保这一切顺利运转的基础是:招聘最聪明的员工。其考题变态,比如:在常数e里找出第一个10位的质数(find the first ten-digit prime number in the mathematical constant called 'e')。通常一个人要经过8轮面试,那些表现出缺乏团队合作能力的人会剔除。

京ICP备05053527号
经过23次查询历时0.477秒终于生成了此页面
Powered by WordPress & Designed by Felix © 2012