Tool Support for Design by Contract - CiteSeerX

3 downloads 27903 Views 594KB Size Report
Contact: Manager, Copyrights and Permissions/IEEE Service Center/445 Hoes ... object-oriented analysis, but that the notation of contracts in conjunction with ..... debugger for DBC that intercepts any method call and thus allows the DBC ...
JOHANNES KEPLER UNIVERSITÄT LINZ INSTITUT FÜR WIRTSCHAFTSINFORMATIK CD-LABOR FÜR SOFTWARE ENGINEERING O. UNIV.-PROF. DR. G. POMBERGER

Software Engineering

R. Plösch

Tool Support for Design by Contract Copyright Copyright 1998 IEEE. Published in the Proceedings of the TOOLS-26 Conference, August 1998, Santa Barbara, U.S.A, IEEE Computer Society Press, pp 282-294. Personal use of this material is permitted. However, permission to reprint/republish this material for advertising or promotional purposes or for creating new collective works for resale or redistribution to servers or lists, or to reuse any copyrighted component of this work in other works, must be obtained from the IEEE. Contact: Manager, Copyrights and Permissions/IEEE Service Center/445 Hoes Lane/P.O. Box 1331/Piscataway, NJ08855- 1331, USA. Telephone: + Intl. 908-562-3966.

TR-SE-98.09

Tool Support for Design by Contract Reinhold Plösch C. Doppler Laboratory for Software Engineering Johannes Kepler University of Linz Altenbergerstr. 69, A-4040 Linz, Austria [email protected] Abstract Numerous experience reports indicate that prototyping is a serious and successful development strategy. We believe that it is not sufficient to provide graphical notations for object-oriented analysis, but that the notation of contracts in conjunction with prototyping, i.e., building executable models, is the proper technique for mastering complexity and gaining insights into a problem domain. We therefore developed a set of tools that is especially suitable for functional prototyping and for architectural prototyping. The underlying prototyping model is based on objectorientation and assertions. The infrastructure tools are implemented with the object-oriented programming language Python, while the high-level tools (assertion browser and graphically oriented debugger for assertions) are implemented in C++. The two parts of the system are tightly connected by means of the API provided by Python. Although the tool support provided covers the core tasks for functional prototyping and for architecture prototyping, additional support for evolutionary software development and for higher level techniques for requirements elicitation, e.g., for scenario oriented (use case oriented) analysis is desired.

1: Motivation Prototyping is a development approach to overcome the shortcomings of traditional software life cycle approaches by developing executable prototypes for experimental purposes (see Figure 1). The emphasis of this prototyping-oriented life cycle is on the two planned iterations in the analysis and design phase (user interface prototyping, architecture and component prototyping). A number of available experience reports ([12], [11], [7], [30]), illustrate the impact of prototyping on software construction and on the overall development process. Bäumer et al. [2] summarize the experience gained in the application of prototyping in industrial projects. Although they draw very positive conclusions, the emphasis of their analysis and experience reports is on user interface prototyping. Currently established object-oriented development approaches consider prototyping to be an important methodology, but deal with it superficially. Booch [5], Rumbaugh [28] and Jacobson [17] mention prototyping but fail to provide precise advice on how to use it in the context of object-oriented development.

Requirements analysis

Requirements analysis, project contract, coarse schedule

Requirements definition User-interface prototyping

Requirements definition, project schedule, system prototype

Design Architecture and component prototyping

System architecture, architecture prototype

Implementation

System implementation

System test

Product

Operation and maintenance

Figure 1: Prototyping-oriented software life cycle [4]

We do not discuss different definitions of the terms prototype and prototyping in much detail as this is beyond the scope of this paper. For details see, e.g., Bischofberger and Pomberger [4] or Pomberger and Blaschek [25]. It is widely accepted in the research community, that a prototype is a working model of a system. The essential difference between a prototype and a model produced with objectoriented methods like OMT is expressed by the word “working”. A prototype is therefore always a usable model implemented on a computer. It is also commonly accepted that the later users have to be involved in the validation of the prototype; i.e., user participation is of vital importance. Furthermore we believe that introducing formalisms is essential to ensure the quality of requirements specifications. This is also explicitly addressed by Bowen and Hinchey [6]. One essential problem with formal methods is the fact that they contradict the idea of quickly building prototypes with user participation, as formal methods tend to be rigid and need a sound understanding of the underlying mathematical concepts. We therefore implemented Design by Contract (DBC) for the programming language Python [20], a dynamically typed, object-oriented, interpreted programming language (see Ploesch [24] for more details). The emphasis of this work was to provide reasonable support throughout prototyping-oriented software development. We see the main benefits of a DBC solution with Python within the two proposed iterations as depicted in Figure 1. We believe that the proposed combination of an object-oriented, dynamically typed, interpreted programming language (which facilitates the construction of prototypes) with a more formal approach like DBC is a perfect fusion of informality and formalism in the first phases of the software life cycle. This is especially due to the fact that the concepts of DBC are easily and quickly understood. Second, in prototyping-oriented development, an interpretable and lean language far outperforms a statically typed programming language like Eiffel during analysis and early design. This makes our DBC-Python approach especially valuable for prototyping-oriented development, no matter whether the DBC technique is used during requirements elicitation and specification or in the design phase, where the emphasis is on evaluating different design approaches. Nevertheless, support only on the level of the programming language is not sufficient, especially in the first phases of software development. We therefore developed a set of tools to facilitate the construction and understanding of assertions.

Section 2 briefly describes our DBC model for Python to explain the need for tool support. Section 3 describes the provided tool support in depth. The final section draws some conclusions on the benefits of the provided tools as related to the prototyping-oriented software life cycle described in this section.

2: DBC for Python We describe our DBC model for Python only as far as it is relevant for understanding our need for appropriate tool support. DBC was introduced in the programming language Eiffel [23], based on ideas by Dijkstra [9], Hoare [15] and some others. The original literature (see Meyer [23], [22]) and our previously published work on this subject [24] serve as basis for clarifying certain aspects of the theory. At the end of this section we will briefly discuss related and enhanced concepts 2.1: DBC elements Preconditions/postconditions: In our Python model every method has its associated documentation. The basic idea of our Python DBC model is to specify preconditions and postconditions in the documentation section of a method. Preconditions and postconditions are checked according to the theory of DBC. Figure 2a shows a method SetProperties of class Person. def SetProperties(self, age, ssn): ””” param: IntType, IntType; old.age: self.age; req: age > 0; req: self.age > 0 and self.age < 100; ensure: self.old.age == self.age - 1; ensure: if age > 65: self.pensioner == 1; ””” self.age= age self.ssn= ssn

Figure 2a: Preconditions, postconditions

class Person(LivingThing): ””” inv: self.age >= 0; inv: self.age < 100; inv: len(self.name) > 0; inv: self.socialSecurityNumber > 1000; ””” def __init__(self, a, n, ssn): ””” type: age: IntType, name: StringType, socialSecurityNumber: IntType; ””” self.age= a self.name= n self.socialSecurityNumber= ssn Figure 2b: Invariants

There may be an arbitrary number of req: and ensure: clauses but only one param: clause per method. The param: assertion is a feature beyond standard DBC concepts. The param: clause describes the type of parameters (not including the first parameter self) in the order of their occurrence. The param: clause leads to a run-time type check of the parameters. Type checking is possible not only for Python built-in types but for arbitrary class types. This addition and its methodical use leads to more comprehensible Python code and is a mechanism for improving correctness of the developed software. No special keywords (like require else and ensure else in Eiffel) are necessary for overridden methods. The preconditions of the overridden method are automatically or-ed with the original preconditions, and the postconditions of the overridden method are automatically

and-ed with the original postconditions. This rule is valid not only for direct ancestors of a class but for the entire inheritance path. Although Python supports multiple inheritance, inheritance of preconditions and postconditions is restricted to single inheritance. We impose this limitation for the following reasons: •



We do not want to encourage the use of multiple inheritance, as Python supports implementation inheritance only, which is often difficult to understand [29], especially in the analysis and early design stage. In addition, multiple inheritance can be reproduced by means of single inheritance and by use of the Adapter-Pattern [10]. The model for solving name conflicts is poorly developed in Python. If an attribute is defined in more than one place in the hierarchy, Python takes the closest and leftmost version from the perspective of the object qualified [20]), which makes understanding multiple inheritance architectures even harder.

As shown in Figure 2a, the specification of old expressions is possible. The right side of the old expression (self.age in our case) may consist not only of elementary data types but of arbitrary class types. In the latter case, a deep copy of the object is created at method entry. Boolean implications can be simulated by writing if statements in req: or ensure: clauses (see ensure: if age>100: self.pensioner == 1 in Figure 2a). Class invariants: In Python every class has its associated documentation, as does every method. The basic idea is to specify class invariants in the documentation section of a class. Class invariants are checked according to the theory. Figure 2b shows class Person, a subclass of LivingThing. Figure 2b shows the invariants of a class Person, defining a number of consistency conditions on every object of class Person. Method __init__, which semantically is comparable to C++ constructor operations, shows an example of a type: clause. The type: clause provides a mechanism for describing the types of instance variables of a class. What we already stated for the param: clause is also valid for the type: clause. The only difference is that the type: clause is treated like a class invariant; i.e., the types of instance variables are always checked before and after invocation of a method. Check instructions: Check instructions can be placed anywhere in method implementations. A check instruction may contain one boolean expression. Figure 3 shows an example of method SetAge in class Person, which is a subclass of class LivingThing. This particular check instruction in the example could be replaced by a precondition, which would have slightly different semantics, as the preconditions of the base class LivingThing would have to be checked on program execution, too. class Person(LivingThing): … def SetAge(self, age): self.Check(“age > 10 and age < 100”) Figure 3: Python check instructions

Loop invariants: Loop invariants are currently not considered in our DBC model for Python, as they are a lower level kind of specification compared to invariants, preconditions and

postconditions and check instructions. In this context we point out again that our emphasis is not on correct software but on providing mechanisms to combine formal approaches with object-oriented technology in the first phases of the software life cycle. For this purpose we do not consider loop invariants to be essential. 2.2: Related and enhanced concepts Eiffel: The programming language Eiffel and the implementation by ISE is the only commercial object-oriented language with full support for invariants, preconditions and postconditions. Although the syntax of Python DBC differs from the Eiffel syntax, the semantics is close to the Eiffel semantics. As already mentioned, we currently do not support loop invariants. Furthermore, Python DBC allows specification of type attributes for parameters and for instance variables. This feature complements Python, as Python supports dynamic type checking only. Naturally, this support is not necessary in a statically typed programming language like Eiffel. The emphasis here is not to introduce some kind of static typing but to enhance understandability and readability by using type information. Contracts: As defined by Helm [14], contracts are a technique for specifying the obligations of participating objects. Essentially, a contract is intended to formalize the collaboration and behavioral relationships between objects. A contract therefore defines communicating participants and their contractual obligations. The contractual obligations not only comprise traditional type signatures but also capture behavioral dependencies. An additional feature is to specify a sequence of messages that have to be sent (in the exact order of their specification) in the body of a method (Helm and Holland [14], [16] describe this aspect). We could easily provide syntax and run-time support for such a feature, but we are currently not convinced that this is an appropriate mechanism during analysis and early design stages. Larch/C++: This behavioral specification language [19] allows the specification of the behavior of a C++ program. The underlying mathematical model is closely related to concepts of Z [31]. Due to the underlying programming language and due to the underlying formal semantics, this approach is interesting for ensuring correctness of C++ implementations, but it is not suitable for a prototyping-oriented approach. Temporal system properties: Temporal perspectives as described by Arapis [1] and Manna and Pnueli [21] allow the specification of the temporal ordering of state transitions in general and thus also the temporal ordering of sequences of messages; this clarifies of course the execution semantics, i.e., the behavior of objects. In principal such support could be integrated with our approach, but we are currently not convinced that this is an appropriate approach during analysis and early design.

3: Tool support In this section we describe the tool support currently available. The main emphasis of our DBC support for Python is not related to building bug-free software but on capturing parts of requirements in the form of assertions. Especially with the emphasis on using this technique for requirements elicitation and documentation as well as in the design phase (architecture prototyping), there is a need for interactive tools that allow easy inspection and editing of assertions and inherited assertions.

In general, we differentiate between tools necessary for providing the infrastructure and tools for performing analysis and prototyping tasks. Figure 4 gives an overview of the tools currently available. Debugger Browser JIT Parser

Parser

DBC Checker

DBC Runtime Extension Python Programming Language and Runtime System

Figure 4: Currently available tools

The parser, JIT parser, DBC checker and the DBC run-time extension form the infrastructure tools necessary for parsing the assertion statements from the documentation sections of the Python source code and for checking them properly at run-time. The tiling structure of Figure 4 indicates, that, e.g., the DBC checker is based both on the parser and on the DBC run-time extension. The browser and the debugger, suitable during requirements specifications or in the design phase (for architectural prototyping), form the analysis tools and also provide a graphical user interface to ease the use of the tools. Whereas the browser relies on the information provided by the parser only, the debugger additionally needs the DBC checker for checking the assertions at run-time. In the following sections we describe the infrastructure tools and in more detail the analysis tools. 3.1: Infrastructure tools Parser: We provide support for traditional parsing and for just-in-time (JIT) parsing. Both parsing techniques heavily rely on the reflective capabilities of Python. This means that not the source code of files is parsed, but the meta-information provided by the run-time system. This approach is applicable, as the necessary meta-information (e.g., class/base class relationships, methods of a class, documentation of a class or method) is available at run time. This availability reduces the parsing effort substantially, as parsing is based on prestructured symbol information. In case of the JIT parser, a class is always parsed in case of an import. This allows changing the assertions of a class and applying these changes to a running system. To implement this approach elegantly, interception of the class loading mechanism is necessary to be able to parse the meta-information without having to change the code to be parsed. Whether a class has already been parsed and whether DBC support should be provided by a class is checked at loading time. A configuration file controls the parsing activities, i.e., whether a class has to be parsed. If a class has to be parsed (according to the configuration file), all its base classes are parsed, too. The traditional parser takes a configuration file (describing the classes to parse) as input and generates persistent symbol information. Naturally the persistent symbol information comprises not only names of classes, base classes, methods, etc., but also the assertions related to a symbol. The analysis tools described in section 3.2 build upon this information. DBC checker: The basic idea of our execution model is to extend the debugger framework provided by Python. The DBC run-time extension (see Figure 4) is therefore a special

debugger for DBC that intercepts any method call and thus allows the DBC checker to perform the run-time checks according to the theory on the basis of the symbol information provided by the parser. The process of DBC checking is controlled by an environment variable (to switch checking on and off) and by a configuration file. The configuration file consists of a list of module/class pairs that have to be checked. Thus by altering the configuration file, DBC checking can be enabled and disabled selectively for certain classes. 3.2: Analysis tools In this section we describe the analysis tools in more detail. The emphasis of the section is to show that the tools provided are suitable for the intended purpose, i.e., for prototyping activities during requirements elicitation and specification and for architectural prototyping. The analysis tools were implemented on Sun Solaris 2.x and Windows NT using the programming language C++ and the application framework ET++ [33]. The integration of the analysis tools (implemented in C++) with the infrastructure tools (implemented in Python) as well as the integration with other tools is described in more detail in the next subsection. Architecture: Figure 5 gives an architectural overview of the analysis tools currently provided. Figure 4 shows the basic relations between infrastructure tools and analysis tools; Figure 5 shows how the tools involved are interconnected and the main kinds of data and control flow.

Analysis Tools é DBC Browser é DBC Debugger

SNiFF development environment

Parser

Infrastructure é DBC Symbol Information é Run-time Environment

Symbol Files

Python Files

Figure 5: Architectural overview

The rounded boxes denote operating system processes. As we can see from the figure, DBC debugger and DBC browser reside in the same address space. The debugger is just a tiny extension to the browser but principally uses the same graphical user interface as the browser. The infrastructure, i.e., symbol information from the parser as well as the run-time environment for assertion checking is embedded in the browser/debugger application. Nevertheless, the distinction between infrastructure tools and analysis tools is crucial, as the analysis tools are implemented in C++ using the application framework ET++, whereas the infrastructure tools are entirely written in Python. Python provides good APIs for embedding itself in a C++ environment. The bi-directional solid arrow between infrastructure and core analysis tools indicates control and data exchange, in this case based on the API provided and by means of parameter passing. The API eases passing of datastructures beyond elementary data types. It is therefore relatively simple to pass Python vectors or arbitrary Python objects to the C++ part of the application and vice versa.

The main disadvantage of this embedded single-threaded architecture for the analysis tools is, that, in a case when the control flow is passed to the infrastructure (e.g., in order to execute some Python code) the graphical user interface of the analysis tools is blocked. We do not consider that to be a major drawback, as in most cases not very much (time consuming) code will have to be executed. In this context we must recall, that the intended purpose of the toolset is to provide some support for prototyping activities and not to debug full-fledged applications implemented in Python. Currently the SNiFF development environment can be used to define new Python classes, to view the entire class hierarchy, to edit code, to directly edit assertions, etc. The analysis tools and the SNiFF development environment are only loosely coupled, as there is no direct data transfer (denoted by the doted line) but only exchange of control information. The analysis tools typically request the SNiFF development environment to display a certain class or method whereas the SNiFF development environment informs the analysis tool that, e.g., a class has been deleted. The parser is controlled by the analysis tools and by the SNiFF development environment. The parser is responsible for reading Python source files and providing persistent symbol information that is needed by the analysis tools to properly display assertions. The information provided by the analysis tools is based solely on the symbol file; i.e., in principal no Python source code is necessary to view the assertions. As we have already seen in the above sections, the browser tool also allows editing operations like adding new assertions, deleting assertions and changing assertions. The browser applies these changes to the Python source code files on demand, i.e., when a corresponding menu entry is selected by the user. These changes are, of course, also reflected in the SNiFF development environment. Browser: The browser window depicted in Figure 6a is divided into three main parts. The upper part (marked with € in Figure 6a) shows all classes and methods contained in the project to analyze.

1

1

2

3

3 3

Figure 6a: DBC Browser

Figure 6b: Editing type expressions

The gray icon in front of the class name or the method name gives some basic information on the applicable assertions. The icons in front of the class names show whether there exist any class invariants, whereas the icons in front of the method names indicate whether preconditions, postconditions, old expressions or type expressions for parameters are specified. • • •

A hollow box indicates that no assertion is specified for the respective symbol, neither in the class itself nor in a subclass or superclass. This information is only related to assertions, not to any inheritance hierarchy in the sense of object-oriented programming. A box with a middle bar indicates that assertions are specified for the respective symbol, but that there are no assertions specified for any subclasses or superclass A box with a middle bar and gray corners indicates that assertions are specified for the respective symbol and for subclasses and/or the superclass. The filled upper corner indicates that assertions apply for superclasses, whereas a filled lower corner indicates that assertions apply for subclasses (both corner may be filled, too).

We consider this information to be very valuable as it gives a rough overview about the complexity of classes with respect to assertions. Classes with inherited assertions, especially in cases where many methods of a class inherit assertions, have to be understood and reviewed thoroughly as they are obviously core components and sources of misunderstandings between the developer and customers. On the other hand, classes with few assertions or few inheritance relationships (in the context of assertions) indicate either minor importance or white spots, i.e., not yet well understood parts of an application domain. The middle part of the browser (marked with ó in Figure 6a) displays the assertions of the selected symbol. The icons in front of the assertion expression indicate the type of assertion. Although this is redundant information (the type of an assertion can always be deduced from the assertion text), we consider this to be important information for the analyst, as the icons allow quick and easy recognition what kind of assertions are most important. By default all types of assertions are displayed for a class and all its superclasses. To facilitate understanding, i.e., to reduce the amount of assertions displayed simultaneously, filters may be applied. Three different filters (marked with ì in Figure 6a) apply to the assertions. First, the analyst may decide whether to include the assertions of base classes or not. This hierarchy filter always shows the inheritance path of the currently selected class. The analyst may selectively include or exclude the assertions of arbitrary base classes along the inheritance path. Second, the analyst may filter the display of assertions related to classes, i.e., class invariants and type expression for instance variables. Third, the analyst may filter the display of assertions related to methods, i.e., preconditions, postconditions, olds expressions and type expressions for method parameters. All three groups of filtering conditions are simultaneously applied to the currently displayed assertions. The filter mechanism is useful for selectively browsing the assertions of a class or a family of classes and thus facilitates understanding of specified assertions. Besides merely viewing assertions, the tool allows browsing the code of arbitrary classes with the SNiFF programming environment. The SNiFF application is controlled by our browser by means of the protocol provided by the programming environment SNiFF. Besides merely browsing assertions, the tools allows directly changing existing assertions and adding or deleting assertions. It is not possible to alter the signatures of classes or to add new classes. This task should be accomplished by using the programming environment SNiFF. We believe, that the syntax of Python is simple enough for easily specifying classes and

methods and is thus suitable for prototyping activities; nevertheless, classes and methods could also be specified by using a graphic notation like UML [32]. The user interface for altering assertions is particularly designed for ease of use. Figure 6b gives an example for a window that allows editing the type expression of a class. The currently specified instance variables and their associated type are depicted in the left part of Figure 6b. The type of an instance variable is easily changed by dragging one of the types shown in the right part of the window to the respective instance variable in the left part of the window. The types available for dragging are constructed dynamically, as, besides the built-in types, any class type currently available in the project may be used. The analyst may export the changes made on demand directly to the Python source code. Besides the special-purpose editor depicted in Figure 6b, other special-purpose editors are available for other types of assertions. Debugger: The DBC debugger is a separate tool but tightly integrated with the DBC browser. On selecting the debug mode in the Debug menu of the browser, the browser mutates to the DBC debugger as depicted in Figure 7a. The debugger does not at all restrict the browsing and filtering mechanisms of the DBC browser but extends them for debugging purposes. Specifically, the debugger allows setting breakpoints arbitrarily; i.e., a breakpoint may be set for a class, a method or an arbitrary assertion. A breakpoint for a class instructs the run-time system to stop whenever a class invariant is checked, i.e., before executing any method of this class. A breakpoint for a method indicates that the runtime system stops before checking the assertions of the particular method. A breakpoint for an assertion indicates the run-time system to stop before checking the marked assertion.

Figure 7a: DBC Debugger

Figure 7b: Inspecting objects

An arrow (see Figure 7a) indicates that a breakpoint has been reached. At this point the debugger allows inspection of the object in question. For this purpose we integrated PTUI [27] into our debugger. The PTUI component is part of the DBC checker depicted in Figure 5. An example snapshot is given in Figure 7b. The PTUI object browser allows visualizing data members of objects including inherited members, as well as inspecting class members. As PTUI is completely written in Python, the integration into our DBC checker was painless. Violations of assertions detected by the DBC checker are displayed in a window. We believe that the debugging support provided, in combination with the analysis support of the browser, contributes to facilitating the understanding of complex contractual relations. 3.3: Related tools The programming language Eiffel and the implementation by ISE is the only commercial object-oriented language with full support for invariants, preconditions and postconditions. As Design by Contract is built-in in the Eiffel programming language and run-time system, no special discussion is necessary. iContract: iContract [18] is a tool that provides support for Design by Contract for the programming language Java. iContract is a source-code preprocessor that instruments the code with checks for assertions. Special comment tags are interpreted by iContract and converted into assertion check code that is inserted into the source code. The instrumentation level (e.g., only postcondition checks) can be chosen on a file level, enabling fine-grained performance control. The basic idea, i.e., using special comment tags for marking assertion statements, is similar to our approach. The implementation differs substantially, as our implementation relies heavily on reflective capabilities of Python, whereas iContract is a source-code preprocessor. We do not believe that iContract would be suitable for prototyping activities, as the underlying programming language is too complex for prototyping issues and no distinctive tool support for prototyping is available. Design by Contract for Smalltalk: The work by Carillo-Castellon et al. [8] implements portions of Design by Contract for the programming language Smalltalk. The emphasis here is to support correctness. Due to a lack of static typing and dynamic type assertions (as provided by Python DBC) it is difficult to fully support correctness. No special tools are available for analyzing assertions. The implementation is straightforward; i.e., it is necessary to invoke the appropriate methods for checking assertions in the Smalltalk code manually. The assertion expressions are passed as Smalltalk blocks.

4: Conclusion and further work We believe that the DBC approach, together with the tool support provided (i.e., Python as a kind of model description language together with the high-level analysis and debugging tools) is a well-suited technique for prototyping of functional requirements and for architectural prototyping. Furthermore, we believe that there is a need for evolutionary development. In this context, migration techniques have to be developed to transform the prototypes (implemented by means of Python and our DBC extensions) to a target environment, i.e., C++ or Java. We are currently implementing such transformational tools.

The technique presented in this paper together with the tool support provided has to be combined with other widely used techniques especially in the analysis phase of the software life cycle. Therefore we are currently investigating the integration of our approach with user interface prototyping and with use-case-centered requirements elicitation techniques [3], [13], [26].

Bibliography [1]

Arapis C.: “A Temporal Perspective of Composite Objects”, in: Nierstrasz O., Tsichritzis D.: “ObjectOriented Software Composition”, Prentice Hall, The Object-Oriented Series, 1995, pp 123-152

[2]

Bäumer D., Bischofberger W. R., Lichter H., Züllighoven H.: “ User Interface Prototyping - Concepts, Tools, and Experience”, Proceedings of the 18th International Conference on Software Engineering (ICSE), Berlin, Germany, March 1996, pp 532-541

[3]

Behringer D.: “Modelling Global Behaviour with Scenarios in Object-Oriented Analysis”, Theses No. 1655 (1997), Ecole Polythechnique Federale de Lausanne (EPFL), 1997

[4]

Bischofberger W. R., Pomberger G: “Prototyping-Oriented Software Development – Concepts and Tools”, Springer-Verlag, 1992

[5]

Booch G.: “Object-oriented Analysis and Design with Applications”, The Benjamin Cummings Publishing Company, 1994

[6]

Bowen J. P., Hinchey M. G.: “Ten Commandments of Formal Methods”, IEEE Computer, IEEE Computer Society, April 1995, pp 56-63

[7]

Carey J. M., Currey J. D.: “The Prototyping Conundrum”, Datamation, June 1, 1989, pp 29-33

[8]

Carillo-Castellon M., Garcia-Molina J., Pimentel E., Repiso I.: “Design by Contract in Smalltalk”, Journal of Object Oriented Programming, November-December 1996, pp 23-28

[9]

Dijkstra E.W.: “A Discipline of Programming”, Prentice Hall, Englewood Cliffs, 1976

[10] Gamma E., Helm R., Johnson R., Vlissides J.: “Design Patterns - Elements of Reusable Object-Oriented Software”, Addison-Wesley, Professional Computing Series, Reading, Massachusetts, 1994 [11] Goma H.: “Prototypes – Keep Them or Throw Them Away”, in: Lipp M. E. (ed.): “Prototyping – State of the Art Report”, Pergamon Infotech Ltd, Maidenhead, 1986, pp 41-54 [12] Gordon S., Bieman J.: “Rapid Prototyping and Software Quality: Lessons from Industry”, Technical Report CS-91-113, Department of Computer Science, Colorado State University, 1991 [13] Graham I.: “Task Scripts, Use Cases and Scenarios in Object Oriented Analysis”, Object Oriented Systems 3, 1996, pp 123-142 [14] Helm R., Holland I.M., Gangopadhyay D.: “Contracts: Specifying Behavioral Compositions in ObjectOriented Systems”, Proceedings of ECOOP/OOPSLA'90 conference, 1990, pp 169-180 [15] Hoare C.A.R.: “Proof of Correctness of Data Representations”, Acta Informatica, Vol. 1, 1972, pp 271-281 [16] Holland I.M.: “Specifying Reusable Components Using Contracts”, Proceedings of ECOOP 92 conference, Lecture Notes in Comuter Science 615, Springer Verlag, 1992, pp 287-308 [17] Jacobson I.: “Object-Oriented Software Engineering – A Use Case Driven Approach”, Addison-Wesley, 1993 [18] Kramer R. “iContract-The Java Design by Contract Tool”, to be published in Proceedings of TOOLS USA ’98 conference, 1998 [19] Leavans G. T.: “An Overview of Larch/C++: Behavioral Specifications for C++ Modules”, TR 96-01d, February 1996, revised March, April 1996, January, July 1997, Department of Computer Science, Iowa State University, 1997 [20] Lutz M.: “Programming Python”, O'Reilly & Associates, Sebastopol, 1996 [21] Manna Z., Pnueli A.: “The Temporal Logic of Reactive and Concurrent Systems – Specification”, SpringerVerlag, 1991

[22] Meyer B.: “Building Bug-Free O-O Software: An Introduction to Design by Contract”, Object Currents, SIGS Publication, Vol. 1, No. 3, March 1996 [23] Meyer B.: “Eiffel - The Language”, Prentice Hall, Object-Oriented Series, Hemel Hempstead, 1992 [24] Ploesch R.: “Design by Contract for Python”, Proceedings of the Asia Pacific Software Engineering Conference, 1997 [25] Pomberger G., Blaschek G.: “Object-Orientation and Prototyping in Software Engineering”, Prentice Hall, The object-oriented series, Hemel Hempstead, 1996 [26] Ralyté J., Ben Achour C.: “Scenario Integration into Requirements Engineering Methods”, Proceedings of the Workshop on the Many Facets of Process Engineering (MFPE'97), Gammarth, Tunis, September 22-23, 1997 [27] Roadhouse Z.: see http://starship.skyport.net/crew/zack/ptui for more details [28] Rumbaugh J.: “Object-Oriented Modeling and Design”, Prentice Hall, 1991 [29] Shang D. L.: “Multiple Inheritance - A Critical Comparison on Transframe, Java & C++”, Object Currents, SIGS Publication, Vol. 1, No. 11, November 1996 [30] Sobol M. G., Kagan A.: “Which Systems Analysts are more Likely to Prototype?”, Journal of Information System Management, Summer 1989, pp 36-43 [31] Spivey J. M.: “The Z Notation: A Reference Manual”, International Series in Computer Science, PrenticeHall, New York, 1992 [32] UML: “Unified Method for Object-Oriented Development”, Rational Software Corporation, Version 0.91, 1996 [33] Weinand A., Gamma E., Marty R.: “Design and Implementation of ET++, a Seamless Object-Oriented Application Framework”, Structured Programming, Vol. 10, No. 2, Springer International, 1989, pp 63-87

Suggest Documents