方法在分门别类的放在不同类中,类再放置于包中,这样就方便我们去阅读代码。当然方法还有一个重要的用途就是解决了代码的重用问题。
分割方法时,基本原则就是应该放在一起的放在一起,应该分割的片段分割开。呵呵,是不是觉得很废话呢?不过事实确实如此。Kent给出了他认为划分方法时需要考虑的几个因素:大小、意图和方法命名。代码分了太多很小的方法容易导致意图表达不明确,但太大的话容易导致代码重复,缺失了灵活性。在《对象健身操》一文中,作者提出了一个比较极端的要求就是一个方法不能超过5行,大家可以根据自己实际情况来判别自己的方法大小,但是我觉得如果不是特别需要,不要超过一屏。最后要说的是一定要有一个好的名字,多翻翻字典什么也是有必要的,这个无论是Kent、Martin还是Uncle Bob都是很认可的,并都在他们的书中做出了要求。
组合方法(Composed Method)
通过对其他方法的调用来组合出新的方法。被调用的方法大致属于相同的抽象层次。小的方法体读起来更轻松一些。
组合方法时应当根据事实而非推测。先让代码工作,然后再决定该怎么安排它的结构。
揭示意图的名称(Intension-Revealing Method)
在名称上反映方法打算做什么事。如果一个方面不能起一个非常恰当的名字,那么有可能你的方法不满足SRP,这个要注意。
方法可见性( Method Visibility)
尽可能降低方法的公开程度。选择可见性要注意两个方面:1、未来的灵活性;2、调用对象的代价。
方法对象( Method Object)
把复杂的方法变成对象。
覆盖方法(Overriden Method)
通过覆盖一个方法来表达特殊化。
重载方法(Overloaded Method)
为同样的计算提供不同的接口。
方法返回类型( Method Return Type)
在可以表达意图的基础上,尽可能声明一个泛化的返回类型。
方法注释( Method Comment)
通过方法注释来传达不容易从代码中读出的信息。但是在应用程序,我们尽可能的通过测试来解释代码意图,因为TDD下,测试与代码是一致的,而我们大多数人很少会尽心的维护注释。只在不得不用的时候再写注释。
助手方法(Helper Method)
增加小的、私有的方法来使计算的主体部分表达的更简明。助手方法的目的是通过暂时隐藏目前不关心的细节,让你得以通过方法的名字来表达意图,从而令大尺度的运算更具可读性。
调试输出方法(Debug Print Method)
用toString()输出有用的调试信息。
转换(Conversion)
清晰的表达一个类型的对象到另一个类型的转换。
转换方法(Conversion Method)
对于简单的、有限的转化,在源对象中提供一个方法,让它返回转换后的对象。
在转换方法中,源对象需要和目标对象耦合在一起,但是如果本来没有关系的两者仅仅只是由于转换才关联在一起,那就没有什么必要了。
转换构造器(Conversion Constructor)
对于大多数转换,在目标对象的类中提供一个方法,让它接受一个源对象作为参数。
创建(Creation)
清晰表达对象的创建。
完整的构造器(Complete Constructor)
编写一个构造器,让它返回完全塑造好的对象。它告诉读者运行这个类必须要有那些参数,要比无参构造器+set方法更能表达意图。
工厂方法(Factory Method)
将较复杂的创建表达成类中的一个静态方法,而非构造器。只有我们在创建对象时,不仅仅单纯的创建,还要进行其他动作才需要用到工厂方法,否则用构造器就可以了。
内部工厂(Internal Method)
将需要进一步解释或者日后需要调整的对象创建封装进一个助手方法。我们建立一个方法并返回一个对象,常见的延迟初始化就是一个内部工厂的例子:
private T getT(){
if(t == null)
t = new T();
return t;
}
容器访问器方法(Collection Accessor Method)
为容器的限制性访问提供方法。不需要把整个容器展现给别人,那样一方面不容易表达我们使用容器的意图,另一方面容器中的状态很容易在不知情的情况下被人修改,这绝对是一个灾难。
当然,如果我们要返回一个容器的Iterator时要注意,Iterator是支持remove操作的。
布尔值Setting方法(Boolean Setting Method)
如果有助于沟通,为布尔值的两种状态分别提供一个设置方法。
查询方法(Query Method)
通过名为asXXX的方法返回布尔值。
有时候一个对象需要根据另一个对象的状态来决定,这种依赖关系并不好,不过万一确实需要时,我们应该在相应的方法名称上加上‘be’、‘have’、’is‘等。
当然如果一个对象有很多逻辑都需要另一个对象的状态,那么我们就需要考虑是不是逻辑犯错地方了。
相等性判断方法(Equality Method)
同时定义equals()和hashCode().
Getting方法(Getting Method)
在特殊情况下提供对一个字段的访问,用一个方法返回该字段。当然在写一个getting之前要注意是不是真的需要,根据“数据应该和逻辑在一起”的原则,getting是不是意味着逻辑在其他地方呢?是不是需要调整数据或是逻辑的位置呢?
Setting方法(Setting Method)
在更罕见的情况下提供一个设置字段的方法。settting容易暴露程序的内部结构,使用前一定要多加注意。
安全副本(Safe Copy)
对传入或传出访问器方法的对象进行复制,避免混淆。