按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
RMI 只是一种创建特殊对象的方式,它创建的对象可通过网络发布。它最大的优点就是提供了一种“纯
Java ”方案,但假如已经有许多用其他语言编写的代码,则RMI 可能无法满足我们的要求。目前,两种最具
竞争力的替选方案是微软的D (根据微软的计划,它最终会移植到除Windows 以外的其他平台)以及
CORBA。CORBA 自Java 1。1 便开始支持,是一种全新设计的概念,面向跨平台应用。在由 Orfali 和 Harkey
编著的《Client/Server Programming with Java and CORBA》一书中(John Wiley&Sons 1997 年出版),
大家可获得对Java 中的分布式对象的全面介绍(该书似乎对 CORBA 似乎有些偏见)。为CORBA 赋予一个较公
正的对待的一本书是由 Andreas Vogel 和Keith Duddy 编写的《Java Programming with CORBA》,John
Wiley&Sons 于 1997 年出版。
15。9 总结
由于篇幅所限,还有其他许多涉及连网的概念没有介绍给大家。Java 也为 URL 提供了相当全面的支持,包括
为因特网上不同类型的客户提供协议控制器等等。
除此以外,一种正在逐步流行的技术叫作Servlet Server。它是一种因特网服务器应用,通过Java 控制客
户请求,而非使用以前那种速度很慢、且相当麻烦的CGI (通用网关接口)协议。这意味着为了在服务器那
一端提供服务,我们可以用Java 编程,不必使用自己不熟悉的其他语言。由于 Java 具有优秀的移植能力,
所以不必关心具体容纳这个服务器是什么平台。
所有这些以及其他特性都在《Java Network Progr amming》一书中得到了详细讲述。该书由 Elliotte Rusty
Harold 编著,O'Reilly 于 1997 年出版。
15。10 练习
(1) 编译和运行本章中的JabberServer 和 JabberClient 程序。接着编辑一下程序,删去为输入和输出设计
的所有缓冲机制,然后再次编译和运行,观察一下结果。
(2) 创建一个服务器,用它请求用户输入密码,然后打开一个文件,并将文件通过网络连接传送出去。创建
一个同该服务器连接的客户,为其分配适当的密码,然后捕获和保存文件。在自己的机器上用 localhost
(通过调用InetAddress。getByName(null)生成本地 IP地址 127。0。0。1)测试这两个程序。
(3) 修改练习2 中的程序,令其用多线程机制对多个客户进行控制。
(4) 修改JabberClient,禁止输出刷新,并观察结果。
(5) 以ShowHTML。java 为基础,创建一个程序片,令其成为对自己Web 站点的特定部分进行密码保护的大
586
…………………………………………………………Page 588……………………………………………………………
门。
(6) (可能有些难度)创建一对客户/服务器程序,利用数据报(Datagram )将一个文件从一台机器传到另
一台(参见本章数据报小节末尾的叙述)。
(7) (可能有些难度)对VLookup。java 程序作一番修改,使我们能点击得到的结果名字,然后程序会自动取
得那个名字,并把它复制到剪贴板(以便我们方便地粘贴到自己的E…mail )。可能要回过头去研究一下IO
数据流的那一章,回忆该如何使用 Java 1。1 剪贴板。
587
…………………………………………………………Page 589……………………………………………………………
第 16 章 设计范式
本章要向大家介绍重要但却并不是那么传统的“范式”(Pattern)程序设计方法。
在向面向对象程序设计的演化过程中,或许最重要的一步就是“设计范式”(Design Pattern)的问世。它
在由Gamma,Helm 和 Johnson 编著的《Design Patterns》一书中被定义成一个“里程碑”(该书由
Addison…Wesley 于 1995 年出版,注释①)。那本书列出了解决这个问题的 23 种不同的方法。在本章中,我
们准备伴随几个例子揭示出设计范式的基本概念。这或许能激起您阅读《Design Pattern》一书的欲望。事
实上,那本书现在已成为几乎所有 OOP 程序员都必备的参考书。
①:但警告大家:书中的例子是用 C++写的。
本章的后一部分包含了展示设计进化过程的一个例子,首先是比较原始的方案,经过逐渐发展和改进,慢慢
成为更符合逻辑、更为恰当的设计。该程序(仿真垃圾分类)一直都在进化,可将这种进化作为自己设计方
案的一个原型——先为特定的问题提出一个适当的方案,再逐步改善,使其成为解决那类问题一种最灵活的
方案。16。1 范式的概念
在最开始,可将范式想象成一种特别聪明、能够自我适应的手法,它可以解决特定类型的问题。也就是说,
它类似一些需要全面认识某个问题的人。在了解了问题的方方面面以后,最后提出一套最通用、最灵活的解
决方案。具体问题或许是以前见到并解决过的。然而,从前的方案也许并不是最完善的,大家会看到它如何
在一个范式里具体表达出来。
尽管我们称之为“设计范式”,但它们实际上并不局限于设计领域。思考“范式”时,应脱离传统意义上分
析、设计以及实施的思考方式。相反,“范式”是在一个程序里具体表达一套完整的思想,所以它有时可能
出现在分析阶段或者高级设计阶段。这一点是非常有趣的,因为范式具有以代码形式直接实现的形式,所以
可能不希望它在低级设计或者具体实施以前显露出来(而且事实上,除非真正进入那些阶段,否则一般意识
不到自己需要一个范式来解决问题)。
范式的基本概念亦可看成是程序设计的基本概念:添加一层新的抽象!只要我们抽象了某些东西,就相当于
隔离了特定的细节。而且这后面最引人注目的动机就是“将保持不变的东西身上发生的变化孤立出来”。这
样做的另一个原因是一旦发现程序的某部分由于这样或那样的原因可能发生变化,我们一般都想防止那些改
变在代码内部繁衍出其他变化。这样做不仅可以降低代码的维护代价,也更便于我们理解(结果同样是降低
开销)。
为设计出功能强大且易于维护的应用项目,通常最困难的部分就是找出我称之为“领头变化”的东西。这意
味着需要找出造成系统改变的最重要的东西,或者换一个角度,找出付出代价最高、开销最大的那一部分。
一旦发现了“领头变化”,就可以为自己定下一个焦点,围绕它展开自己的设计。
所以设计范式的最终目标就是将代码中变化的内容隔离开。如果从这个角度观察,就会发现本书实际已采用
了一些设计范式。举个例子来说,继承可以想象成一种设计范式(类似一个由编译器实现的)。在都拥有同
样接口(即保持不变的东西)的对象内部,它允许我们表达行为上的差异(即发生变化的东西)。合成亦可
想象成一种范式,因为它允许我们修改——动态或静态——用于实现类的对象,所以也能修改类的运作方
式。
在《Design Patterns》一书中,大家还能看到另一种范式:“继承器”(即Iterator,Java 1。0 和 1。1 不
负责任地把它叫作Enumeration,即“枚举”;Java1。2 的集合则改回了“继承器”的称呼)。当我们在集合
里遍历,逐个选择不同的元素时,继承器可将集合的实施细节有效地隐藏起来。利用继承器,可以编写出通
用的代码,以便对一个序列里的所有元素采取某种操作,同时不必关心这个序列是如何构建的。这样一来,
我们的通用代码即可伴随任何能产生继承器的集合使用。
16。1。1 单子
或许最简单的设计范式就是“单子”(Singleton),它能提供对象的一个(而且只有一个)实例。单子在
Java 库中得到了应用,但下面这个例子显得更直接一些: