1.3 客户/服务器模式与消息传递
无论是采用面向过程方法还是面向对象方法或其他方法,一个设计良好的程序在风格上具有某些类似性。例如,这些程序都是由模块组成的且具有清晰的流程控制。但是,采用面向对象方法且设计良好的程序因信息隐藏和封装机制而具有更加鲜明的特色。在本节中,我们介绍一些典型的面向对象编程(www.cppentry.com)模式。
1.3.1 客户/服务器模式
面向对象编程(www.cppentry.com)以客户/服务器模式为计算基础。该模式诠释了面向对象编程(www.cppentry.com)中的重点:信息隐藏。例如,C++(www.cppentry.com)标准程序库有一个string类(见2.5节),该类的公有接口有如下成员函数:创建string、销毁string、合并string、在string中查找字符等等。这个string类是一个字符串处理功能的提供者,我们称string类是有关string对象的服务器(string对象提供字符串处理服务),使用string类的C++(www.cppentry.com)程序称为客户。客户通过调用string对象的成员函数来请求服务,我们将这种调用称为向string对象发送了一个消息。例如,代码段
首先创建并初始化了string对象s1,然后向对象s1发送一个消息来请求获取字符串长度,即The Day the Music Died的字符个数。包含这段代码的程序就表现为对象s1的客户,而s1就是服务器。我们通过函数调用的方式向服务器(如s1)发送消息,这些函数都封装在服务器当中。
设计良好的服务器所提供的服务最大限度地降低客户端的工作量。特别是客户端不需要了解服务器是如何提供服务的。也就是说,服务器应该将其实现的细节隐藏起来,客户仅需知道服务器提供的接口即可。接口就是客户所能调用的那些函数,这些函数将消息发给服务器,这样,服务器就知道客户需要什么样的服务,服务器会返回一些数据给客户,或执行客户所需的任务等一些步骤。设计良好的服务器可利用信息隐藏使得客户易于使用。例如,为获取字符串的长度,客户仅需知道length方法。客户不必知道string对象是否把长度存放在返回值的封装变量中,或者是否每次调用length方法时都进行计算,即逐一查看字符数组中的字符,直到遇到结束符为止,或者是否使用其他长度计算方法。
信息隐藏也可以提高服务器的健壮性。例如,假设string类的接口中的成员函数均设计良好且经过完整测试,而这些接口的实现都是隐藏的,同时,我们已经对string类的这些成员函数m1,m2,……,mn进行了充分的测试,直到相信任何函数调用顺序都不会导致服务器出现异常。这样,由于客户仅能访问string类的公有接口,不能访问其私有的实现函数,我们就可以确信客户在访问string对象时不会“破坏”这样的对象。因此,string服务器的健壮性为使用这种服务器的程序的整体健壮性作出了明显的贡献。