第四章:设计问题之可扩展性
天下维客,你可以修改的网络知识库
[编辑]
继承
封装定义了代码段周围的边界。所有面向对象编程语言都提供了一种机制,以扩展代码段而不破坏这些边界。在 Java 语言中,这个机制由继承提供。
[编辑]
通过继承定制
示例库中的主类称作 Server。如果查看这个类的源代码,就会发现这个类本身什么功能也没有。
主循环(在单独线程中运行)侦听入网连接。当进入一个连接时,它就将这个连接转交给一个称作 handleConnection() 的方法,如下所示:
// subclass must supply an implementation abstract public void handleConnection( Socket s );
由于没有缺省实现,因此这个类被声明成 abstract,这表示用户应提供实现。EchoServer 实现了这个方法:
// This is called by the Server class when a connection
// comes in. "in" and "out" come from the incoming socket
// connection
public void handleConnection( Socket socket ) {
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
// just copy the input to the output
while (true)
out.write( in.read() );
} catch( IOException ie ) {
System.out.println( ie );
}
}
可以将这个过程看作是一种定制:完成大部分工作的类 (Server) 还不完整;子类 (EchoServer) 通过添加方法 handleConnection() 的实现来完善它。
[编辑]
考虑特殊情况
应该事先考虑库的用户想要执行的定制类型。前一个示例很明显 -- 必须提供一种方法以使子类能够真正使用入网连接,否则程序不产生任何作用。
但如果没有事先考虑,那么其它一些定制可能不提供给您。相反,这些定制将提供给用户,用户希望您会事先考虑到这些情况。
在样本库中,Server 中有一个方法叫作 cleanUp()。这个方法由服务器的后台线程在退出之前调用。基本服务器不需要在这个方法中执行任何操作,因此它是空的:
// Put any last-minute clean-up stuff in here
protected void cleanUp() {
}
注:不要将这个方法声明成 abstract,因为这会要求用户实现此方法,而在某些情况下,没有必要这样做。


