每个人都应该懂点函数式编程 2015-08-27 11:47by 周见智 目录
Ø 一个问题假设现在我们需要开发一个绘制数学函数平面图像(一元)的工具库,可以提供绘制各种函数图形的功能,比如直线f(x)=ax+b、抛物线f(x)=ax2+bx+c或者三角函数f(x)=asinx+b等等。那么怎么设计公开接口呢?由于每种行数的系数(a、b、c等)不同,并且函数构造也不同。正常情况下我们很难提供一个统一的接口。所以会出现类似下面这样的公开方法: 复制代码 //绘制直线函数图像 public voidDrawLine(double a, double b) { List<PointF> points = newList<PointF>(); for(double x=-10;x<=10;x=x+0.1) { PointF p =new PointF(x,a*x+b); points.Add(p); } //将points点连接起来 } //绘制抛物线图像 public voidDrawParabola(double a, double b, double c) { List<PointF> points = newList<PointF>(); for(double x=-10;x<=10;x=x+0.1) { PointF p =new PointF(x,a*Math.Pow(x,2)+ b*x + c); points.Add(p); } //将points点连接起来 } ... DrawLine(3, 4); //绘制直线 DrawParabola(1, 2,3); //绘制抛物线 复制代码 如果像上面这种方式着手的话,绘制N种不同函数就需要定义N个接口。很明显不可能这样去做。 (注,如果采用虚方法的方式,要绘制N种不同函数图像就需要定义N个类,每个类中都需要重写生成points的算法) 如果我们换一种方式去思考,既然是给函数绘制图像,为什么要将它们的系数作为参数传递而不直接将函数作为参数传给接口呢?是的,没错,要绘制什么函数图像,那么我们直接将该函数作为参数传递给接口。由于C#中委托就是对方法(函数,这里姑且不讨论两者的区别)的一个封装,那么C#中使用委托实现如下:
|