隨筆 - 50  文章 - 0  trackbacks - 0
          <2008年3月>
          2425262728291
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          常用鏈接

          留言簿(1)

          隨筆檔案

          文章檔案

          相冊

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜


          網站: JavaEye  作者: justjavac  鏈接:http://justjavac.javaeye.com/blog/170076  發表時間: 2008年03月11日

          聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!

          你,一個DotNet程序員,剛剛加入一個新項目組。除了你之外,其他的成員包括:Ceer,一直從事C項目的程序員,他剛剛轉入C#不到一個月; Jally,整天抱著本Design Pattern(沒錯,就是GoF的那本)在啃的前Java程序員;以及Semon,你對他完全不了解,只是聽PM介紹說他是搞Scheme的(傳說中的第二古老的語言LISP的方言之一)。不過你也沒在意,畢竟計算機這玩意,老東西是不吃香的。

            周一,剛打開電腦,老板就跑到你們組的辦公座面前:“好吧,伙計們,現在有個function需要你們來搞定。具體是這樣的:用戶輸入2個數,并輸入一個操作符。你根據輸入的情況來得出相應的運算結果。“

          Example: Foo(+, 1, 2) = 3; Foo(*, 3, 6) = 18; Foo(/, 2, 4) = 0.5


            Ceer最先作出反應:簡單嘛,判斷一下輸入的操作符就好了。說著,他很快在白板上寫出如下代碼:

           

          public class CStyle_Calculator
          {
           static public double Foo(char op, double x, double y)
           {
            switch(op)
             case ’+’: return x + y; break;
             case ’-’: return x - y; break;
             case ’*’: return x * y; break;
             case ’/’: return x / y; break;
             default: throw new Exception(”What the Hell you have input?");
           }
          }
           
            Jally只看了一遍,就捂著鼻子連連搖頭:好一股的代碼臭味。還不如看我用OO的方法來解決:

          public interface I操作符 //誰說代碼不能寫中文的?恩恩
          {
           double 運算(double x, double y);
          }
          
          public class OO_Calculator
          {
           private I操作符 m_op;
           public OO_Calculator(I操作符 op)
           {
            this.m_op = op; //依賴注入【注2】
           }
          
           public double Foo(double x, double y)
           {
            return this.m_op.運算(x, y);
           }
          }
          
          public class 加法:I操作符
          {
           public double 運算(double x, double y)
           {
            return x + y;
           }
          }
          
          public class 減法:I操作符
          {
           public double 運算(double x, double y)
           {
            return x - y;
           }
          }
          
          public class 乘法:I操作符
          {
           public double 運算(double x, double y)
           {
            return x * y;
           }
          }
          
          public class 除法:I操作符
          {
           public double 運算(double x, double y)
           {
            return x / y;
           }
          }
          
          public class TheMainClass
          {
           static public void Main()
           {
            I操作符 我的加法 = new 加法();
            OO_Calculator 我的加法器 = new OO_Calculator(我的加法);
            double sum = 我的加法器.Foo(3, 4);
            System.Console.WriteLine(sum);
            //sum = 7
          
            //其他3個我就不廢話了
           }
          } 
           
            你看著Jally把白板寫得密密麻麻之后,聳聳肩,暗嘆,你們這些用java的廢柴,就一個運算器還搞出Interface這些東西,煩不煩啊。 讓你們見識見識DotNet的強大吧. 那個運算符我直接用delegate傳進去不就好了么.

          public delegate double TheOperator(double x, double y);
          
          public class Operators
          {
           static public double Add(double x, double y)
           {
            return x + y;
           }
          
           static public double Sub(double x, double y)
           {
            return x - y;
           }
          
           //乘,除法 我也懶得廢話了
          }
          
          public class DotNet_Calculator
          {
           public double Foo(TheOperator op, double x, double y)
           {
            return op(x, y);
           }
          }
          
          public class TheMainClass
          {
           static public void Main()
           {
            TheOperator myAdd = new TheOperator(Operators.Add);
            TheOperator mySub = new TheOperator(Operators.Sub);
          
            DotNet_Calculator dc = new DotNet_Calculator();
            double sum = dc.Foo(myAdd, 2, 4); //sum = 6
            System.Console.WriteLine(sum);
            double sub = dc.Foo(mySub, 3, 7); //sub = -4
            System.Console.WriteLine(sub);
           }
          }
           
          //dot net 下面還可以用CodeDom動態構造C#代碼,然后在內存編譯運行。
          //如果覺得專門寫個Operators很煩的話,可以試試C#2.0的匿名方法

            很好,當你寫完代碼之后,挑釁的看著Jally,Ceer卻開始抱怨起來:”這不就是C里面的函數指針么,我也會...“

            “然則DotNet下面的Delegate是類型安全滴...”你繼續洋洋得意.

            而Semon,看了看你們3位華麗的代碼,啥也沒說,只是在鍵盤上敲下了2行代碼

          (define (Foo op x y)
          (op x y)) 
           
            然后就下班了...

            【注: scheme的代碼稍微解釋下:(+ 1 2) = 3, (* 3 4) = 12.】

            至于Semon的解法:

          (define (Foo op x y)
          (op x y)) 
           
            看明白了么,上面的代碼只有一個作用:第一行是函數頭,定義了一個叫Foo的函數。該函數接受3個參數op, x, y。

            第二行定義了函數的行為:把第一個參數op當作運算符,計算后面2個參數。

            所以:(Foo + 1 2) = 3. (Foo / 12 6) = 2.

            好了好了,不編故事了。

            我只是想簡單的讓大家在繁忙的工作之余,也瞅瞅Function Programming(函數編程)世界的美妙。函數編程,最大的特點是它是將函數作為語言里1st class的元素來對待的。一個函數可以接受另一個函數作為參數,也可以把一個函數作為結果來返回。這樣的函數我們稱為Higher-order function。

            那么,Function Programming和我們傳統的面向對象有啥區別捏? 恩,這個嘛,扯得遠可以扯到圖靈機和馮·諾以曼這2種體系的差異...@_@不過那個太學術性,俺就不說了。不過有句話可以較好的概括FP和OO的區別(好吧,這個也是抄“紫皮書”上面的):
           
            “Pascal是為了建造金字塔...Lisp是為了建造有機體...”“作為Lisp的內在數據結構,表對于這種可用性起著重要的提升作用...”“采用100函數在一個數據結構上操作,遠遠優于采用10個操作在十個數據結構上工作”“金字塔矗立在那里千年不變,而有機體則必須演化,否則就會消亡”。

            而另一個總結得比較好的話是:(同樣是抄來的)

            一個對象:一組相同的運算上面,外加不同的數據。(想想你的object,是不是這樣的?)

            一個Closure:一組相同的數據,外加不同的操作。(Delegate就是這樣的思想,有興趣的話也可以去看看Ruby)

            基本上,恩,沒啥說的了。 如果你感興趣的話,可以去看MIT SICP的課程(有在線版的,MIT也作為Open Course開設了的) 
          本文的討論也很精彩,瀏覽討論>>


          JavaEye推薦
          中國領先的電子商務網站-淘寶網招賢納士,誠聘Java工程師



          文章來源:http://justjavac.javaeye.com/blog/170076
          posted on 2008-03-15 10:04 justjavac(迷渡) 閱讀(87) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 泽州县| 米脂县| 普宁市| 北票市| 鹿泉市| 禄丰县| 安新县| 涞源县| 牙克石市| 东港市| 东阿县| 余庆县| 双城市| 扎兰屯市| 兴安县| 汉中市| 成都市| 余庆县| 仁化县| 灵山县| 庆元县| 伊通| 东兰县| 福鼎市| 金秀| 汝南县| 察哈| 弥渡县| 五原县| 英吉沙县| 延津县| 定州市| 梓潼县| 乌苏市| 滁州市| 巨野县| 禹城市| 遂平县| 聊城市| 奉化市| 辰溪县|