Fork me on GitHub

编程技巧总结(实践中总结的个人认为比较好的方法论)

 一、关于函数参数问题。

当写一个提供功能很灵活的函数的时候其接收的参数必然要很多(因为各种参数都可以由调用者灵活设定),一个比较常用的解决方案是设定一个封装类,把要传入的参数封装到这个对象中然后传入,比如:

 1 /**
 2  * 点工具
 3  * @author CC11001100
 4  *
 5  */
 6 public class PointUtils{
 7     
 8     /**
 9      * 计算两点的距离
10      */
11     public static double getDistance(double x1,double x2,double y1,double y2){
12         return Math.sqrt(Math.pow(x1-y1,2)+Math.pow(x2-y2,2));
13     }
14     
15 }

很明显这不符合面向对象的思想,我们应该把(x1,y1) (x2,y2)封装为对象再传入,比如封装一个类表示点:

 1 /**
 2  * 平面上的一个点
 3  * @author CC11001100
 4  *
 5  */
 6 public class Point {
 7 
 8     private double x;
 9     private double y;
10     
11     public Point(double x, double y) {
12         this.x = x;
13         this.y = y;
14     }
15 
16     public double getX() {
17         return x;
18     }
19     
20     public void setX(double x) {
21         this.x = x;
22     }
23     
24     public double getY() {
25         return y;
26     }
27     
28     public void setY(double y) {
29         this.y = y;
30     }
31 }

  然后修改(注意并不一定是改进哦,凡事无绝对)之前的工具类:

 1 /**
 2  * 点工具
 3  * @author CC11001100
 4  *
 5  */
 6 public class PointUtils{
 7     
 8     /**
 9      * 计算两点的距离
10      */
11     public static double getDistance(Point p1,Point p2){
12         return Math.sqrt(Math.pow(p1.getX()-p2.getX(),2)+Math.pow(p1.getY()-p2.getY(),2));
13     }
14     
15 }

 这个时候再调用就感觉比较爽了:

 1 public class Main_022 {
 2 
 3     public static void main(String[] args) {
 4         
 5         double ans=PointUtils.getDistance(new Point(1,1),new Point(2,2));
 6         System.out.println(ans);
 7         
 8     }
 9 
10 }

 一般情况都可以这么处理,总结一下规律:

当形参的个数很多的时候,我们就应该考虑如何精简了,这个时候就将形参列表中可以分为一组的参数提取出来封装为一个类,然后通过这个类来传递参数。

 我猜这个《重构》中肯定会有,虽然我买了从来没看完,准确的说是因为能理解的部分太少了于是就看不下去了...... :(

 也悟出了一个道理:日常生产中会有非常多的技巧,非常多的看起来很酷很炫的方法论,前人都将它们总结好了放在书中了,但是很多东西,如果没有经历过类似相应情景的时候是很难理解它的。知行合一讲的大概就是这么个道理吧。

记忆-->理解-->创造 大概是这么个过程。

但是呢,凡事都有两面性。换种思路分析一下这种方法的弊端:
调用者必须要去花费额外的成本去了解提供的封装类,因为点是我们很熟悉的概念所以比较容易理解,如果是一个很复杂很抽象并且很有可能是程序编写者自个儿创造的概念的话(别跟我说你没这么干过...),再使用这个接口的学习成本就会大大提高,调用者必须要深入细节。

 

 如果不封装呢,比如我之前写过的一个图像工具类:

public static void draw9patchImage(BufferedImage panel,BufferedImage ninePatchImage,int patchRectSize,int panelRectSize,int x,int y,int width,int height)

  其实最后四个形参是比较通用的概念应该封装为对象再传入的,可是我就是不想,然后在调用的时候就比较痛苦了:

//绘制数据库边框
ImageUtils.draw9patchImage(buffer,border,7,7,30,30,230,280);

 最后的那些数字简直看花眼有木有啊,然后我就发明了一种方法....(看来cnblog的代码识别度并不是特别好嘛...)

//绘制数据库边框
ImageUtils.draw9patchImage(buffer,border,7,7,/**/30,30,/**/230,280);

 万一耳鼻编写者写出了类似的接口,我们调用的时候的一个小技巧就是可以用注释给实参分组

这样子的话一眼就可以看出实参的哪一部分是用来干嘛的,不至于再看花眼了。

 

当然应该尽量设计让人用着舒服用着爽的接口啦   :)

 

总结一下:

形参:对象分组,提取可以分为一组的参数封装为对象。

实参:注释分组,借助注释实现类似分组的功能来管理。

 

后注:当参数实在太多的时候就该考虑使用Builder设计模式了。 

参考资料:设计模式之构建者模式(Builder)

 

posted @ 2016-09-25 00:45  CC11001100  阅读(1312)  评论(0编辑  收藏  举报