精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (6)
|
|
---|---|
作者 | 正文 |
发表时间:2010-05-17
在《类的设计基础知识》文章中提到, 方法作为 命名的控制类或者对象的有状态或无状态的执行模块,可称作类或者对象的“行为”。 方法在类中的地位相当重要,利用面向对象的多态性能够设计更为优雅的结构,同时巧妙地使用继承能够更好地减少冗余,因此其设计是重重之重。方 法的设计实践会按照下列的议程安排:
一、 名称和注释设计
方法名称好比人的姓名,父母在给自己子女起名的时候,在字面上,尽量不想重复,同时在意义上,面体现了 父母的美好希望。好的名称不仅容易让人记住,同时会想起其特征。方法也是如此。
在面向对象设计中,对于API 方法来说,说明它的语义和体现的行为。那么,设计人员应该遵循方法的设计原则: 输入和输出,以及异常触发应该是规约的和可控制的,也就说方法说体现的行为或者履行的职责应该是有限的 。凡是任意暴露(从结构上)和职责(从逻辑上)模糊或者歧义,皆视作低内聚- 高耦合设计。
那么,规约方法行为和科学的名称是必要,也是重要的。
1. 注释即规约 在TDD 中,有句名言是“实现未动,测试先行”。那么设计中,则是“实现未动,规约先行”。也就说,在实现和命名方法的之前,应该好好设计下这个方法 的语义规约,即它要表达的语义和行为是什么。也叫做 契约编程 。良好的单一性规约,是 高内聚- 低耦合 的前提。
在实现方法之前,一般的设计人员更多地关注与功能性需求,而非功能性需求更多地由架构师考虑。显然,良 好的设计是需要全面考虑到的。下面总结了一些通用的规约,这也是后续文章重点介绍的。 功能性需求的规约:
非 功能性需求的规约:
当了解这些规约之后,那么剩下就是怎么体现到设计中。代码实现是利用编程语言,而规约表述是自然语言, 自然地,在编程语言中,大多数是利用注释来表达。Java 同样如此,不过可利用 Javadoc 来生成 API 文档。
当客户端使用方法之前,它可以通过注释来了解方法规约,更好地增加了方法的可用性。
在方法实现之前,给方法添加注释,固然是一种很好的方法。当受制于时间的情况下,采用一种“命名即注 释”的方法更佳。接下来接受方法命名。
2. 名称即语义 前面提到“命名即注释”的方法,通过命名就知道方法的意图,一般用于方法实现相对简单的情 况,比如在Java Bean 中, Setter 和 Getter 方法就是一种体现。设计时,可以利用这种方法提高方法的易用性和可读性。
Java的 API 中,提供了很多命名模式的参考,其命名一般可以归纳为几类: a) 动词 以动词命名方法,比如: i. 对象状态比较 java.lang.Object#equals(java.lang.Object), java.lang.String#contains(java.lang. CharSequence), java.util.Collection<E>#contains(E), java.util.Comparator<T>#compare(T,T)
ii. 状态改变的 java.lang.Collection<E>#clear(), java.io.Closeable#close(), java.lang.String#intern(), java.lang.String#trim();
b) 动词- 名词 i. 状态转化 java.lang.Integer#parseInt(java.lang.String) , java.lang.String#getBytes(), javax.jms.Session#createMessage()
ii. 条件判断 java.util.Iterator<E>#hasNext(), java.lang.Class#isInterface(), java.lang.String#isEmpty(), java.lang.Thread# holdsLock (java.lang.Object)
iii. 状态改变 java.lang.Thread#setContextClassLoader(java.lang.ClassLoader), javax.Servlet.http.HttpSession#removeAttribute(java.lang.String)
iv. 通讯传输 javax.mail.Transport#sendMessage(javax.mail.Message,javax.mail.Address[])
c) 动词- 介词 i. 对象状态比较 java.lang.Comparable<E>#compareTo(E)
ii. 抽象实现 java.util.Formattable#formatTo(java.util.Formatter,int,int)
d) 动词- 介词 - 名词 e) 名词 i. 状态转化 java.util.Map<K,V>#values(), java.util.Collection<E>#iterator(), java.lang.Number#longValue(), java.util.Collections#singletonMap(K,V)
ii. 用户状态表示 java.lang.String#length(), java.lang.Object#hashCode(), java.util.Collection#size()
f) 名词- 动词过去式 i. 事件回调
java.awt.ActionListener#actionPerformed(java.awt.ActionEvent), javax.servlet.ServletContextListener# contextInitialized javax.servlet.ServletContextEvent)
g) 介词- 名词 以介词- 名词组合的方法, i. 状态转换 java.lang.Object#toString(), java.lang.String#toLowerCase(), java.util.Collections#asList(T...)
ii. 事件回调 javax.jms.MessageListener#onMessage(javax.jms.Message)
h) 形容词- 名词 i. 对象创建
javax.xml.parsers.DocumentBuilderFactory#newDocumentBuilder()
ii. 状态转换
java.util.Collections#synchronizedList(java.util.List<E>), java.util.Collections#unmodifiableList(java.util.List<? extends E>)
iii. 状态表示。 java.util.concurrent.BlockingQueue#remainingCapacity()
通过归纳的这些命名模式,相信能够给方法命名带来些灵感。
(待续) 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-05-18
LZ归纳的这些命名模式够细的,平时还真没注意过
不过确实 有时在命名时 我会琢磨半天。。 |
|
返回顶楼 | |
发表时间:2010-05-18
whaosoft 写道 LZ归纳的这些命名模式够细的,平时还真没注意过
不过确实 有时在命名时 我会琢磨半天。。 好的方法命名不容易,尤其是言简意赅。 |
|
返回顶楼 | |
发表时间:2010-05-18
最后修改:2010-05-18
看了LZ的归纳,发现自己写的命名完全不够规范。。
比如说 java.lang.Integer#parseInt(java.lang.String) 我就会命名为getInteger |
|
返回顶楼 | |
发表时间:2010-05-18
很不错,深有感触
|
|
返回顶楼 | |
发表时间:2010-05-18
#这个符号,是新的java7里的吗???
具体干什么用的能说下吗? |
|
返回顶楼 | |
发表时间:2010-05-18
最后修改:2010-05-18
zhao103804 写道 看了LZ的归纳,发现自己写的命名完全不够规范。。
比如说 java.lang.Integer#parseInt(java.lang.String) 我就会命名为getInteger 返回类型超出预期。 coffeesweet 写道 #这个符号,是新的java7里的吗???
具体干什么用的能说下吗? 类名#方法名 javadoc可以识别的语法 |
|
返回顶楼 | |
发表时间:2010-05-18
看了LZ的帖子,觉得在命名方法名上是该花点功夫。
|
|
返回顶楼 | |
发表时间:2010-05-18
coffeesweet 写道 #这个符号,是新的java7里的吗???
具体干什么用的能说下吗? 这是Javadoc里面的方法识别符号, 比如可以这么些 {@link java.lang.Object#toString}这样就可以连接到java.lang.Object#toString()方法。 |
|
返回顶楼 | |
发表时间:2010-05-18
zhao103804 写道 看了LZ的归纳,发现自己写的命名完全不够规范。。
比如说 java.lang.Integer#parseInt(java.lang.String) 我就会命名为getInteger 返回值不同,如果要返回Integer类型的话,还是要使用java.lang.Integer#valueOf(java.lang.String); 看方法命名就知道parseInt会return int类型。 |
|
返回顶楼 | |