3.5.2 决定公开的接口
当设计类的时候,其他程序员如何与您的对象交互是一个问题。在C++(www.cppentry.com)中,类的属性以及行为可以是公有的(public)、保护的(protected)以及私有的(private)。将属性或者行为设置为public意味着其他代码可以访问它们。protected意味着其他代码不能访问这个属性或者行为,但是子类可以访问。private是最严格的控制,意味着不仅其他代码不能访问这个属性或者行为,子类也不能访问。
设计公开的接口就是选择哪些接口应该成为public。当与其他程序员一起完成一个大项目时,应该将设计公开接口作为一个步骤。
1. 考虑用户
设计公开接口的第一步是考虑为谁设计。用户是团队中的其他成员吗?这个接口只是您个人使用吗?公司外面的程序员会使用接口吗?是某个用户还是国外的承包商?除了判断谁会用到接口之外,还应该注意您的设计目标。
如果接口供自己使用,那么设计起来会更加灵活,为了适合您的需要可以改变它。然而,应该记住团队中角色会改变,很有可能在某一天其他人也会用这个接口。
设计供其他程序员使用的接口有一点不同之处。在某种意义上,接口变成了您与他们之间的契约。例如,如果您实现程序的数据存储组件,其他人依靠这个接口支持某些操作。您应该找出团队中其他成员需要您的类完成的所有工作。他们需要版本控制吗?可以存储什么类型的数据?作为契约,您应该把接口看成是几乎不可改变的。如果在开始编码之前就接口达成了一致,而您在开始编码之后改变了接口,就会听到许多抱怨声。
如果用户是外部客户,对设计有不同的要求。理想情况下,目标客户会参与指定接口公开的功能。您应该同时考虑用户需要的特定功能以及他们在将来可能会要求的功能。接口中使用的术语必须是客户熟悉的,并且必须为这些客户编写文档。设计中不应该出现内部的笑话、代号以及程序员的俚语。
2. 考虑目的
编写接口有很多理由。在编写代码之前,甚至在决定公开的功能之前,必须理解接口的目的。
应用程序编程(www.cppentry.com)接口(API)
API是一种外部可见机制,用于在其他环境中扩展产品或者使用其功能。如果说内部的接口是契约,那么API更接近于刻在石头上的法律。一旦用户开始使用您的API,哪怕他们不是您所在公司的员工,他们也不希望API改变,除非是加入帮助他们的新功能。在交给用户使用之前,应该关心API的设计并与用户进行商谈。
设计API时主要考虑使用的难度以及灵活性。由于接口的目标用户并不熟悉产品内部的运行方式,因此学习使用API是一个逐步的过程。毕竟,公司向用户公开这些API的目的是想让用户使用API。如果使用难度太大,API就是失败的。灵活性经常与此对立,您的产品可能有许多不同的用途,您想让用户使用提供的所有功能。然而,如果一个API让用户做您产品可做的任何事,会过于复杂。
正如编程(www.cppentry.com)格言所说的那样"好的API使得容易的情况变得更容易,艰难的情况变得可能"。也就是说,API应该容易被使用。大多数程序员想要做的事情就是访问。然而,API应该允许更高级的用法,因此在少见的复杂情况以及常见的简单情况之间的折中是可以接受的。
工具类或者库
通常,您的任务是设计某些特定的功能供应用程序中的其他部分使用,可能是一个随机数库或者一个日志类。在此情况下比较容易确定接口,因为您倾向于公开大多数或者全部功能,理想情况不应该给出与实现有关的内容。通用性是需要考虑的重要问题,由于类或者库是通用的,因此在设计中应该考虑设置用例。
子系统接口
您可能设计程序中两个主要子系统之间的接口,例如访问数据库的机制。在此情况下,将接口与实现分离异常重要,其他程序员可能会在您的实现完成之前依靠您的接口编写他们的实现。当所做的事情与子系统相关时,首先考虑子系统的主要目的是什么。一旦定义了子系统的主要任务,就可以考虑子系统具体的用法以及如何将它展示给代码的其他部分。试着从他人的角度考虑问题,而不要陷入实现的细节。
组件接口
您定义的大多数组件接口可能都小于子系统接口或者API,组件是您在其他代码中会用到的对象。在这些情况下,当接口逐渐增大并且变得难以控制时就可能会出现问题。哪怕这些接口是供您自己使用的,也要当成不是。与子系统接口类似,此时应该考虑每个类的主要目的,并且不要公开对这个目的没有贡献的功能。
考虑将来
在设计接口的时候,应该考虑将来的需求。您会在这个设计上花费数年的时间么?如果是这样,您可能需要使用插件架构,从而留出扩展空间。您能够确定人们使用接口的目的与当初设计的目的相同么?与他们交流,更好地理解他们的使用情况。否则以后就要重写接口,或者更糟糕的是,以后可能需要不时地添加新的功能从而使接口变得凌乱不堪。要小心!推测性的通用是另一个陷阱。如果将来的用途不明,不要设计包含一切的日志类,因为这样做会不必要地将设计、实现以及公有接口复杂化。