实现模式之方法

      把一个逻辑分成许多方法,而不是全部揉成一团。这是为什么呢?也就是为什么要有方法?因为从理论上讲,只要通过各种跳转控制,可以把任何程序都组织成一段巨大的方法。这样做最大的问题是难以阅读,今后的阅读者很难找到自己关心的部分,另外代码无法重复利用,很多地方出现了相同的代码。

      把一个程序的逻辑分割成很多方法,相当于告诉别人“这些逻辑片断之间的联系不紧密”。在把方法归入类中,把类归入包中,就是进一步传递同样的信息。


      那么怎么把一个逻辑划分成方法?一般划分的时候需要考虑几个因素:大小,意图与方法命名。

      大小:不应该将逻辑划分得太细,因为那样思维的表达就过于琐碎,阅读者不容易理解。如果划分得太大,又会导致代码的重复,灵活性也会受到损失。

      意图:一般划分成不同的方法的时候,根据意图来划分,这一段代码是要干什么,那一段代码是要干什么。最好一个方法实现一个功能(这个功能是我们思维层面上的功能,要让阅读者很容易理解)

      方法命名:好的方法命名能够带来很好的沟通效果,阅读者不必去阅读方法中的具体代码就知道该方法的功能。

     

      各种实现模式:

 

      1. 组合方法

       组合方法是:通过对其他方法的调用来组合出新的方法,被调用方法应该大致属于相同的抽象层次。如果抽象层次混杂,那么预示着这是一个糟糕的方法。比如:

        void compute() {

          input();

          flags = 0x0080;

          output();

        }


       上面这段代码想当碍眼,第2句的抽象层次与第1,3句的抽象层次不同,我们读到第2句的时候就会问自己,这个赋值语句在耍什么花样,到底是什么意思?

      组合方法应该根据事实而非推测,先让代码运行起来,然后再决定该怎么安排它的结构。如果一开始就花很多时间考虑代码的结构,那么一旦在实现过程中发现了一些新东西,那么不得不推翻前面的结构重新来过。


      2. 揭示意图的名称

      给方法命名的时候,应该从潜在调用者的想法出发,根据调用者使用该方法的意图来给方法命名。你可能还想在方法中传达其他的信息,比如方法的实现策略。不过,最好只在名称中传达意图。

     实现策略是最常出现在方法名称中的细枝末节信息,比如:

      Customer.linearCustomerSearch(String id);  //线性搜索客户信息

     如果阅读者本来不关心你是怎么搜索客户信息的,只是需要知道哪个方法是搜索客户信息的方法,这个方法名命名就是有问题的。总之,一切从阅读者的角度出发。在给方法命名的时候,代码的作者不应该马上把方法的所有信息一股脑地倒出来,有时候需要保持克制是必要的。

      让我们遐想一下方法名在调用代码中的情境。阅读者可能是第一次遇到这个方法,为什么要调用这个方法而不是其他方法?这个就是方法名要回答的问题,调用代码是在讲叙一个故事,好的方法命名会让故事讲叙得更流畅。


      3. 方法对象

      当遇到一个方法里面的代码逻辑纠缠不清,像是硬塞到一起的。那么方法对象能帮助你将它整理成可读的,清晰的,逐层向阅读者揭示其细节的代码。

      假设一个方面很长,又有很多参数,并且用了很多临时变量。如果直接用提取其中一部分的方法来重构,提取出来的部分会很难命名,而且参数也很多。这时候应该考虑方法对象模式。(也就是新建一个类来取代这个方法的功能)步骤如下:

     a. 用方法的名称作为类名。比如complexCalculation()变成ComplexCalculator.

     b. 在新类中为每一个参数,局部变量和方法中用到的字段一一建立新字段,字段名称相同。

     c. 建立一个构造器,参数包括原方法的参数以及方法中用到的原对象的字段。

     d. 将原方法复制到新类中的calculate()方法。旧方法中用到的参数,局部变量和字段都变成新对象的字段引用。

     e. 将原方法的方法体替换成创建一个新类的实例并调用calculate()方法。如下所示:

     complexCalculation() {

       new ComplexCalculator().calculate();

     }

     接下来的事情就简单了,现在在类中将这个大方法,分割成很多逻辑相对独立的小方法。在分割的过程中,会发现有些变量可以从字段降级成局部变量。而有些变量可以单独传递给某一个方法,其他地方都没用到,因此没必要为它保留一个字段。随着一个个方法被提取出来,你会发现代码的逻辑变得清晰多了。


      4. 方法注释

     对于不能在代码中表达清楚的信息,需要增加注释。

     但是对于沟通良好的代码来说,很多注释完全是多余的。编写这些注释,以及维护注释与代码一致性的代价,远高于它们带来的价值。归根结底,沟通仍然是所有实现模式的首要价值。如果方法注释是最合适的沟通媒介,那么就写一个好注释吧。


      5. 助手方法

      助手方法是组合方法的衍生产物。(也就是一个大方法,把一些不关心的细节封装成助手方法)要想将大方法分割成若干个小方法,就少不了助手方法。助手方法的目的是通过暂时隐藏目前不关心的细节,让你通过方法的名称来传达意图,从而令大尺度的运算更具有可读性。助手方法一般声明为private,如果打算子类进行微调,可以上升为protected。

      如果助手方法使得逻辑变得不清晰,应暂时去掉助手方法。将所有的助手方法展开到代码中,换一个角度去观察方法的逻辑,重新提取有意义的方法。


        未完待续...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值