This article discusses the problem of constructing robust class libraries. Further design criteria include the flexibility of class libraries, the efficiency of the implementations, and their safe extensibility. We show that it is possible to design robust libraries to satisfy any two of the requirements at the same time. Although the solution may require an exponential growth in the number of classes compared to the original design, this apparent class explosion can be controlled by generating only the necessary additional classes automatically. As an application demonstrating both the theoretical problems and the power of our generator approach, the design of a library modelling data structures and algorithms for graphs is considered. Both the discussion and the results in this article generalize to other domains.
A. FRICK ET AL.with components a 1 , . . . , a n where a i contains a value of type T i if T i is a basic type, and a reference to an object of type T i otherwise. The state of an object o comprises the values and references of its components, together with the states of the referenced objects. If x : T is an attribute and T is a type with attribute y : T , then x.y denotes the reference or value denoted by the y-attribute of T of the object referenced by x. This notation is extended inductively in the straightforward way. The operation #A creates a new object and returns a reference to it. The equality of objects is based on their reference, i.e. on object identities. However, sometimes structural equality is used. This notion is based on the fact that objects can be viewed as vertices of a directed graph and references as edges (e.g. see Schmidt and Zimmermann [9,10]). Two objects are structurally equal iff their directed graphs are isomorphic.The interface of a method declares the signature with its parameters. m(x 1 : T 1 , . . . , x k : T k ) : T denotes a method m with signature m : T 1 × · · · × T k → T , where parameter x i is a variable of type T i , i = 1, . . . , k. T = VOID iff m is a procedure. Methods may have an implementation in a particular programming language. In our case, we also consider methods without implementations. These methods are called abstract. An abstract class is a class that contains abstract methods. Classes without abstract methods are called implementation classes. In our article, abstract classes are denoted by the keyword abstract.In our examples, we use the language SATHER-K [11] for implementing methods. We just use the usual control structures of while-loops, for-loops, and conditionals with their usual semantics ‡ . The lhs := rhs operator denotes an assignment. It means that if lhs is an object of a basic type, then the value denoted by rhs will be the content of lhs. Otherwise, rhs denotes a reference to an object which is copied to lhs. Within the implementation of a function, res denotes the value/reference to be returned.