I l @ ve RuBoard |
Inheritance is a defining property of object-oriented design techniques and programming languages [Mey97]. Although experience shows that deep inheritance hierarchies can be unwieldy [GHJV95], there are benefits of using inheritance judiciously to model software abstractions in a hierarchical manner, as described below. A.4.1 Replace One-Dimensional APIs with HierarchiesProblem: The complexity of the Socket API stems in part from its overly broad and one-dimensional design [Mar64]. For instance, all the functions appear at a single level of abstraction, as shown in Figure A.1. This one-dimensional design increases the effort needed to learn and use the Socket API correctly. To write a networked application, for example, programmers must understand most of the Socket API, even if they use only part of it. Moreover, functionality is decentralized, which duplicates code. Figure A.1. Functions in the Socket API
Solution Replace one-dimensional APIs with hierarchies to maximize reuse and code sharing. This principle involves using hierarchically related classes to restructure existing one-dimensional APIs. For instance, the ACE Socket wrapper facades were designed by clustering the Socket API functions shown in Figure A.1 into a hierarchy of classes shown in Figure 3.1 on page 47. Inheritance increases code reuse and improves modularity in ACE as follows :
A.4.2 Replace Pseudo-Inheritance with C++ InheritanceProblem: Many C-level system programming APIs are error-prone due to insufficient hierarchical abstraction. For example, the Socket API network addressing mechanisms use C structures and typecasts , which provide an awkward form of "inheritance" for Internet-domain and UNIX-domain addresses. The most general socket addressing structure is sockaddr , which defines a pseudo "base class" for defining address information. Its first field indicates the desired address family and its second field is a quasi- opaque byte array. Specific address family structures then define addressing information by overlaying the byte array. This pseudo-inheritance design yields many subtle bugs , as described in Section 2.3.1 and Section 3.2. In particular, the use of typecasts ”combined with the weakly typed handle-based Socket API ”makes it hard for compilers to detect programmer mistakes at compile time. Solution Replace pseudo-inheritance with C++ inheritance. Rather than forcing application developers to wrestle with casts and type overlays, this principle leverages object-oriented programming language features in C++. For example, ACE defines the ACE_Addr class hierarchy described in Section 3.2 to provide type-safe wrapper facades for diverse network addressing formats, such as the Internet- and UNIX-domain addresses, STREAM pipes, files, and devices shown in Figure A.2. Each subclass hides address family-specific details behind a common API. Figure A.2. The ACE IPC Addressing Hierarchy
|
I l @ ve RuBoard |