引言:
我们在设计系统接口时,经常会遇到这样的问题:
1、我们的接口应该提供多少方法才合适?
2、我们的接口应该提供"原子方法"还是"复合方法"?
3、我们的接口是否应该封装(或者,能否封装)所有的细节?
接口的设计需要考虑用户的使用习惯、使用的方便程度、使用...
摘要:
写ejb和rmi的存根类,和其他为了虚拟机正常运行的类通常是很烦人和单调的。一旦宿主类改动了,你除了不得不写这些代码外,还需要修改存根代码。xdoclet提供了一个很好的办法。
xdoclet和ant集成起来,通过ant的自定义标签运行在编译时。你可以和ant其他任务一样使用这些标签。
要使用xdoclet,你就要在代码里面加上自定义的javadoc的标签。xdocl......
摘要:
jvm在运行时会产生三个classloader,bootstrap classloader、extension classloader和appclassloader.其中,bootstrap是用c++编写的,我们在java中看不到它,是null。它用来加载核心类库,在jvm源代码中这样写道:
static const char classpathformat[] =
"%/lib/......
设计合适的接口
我们在设计系统接口时,经常会遇到这样的问题:
1.我们的接口应该提供多少方法才合适?
2.我们的接口应该提供"原子方法"还是"复合方法"?
3.我们的接口是否应该封装(或者,能否封装)所有的细节?
接口的设计需要考虑用户的使用习惯.使用的方便程度.使用的安全程度,根据我的编程经验,下面会详细讨论接口设计的2个需要权衡的方面:接口的单一化 & 复合化.
接口
接口提供了不同系统之间或者系统不同组件之间的界定.在软件中,接口提供了一个屏障,从而从实现中分离目标,从具体中分离抽象,从作者中分离用户.
站在用户的角度看,一个接口建立并命名了一个目标对象的使用方法.一些约束(例如:编译时的类型系统.运行时的异常机制及返回值)使得类作者的目的得以体现与加强.供给(affordances)指事物的被感知的真实的属性,这些属性可以决定事物使用的可能方法,供给提供了对事物操作的线索.
类设计者的一个职责便是在接口中减小约束与供给之间的隔阂.匹配目标以及一定程度上的自由度,尽可能减小错误使用目标对象的可能.
封装
对于封装来说,远不止数据私有那么简单.在设计中,封装往往会涉及到自我包含(self-containment).如果一个类需要你知道如何调用它方法(e.g. 在一个线程的环境中,在一个方法调用后调用另一个方法,你必须明确地同步对象),那么它的封装性就不如将所有这些全部包含并隐藏的类(e.g. 这个类是thread-safe的)好.前一个设计存在着设计的漏洞,它的许多限定条件是模糊的,而且把部分责任推给了用户,而不是让类提供者做这些工作来完成类的设计.
在空间或者时间上分离方法的执行(例如,线程,远程方法调用,消息队列),能够对设计的正确性与效率产生意义深远的影响.这种分离带来的结果是不可忽视的:
并发引入了不确定性与环境(context)选择的开销;
分布引入了回调的开销,这些开销可能不断增加,而且会导致错误.
这些是设计的问题,修改它们可不是象修改bug那样简单.
如果一个接口主要由存取方法(set与get方法)组成,每个方法都相应的直接指向某个私有域,那么它的封装性会很差.接口中的域存取方法通常是不会提供信息的:他们在对象的使用中不能通讯.简单化与抽象化,这通常会导致代码冗长,并且容易出错.
所以,我们首先考虑接口设计的第一个原则:
命令与查询分离(command-query separation)
要求:保证一个方法不是命令(command)就是查询(query)
定义:
查询:当一个方法返回一个值来回应一个问题的时候,它就具有查询的性质;
命令:当一个方法要改变对象的状态的时候,它就具有命令的性质;
通常,一个方法可能是纯的command模式或者是纯的query模式,或者是两者的混合体.在设计接口时,如果可能,应该尽量使接口单一化,保证方法的行为严格的是命令或者是查询,这样查询方法不会改变对象的状态,没有副作用(side effects),而会改变对象的状态的方法不可能有返回值....
下一页 摘要:
摘要:
过去很多年里面,许多的java开发人员都一直在问一个问题:“一个java对象到底耗费多少内存呢?”在本文中,vladimir roubtsov用以前的解决方案来解释了这个问题,在此之外,基于他的经验演示了内存的使用,并且还提供了一些技巧来让你的java程序更加高效。
作者:vladimir roubtsov
近来,我们帮助开发了一个java服务器,这......