四个程序员的一天

楼主
四个程序员的一天
[P]四个程序员的一天[/P][P]你,一个DotNet程序员,刚刚加入一个新项目组。除了你之外,其他的成员包括:Ceer,一直从事C项目的程序员,他刚刚转入C#不到一个月; Jally,整天抱着本Design Pattern(没错,就是GoF的那本)在啃的前Java程序员;以及Semon,你对他完全不了解,只是听PM介绍说他是搞Scheme的(传说中的第二古老的语言LISP的方言之一)。不过你也没在意,毕竟计算机这玩意,老东西是不吃香的。[/P][P]周一,刚打开电脑,老板就跑到你们组的办公座面前:“好吧,伙计[IMG=0,absmiddle,1,1]http://justjavac.iteye.com/blog/1685559[/IMG]们,现在有个function需要你们来搞定。具体是这样的:用户输入2个数,并输入一个操作符。你根据输入的情况来得出相应的运算结果。“[/P][P][/P][P][P][P][b][plain][/b] [/P][/P][ol][li]Example: Foo(+, 1, 2) = 3; Foo(*, 3, 6) = 18; Foo(/, 2, 4) = 0.5    [/li][/ol][/P][P][/P][P]Ceer最先作出反应:简单嘛,判断一下输入的操作符就好了。说着,他很快在白板上写出如下代码: [/P][P][/P][P][P][P][b][java][/b] [/P][/P][ol][li]public class CStyle_Calculator    [/li][li]{    [/li][li] static public double Foo(char op, double x, double y)    [/li][li] {    [/li][li]  switch(op)    [/li][li]   case ’+’: return x + y; break;    [/li][li]   case ’-’: return x - y; break;    [/li][li]   case ’*’: return x * y; break;    [/li][li]   case ’/’: return x / y; break;    [/li][li]   default: throw new Exception(”What the Hell you have input?");    [/li][li] }    [/li][li]}    [/li][/ol][/P][P][/P][P]Jally只看了一遍,就捂着鼻子连连摇头:好一股的代码臭味。还不如看我用OO的方法来解决:[/P][P][/P][P][P][P][b][java][/b] [/P][/P][ol][li]public interface I操作符 //谁说代码不能写中文的?恩恩     [/li][li]{    [/li][li] double 运算(double x, double y);    [/li][li]}    [/li][li]public class OO_Calculator    [/li][li]{    [/li][li] private I操作符 m_op;    [/li][li] public OO_Calculator(I操作符 op)    [/li][li] {    [/li][li]  this.m_op = op; //依赖注入【注2】     [/li][li] }    [/li][li]    [/li][li] public double Foo(double x, double y)    [/li][li] {    [/li][li]  return this.m_op.运算(x, y);    [/li][li] }    [/li][li]}    [/li][li]    [/li][li]public class 加法:I操作符    [/li][li]{    [/li][li] public double 运算(double x, double y)    [/li][li] {    [/li][li]  return x + y;    [/li][li] }    [/li][li]}    [/li][li]    [/li][li]public class 减法:I操作符    [/li][li]{    [/li][li] public double 运算(double x, double y)    [/li][li] {    [/li][li]  return x - y;    [/li][li] }    [/li][li]}    [/li][li]    [/li][li]public class 乘法:I操作符    [/li][li]{    [/li][li] public double 运算(double x, double y)    [/li][li] {    [/li][li]  return x * y;    [/li][li] }    [/li][li]}    [/li][li]    [/li][li]public class 除法:I操作符    [/li][li]{    [/li][li] public double 运算(double x, double y)    [/li][li] {    [/li][li]  return x / y;    [/li][li] }    [/li][li]}    [/li][li]    [/li][li]public class TheMainClass    [/li][li]{    [/li][li] static public void Main()    [/li][li] {    [/li][li]  I操作符 我的加法 = new 加法();    [/li][li]  OO_Calculator 我的加法器 = new OO_Calculator(我的加法);    [/li][li]  double sum = 我的加法器.Foo(3, 4);    [/li][li]  System.Console.WriteLine(sum);    [/li][li]  //sum = 7     [/li][li]    [/li][li]  //其他3个我就不废话了     [/li][li] }    [/li][li]}  [/li][/ol][/P][P]你看着Jally把白板写得密密麻麻之后,耸耸肩,暗叹,你们这些用java的废柴,就一个运算器还搞出Interface这些东西,烦不烦啊。 让你们见识见识DotNet的强大吧. 那个运算符我直接用delegate传进去不就好了么.[IMG=0,absmiddle,1,1]http://justjavac.iteye.com/blog/1685559[/IMG][/P][P][P][P][b][csharp][/b] [/P][/P][ol][li]public delegate double TheOperator(double x, double y);    [/li][li]    [/li][li]public class Operators    [/li][li]{    [/li][li] static public double Add(double x, double y)    [/li][li] {    [/li][li]  return x + y;    [/li][li] }    [/li][li]    [/li][li] static public double Sub(double x, double y)    [/li][li] {    [/li][li]  return x - y;    [/li][li] }    [/li][li]    [/li][li] //乘,除法 我也懒得废话了     [/li][li]}    [/li][li]    [/li][li]public class DotNet_Calculator    [/li][li]{    [/li][li] public double Foo(TheOperator op, double x, double y)    [/li][li] {    [/li][li]  return op(x, y);    [/li][li] }    [/li][li]}    [/li][li]    [/li][li]public class TheMainClass    [/li][li]{    [/li][li] static public void Main()    [/li][li] {    [/li][li]  TheOperator myAdd = new TheOperator(Operators.Add);    [/li][li]  TheOperator mySub = new TheOperator(Operators.Sub);    [/li][li]    [/li][li]  DotNet_Calculator dc = new DotNet_Calculator();    [/li][li]  double sum = dc.Foo(myAdd, 2, 4); //sum = 6     [/li][li]  System.Console.WriteLine(sum);    [/li][li]  double sub = dc.Foo(mySub, 3, 7); //sub = -4     [/li][li]  System.Console.WriteLine(sub);    [/li][li] }    [/li][li]}    [/li][/ol][/P][P]//dot net 下面还可以用CodeDom动态构造C#代码,然后在内存编译运行。[/P][P]//如果觉得专门写个Operators很烦的话,可以试试C#2.0的匿名方法 [/P][P]很好,当你写完代码之后,挑衅的看着Jally,Ceer却开始抱怨起来:”这不就是C里面的函数指针么,我也会...“[/P][P]“然则DotNet下面的Delegate是类型安全滴...”你继续洋洋得意./[/P][P][/P][P]而Semon,看了看你们3位华丽的代码,啥也没说,只是在键盘上敲下了2行代码[/P][P][/P][P][P][P][b][plain][/b] [/P][/P][ol][li](define (Foo op x y)    [/li][li](op x y))  [/li][/ol][/P][P][/P][P]然后就下班了...[/P][P]【注: scheme的代码稍微解释下:(+ 1 2) = 3, (* 3 4) = 12.】[/P][P]至于Semon的解法:[/P][P][/P][P][P][P][b][plain][/b] [/P][/P][ol][li](define (Foo op x y)    [/li][li](op x y))    [/li][/ol][/P][P][/P][P]看明白了么,上面的代码只有一个作用:第一行是函数头,定义了一个叫Foo的函数。该函数接受3个参数op, x, y。[/P][P]第二行定义了函数的行为:把第一个参数op当作运算符,计算后面2个参数。[/P][P]所以:(Foo + 1 2) = 3. (Foo / 12 6) = 2.[/P][P]好了好了,不编故事了。[/P][P]我只是想简单的让大家在繁忙的工作之余,也瞅瞅Function Programming(函数编程)世界的美妙。函数编程,最大的特点是它是将函数作为语言里1st class的元素来对待的。一个函数可以接受另一个函数作为参数,也可以把一个函数作为结果来返回。这样的函数我们称为Higher-order function。[/P][P]那么,Function Programming和我们传统的面向对象有啥区别捏? 恩,这个嘛,扯得远可以扯到图灵机和冯·诺以曼这2种体系的差异...@_@不过那个太学术性,俺就不说了,有时间在『[COLOR=rgb(51, 51, 255)]代码之谜[/COLOR]』系列文章里面科普吧。不过有句话可以较好的概括FP和OO的区别(好吧,这个也是抄“紫皮书”上面的):[/P][P]“Pascal是为了建造金字塔...Lisp是为了建造有机体...”“作为Lisp的内在数据结构,表对于这种可用性起着重要的提升作用...”“采用100函数在一个数据结构上操作,远远优于采用10个操作在十个数据结构上工作”“金字塔矗立在那里千年不变,而有机体则必须演化,否则就会消亡”。[/P][P]而另一个总结得比较好的话是:(同样是抄来的)[/P][P]一个对象:一组相同的运算上面,外加不同的数据。(想想你的object,是不是这样的?)[/P][P]一个Closure:一组相同的数据,外加不同的操作。(Delegate就是这样的思想,有兴趣的话也可以去看看Ruby)[/P][P]基本上,恩,没啥说的了。 如果你感兴趣的话,可以去看MIT SICP的课程(有在线版的,MIT也作为Open Course开设了的) [/P]
1楼
感觉好厉害的样子呢

电脑版 Page created in 0.0693 seconds with 4 queries.