B. Chandrasekaran and Bruce Weide
Principal Investigators
John Hartman and Steve Edwards, Research Associates
Department of Computer & Information Science
The Ohio State University
Columbus, OH 43210
· To develop a discipline and technology of composing reliable software from parts
· To develop a framework for program comprehension, and to apply it for software maintenance, reuse and reengineering.
Clearly these two goals are related. One of our on-going research aims is to make this connection clearer, so progress in each area makes use of advances in the other. One branch of the project, Functional Representation (FR), focuses on developing a framework for comprehension. Another branch, RESOLVE, focuses on developing a discipline for composition of software components. They share a number of underlying ideas. We often use the name FR/RESOLVE to indicate the general framework within which these ideas and technologies are being developed.
Comprehension and design are dual enterprises: we understand an artifact by recognizing functional modules or parts, and building a picture of how components, working together, create device-level functions. If an artifact (or natural system) is so constructed that the component interactions cannot be effectively enumerated and limited, then comprehension of them is correspondingly either incomplete or incorrect. This produces incomplete or incorrect predictions of behavior. Conversely, we design artifacts by composing parts, whose behavior we understand, into larger components which can similarly be composed. We reason about the behavior of the composed artifact to assure ourselves that the artifact realizes intended behavior. Comprehension of a design is an intrinsic part of the design process. Assuming that the components behave as intended, comprehensibility of a design depends on composition that permits component interactions to be fully accounted for.
A representation that lays out the relationships between components and their roles in achieving device functions has many uses. Important uses include reverse engineering, reengineering and effective reuse to construct other artifacts. Generating explanations for users is another common use.
Software architecture is an area of intense interest in software engineering today. The term architecture is itself not clearly defined (at any rate there is no consensus definition that incorporates all the intuitions different researchers have about them). One intuition is that the software architecture is a way of capturing the high-level design of a software system. A related intuition is that often architectures are reusable -- the same high-level design serves as a template for a number of different software system instances. So one of the goals of software architecture research has been to develop formalisms for representing high-level design, and ways of enforcing design practices based on accumulated wisdom about architecture families. This is an area where our work has much to say. We will remark briefly on the issues in this report.
· the function(s) of the artifact
· the structure of the artifact, i.e., a specification of its components and how they are put together
· an account of how the artifact achieves its function based on the roles played by the components and general laws that pertain to the domain.
Functional Representation (FR) is a general language and framework for representing functions, structure and the causal processes that underlie the operation of the device. The FR framework has been applied mostly to engineered physical devices. However, in our earlier work we have shown that FR is applicable to understanding abstract devices such a programs and logistic plans. In software engineering, the language of plans has often been proposed as the basis for encoding comprehension. We have shown that FR subsumes plans, in that it contains the same information as plans do in general, but also adds further information to make them fully satisfy the desiderata for comprehension. In particular, plans as currently represented in software engineering satisfy to some degree parts 1 and 2 of the desiderata. FR satisfies part 3 as well. An important direction of our research is to exploit the extensive work that has already been done in the area of program plans by adding the FR components to make plans more useful for various software engineering tasks.
There are different ways of providing an account of how the function is achieved, the third item in the above list. Mathematically, it is required is to show that the function of the artifact can be derived from the component properties and the way the components are composed. For certain purposes, an account giving relevant state changes of the artifact is useful. In this account, a series of partial state descriptions of the artifact is given. The initial state corresponds to the starting conditions, and the final state corresponds to the predicate which describes the function. Each intermediate state change is explained by appealing to the function of some component. It is explained by showing which function of which component played the causal role in the transition, and by showing the precise way in which the state change happened. This kind of explanation has been used traditionally in the FR work. This form of accounting is useful for explanation to human beings, and for certain kinds of problem solving activities, such as debugging and design criticism. Logically, other kinds of demonstrations can be substituted. For example, the RESOLVE framework seeks to ensure that the composed program satisfies the requirements by developing an effective modular proof technique.
The RESOLVE framework shares a number of intuitions about comprehension with FR, although it has used somewhat different terminology. Because of its exclusive focus on software, RESOLVE has a much better developed formalism for representing the relevant aspects of programs, and techniques for reasoning about composition. Because FR is a general framework for causal understanding, it needs domain-specific theories when it is applied to particular domains. RESOLVE provides such a theory for the software domain.
At first glance, the basic RESOLVE framework and notation resemble those of modern formal specification languages (e.g., Z, Larch) and object-based or object-oriented programming languages (e.g., Ada, C++, Eiffel, ML). What RESOLVE provides beyond its integrated language is an entire framework in which all the important, but sometimes conflicting, aspects of software design can be considered at once. In this framework, component engineering can exploit new perspectives that differ from conventional approaches in many important ways. The full compass of advantages can best be appreciated by examining specific reusable software components. This is why we have spent considerable effort designing, implementing, and using a variety of reusable components. They are specified and implemented in RESOLVE, and -- to facilitate technology transfer -- also implemented in Ada and/or C++.
The technical issues addressed include:
· Representation of an object: its properties and property relations, ports at which an object can be connected to other objects, and how ports are loci of causal interactions. Objects are represented in points of view which select certain properties for representation. Views also specify the object in the context of some generic environments, i.e., an object representation is with respect to the kinds of objects it can be in a causal relationship with. Properties can be static or dynamic. When they are dynamic, they are called state variables. Behavior of an object is the trajectory of the values of its selected state variables over time. Property relations are called behavioral specifications when the properties involved are the state variables. This basic ontology -- objects, static and dynamic properties, ports and behavioral specifications -- provides the basic primitives needed to represent individual objects in specific environments and reason about their properties and behaviors under various conditions.
· Composing objects and deriving the properties and behavior of composed objects. Ports are the basic "connection" points. Thus the structure of composed objects is given by specifying objects and the ports which form the connections between them. A basic framework for composing the behavioral specifications of the component objects into a set of behavioral specifications for the composite object has been developed.
· Various means of abstracting behaviors of the composite objects so that behavioral abstractions at new levels of description can be introduced. This is important because one of the most important consequences in assembling components is that some new behaviors can be described effectively only by using new primitive terms. For example, at some point a composition of transistors and resistors becomes an "adder," whose behavior is described not in terms of currents and voltages, but in terms of addends and sums. Representing the properties and property relations of the composed object may get arbitrarily complicated, especially if we wish to focus on new properties that are not part of the descriptions of the individual objects.
· Structural explanation. Given a composite object and a set of behaviors that it exhibits, there are different ways of "explaining" the behaviors. One kind of explanation is to appeal to the behavioral specifications, the laws of behavior of that object, and relate the behavior to these specifications. Another kind of explanation is structural: show that the behavior is a result of the behavioral specifications of its components and the way they are connected. In order to produce the latter kind of explanation, the object has to be decomposed into its components, their behaviors composed and abstracted to correspond to the set of behaviors to be explained.
· Functions. Functions are defined in terms of desired state changes in the objects in the environment. Artifacts are designed such that they cause the desired state changes in the objects in the environment, i.e., the task of the designer is to compose components into an artifact such that the behavior of the latter causes the desired state changes in the world.
FR can provide elements of an architectural description language (ADL). This foundational framework allows FR to be used as an ADL with well-defined semantics. Its structural description part -- components, their functions, and their ports and a way of describing how the components come together -- can play the role of a high-level description language. In addition, the behavior composition and abstraction techniques can be the basis for describing the behavior of designs.
We have developed a detailed framework to support representing and reasoning about objects, their structure, behavior and functions. The current work uses simple devices as examples. Over the next year, our plan is to apply the framework to larger systems. A draft technical report describing the framework appears as [Chandrasekaran 95]. Because of its length, it is not included as an appendix to this report.
During the year under report, we completed several efforts in the use of FR in software engineering.
We designed FR-Rapide to aid architecture prototyping and evolution using Luckham's Rapide ADL and environment at Stanford University. An example FR was created which explains how part of the Two-Phase Commit protocol is implemented in a Rapide architecture. It captures understanding in domains such as transaction processing, the X/Open standard, concurrent computing, and distributed computing. The value of this approach is demonstrated by the design of an explanation tool which supports Rapide prototyping and other architecture evolution activities. Applications include browsing, documentation, debugging, simulation, design verification, and rationale capture. FR-Rapide is described in [Hartman 1995]. The explanation tool and query semantics in FR-Rapide can be applied to other FR applications in software and non-software domains.
The technical report describing FR-Rapide is included as an appendix to this report.
This work was done as part of an effort to demonstrate, for a presentation at the STISS Symposium in August 1995, the current state of the art in software understanding. The demonstration was based on a scenario for reengineering Army MICOM's Rocket_Sim system using our various capabilities. The system consists of a general-purpose digital simulation system, DigSim, and an embedded subsystem for unguided rocket simulation. The reengineering goals were adding weather information to the flight simulation and adding control to iteratively determine rocket parameters to hit a target.
We showed how an FR could be constructed which captured understanding and answered various questions needed for reengineering, e.g. involving control concepts and data flow interpreted with respect to original and new requirements. Some of this FR can be constructed automatically by UNPROG. For example, the reengineering goals depend heavily on reverse engineering and reengineering the obscure, unstructured top-level loops in DigSim's main program and input procedure. Both of these involve "read-process" and other control concepts which can be automatically recognized by UNPROG. These loops must be restructured for further understanding and reengineering, and this can be done automatically by another of our tools, RESTRUC.
A technical report describing this work is currently in preparation and hence not included as part of this report. In order to give a sense of the work and the results, we describe the problem and our work in some detail below. The Rocket_Sim FR represents understanding used in top-level human reengineering, including necessary requirement and domain material.
Here we will briefly describe how we are combining both approaches in the Rocket_Sim reengineering example. One result is an FR model of interactive reengineering processes which use tools such as UNPROG.

Figure 1. UNPROG-RESTRUC - Automatic understanding and reengineering
As discussed above, we have represented UNPROG plans and output in FR. FR-UNPROG uses FR to represent all of the understanding used in UNPROG and RESTRUC. There are several kinds of advantages for replacing existing special-purpose representations with FR. For example, a single, principled representation provides conceptual and technical unification and clarity. Specific technical advantages and disadvantages of FR and the existing representations can be explored. Furthermore, a unified representation places the automatic system in its process and interactive context, as discussed below.
We are making an FR for all of the understanding used in an automatic understanding and restructuring example. The Rocket_Sim reengineering scenario requires reverse engineering and reengineering the obscure, unstructured top-level loops in DigSim-Rocket_Sim. UNPROG-RESTRUC can automatically understand and restructure the read-process loops in DigSim's main program and input procedure. Here is a overview of an FR for the understanding used by UNPROG-RESTRUC to restructure the DigSim input procedure, Input_Data:

Figure 2. FR for Automatically understanding and reengineering Input_Data
Note that FR research and use has been limited by the cost and difficulty of creating FR's manually. FR-UNPROG can cheaply and consistently create FR's, as needed, for research and some applications.
The Rocket_Sim example shows how FR can capture and model understanding used in human reverse engineering and reengineering. The scenario requires humans to perform difficult reverse engineering and reengineering. One reengineering goal is changing the program to use newly available weather data. This requires understanding how the program reads data, and how the program can be modified to accept new data. There are various possible designs for the modifications. Correct reimplementation depends on broader contexts and domains, such as the DigSim generalized input/output system and the role of weather in the Rocket_Sim flight models. An FR capturing all this understanding could look something like Figure 3.
If the big FR includes an automatic tool, e.g. UNPROG-RESTRUC as shown, it is a useful process model for interactive software engineering. In the Rocket_Sim scenario, we described how UNPROG-RESTRUC could be used interactively to help humans do the more difficult reengineering. When UNPROG-RESTRUC finds and restructures the read-process loop in Input_Data, it helps the human understand how the program reads data, and it makes it easier for him or her to understand and modify the rest of Input_Data and other parts of the system.
There are further advantages because the tool's understanding is represented in FR. For example, explanations involving all aspects of the understanding can be delivered by a general FR explanation tool, such as the one designed for FR-Rapide. As another example, the FR formalizes the interface between the human and automatic parts of the process. The human process can be improved using the FR model of tool use. The tool can be better understood and improved with respect to the human understanding it interacts with. Furthermore, FR representation of the tool's context is a step towards automating more of the task in an expanded tool.

Figure 3. FR for Reengineering Rocket_Sim
We have been consulting and collaborating with two research projects, one in Switzerland and one in Austria, which have been investigating and exploiting FR. In the research division of Swiss PT&T, Liver and Allemang have been using FR to represent and reason about a family of communication programs. They have refined the theoretical basis for the use of FR for representing programs, and issues associated with reuse. The results appear in a series of recent papers[3]
Adapting the RESOLVE discipline to C++. We had previously adapted RESOLVE to Ada, and in that case (at least for Ada83) the path of least resistance seemed clear: there was basically one sensible way to do it. For C++, however, the availability of inheritance as an additional language mechanism opened far more paths to be explored. We had reported following one such path in a paper published last year in Software Engineering Notes. This year we have explored two more paths that have proved to be even more interesting. The last of these now seems to have great promise for teasing out the many possible relationships that can be expressed using inheritance, especially inheritance combined with templates. The novelty and interest of our approach to the C++ community has become evident from newsgroup discussions of some of our ideas, e.g., inheriting from template parameters.
Further developing the RESOLVE framework, language, and discipline. Here, for example, we have explored the technical rationale for two specific component interface design principles called "observability" and "controllability" [Weide 95c]; and we have produced a convincing argument supporting the need for abstraction relations to reason about the correctness of data representations [Sitaraman 95]. We also have developed a set of components that we hope to use as the basis for a portable graphical user interface, with a complete formal specification and an initial implementation using Tcl/Tk. This experience has led us to consider several "domain-specific" refinements to the general RESOLVE discipline.
In addition to making progress on these major objectives, we have published the results of a variety of other work on component-based software technology: empirical studies of the cost and quality benefits of certain key tenets of the RESOLVE approach [Zweben 95]; a formal model of software subsystems in which software components have their own semantic denotations, which is necessary for understandability and modular reasoning [Edwards 95a]; a discussion of some technical impediments to tractable reverse engineering of legacy code [Weide 95a]; three workshop position papers on various aspects of our work ranging from language and environment support for understandability [Bucci 95, Edwards 95b] to software architecture [Hollingsworth 95b]; a method for locally characterizing safe vs. unsafe "code inheritance" [Edwards 95c]; and two short papers about the implications of our work for CS education [Weide 94, Weide 95b]. All but Edwards' Ph. D. dissertation and the two education-oriented papers are included as appendices to this report.
http://www.cis.ohio-state.edu/hypertext/LAIR/Main/arpa.html.
A sample library of software components, along with related project information, is available via the World-Wide Web through URL:
http://www.cis.ohio-state.edu/hypertext/rsrg
We have improved this WWW interface significantly from last year, and have made available a much more comprehensive component library than we had at the end of last year
The following publications have resulted from work conducted during the second year of this project. Items marked with a * after the citation key are enclosed as appendices to this report.
[Bucci 95] * Bucci, P., "A Program Editor to Support Reuse," Proceedings 7th Annual Workshop on Software Reuse, St. Charles, IL, August 1995, 5 pp.
Abstract -- A software engineer's mental model of software is influenced by many factors, including the application, the programming language, and even the programming environment. In particular, all programmers have to interact with a program editor, i.e., a tool to enter, modify, and view programs. This tool plays a role in shaping the way programmers think of software and of the software development process. Here we explore the impact of the program editor on the programmer's view of software, and in particular those aspects that have direct relevance for safe and successful software component reuse.
[Chandrasekaran 95] Chandrasekaran, B., "An Ontology for Reasoning About Objects, Their Behaviors and Functions," Draft, technical report, Laboratory for AI Research, The Ohio State University, 1995.
Abstract. -- The documents lays out a set of representational primitives for objects, their composition and reasoning about their behavior. A discussion of functions is provided and related to designer goals.
[Edwards 95a] Edwards, S.H., A Formal Model of Software Subsystems, Ph.D. dissertation , Department of Computer and Information Science, The Ohio State University, March 1995, 233 pp.
Abstract -- The conventional wisdom that software modules are merely a syntactic mechanism for organizing declarations and controlling visibility is wrong; modules must have meaning independent of the larger systems of which they are pieces. The traditional syntactic view limits the utility of software modules as the building blocks of large, complex software systems that are understandable to their human creators, maintainers, and users. People -- in all these roles and others -- form internal mental models of the things they interact with, and modules in conventional languages do not support the description of such mental models. This dissertation, therefore, proposes ACTI (Abstract and Concrete Templates and Instances) as a formal model in which the structure and meaning of component-based software systems can be defined and studied. We show how various languages and frameworks designed to support component-based software (i.e., the 3C model, OBJ, RESOLVE, Eiffel, and Standard ML) can be described in ACTI terms, comparing and illuminating the shortcomings of these approaches.
[Edwards 95b] * Edwards, S.H., "Good Mental Models are Necessary for Understandable Software," Proceedings 7th Annual Workshop on Software Reuse, St. Charles, IL, August 1995, 7 pp.
Abstract -- People for internal mental models of the things they interact with in order to understand those interactions. This psychological insight has been used by the HCI community to build computer systems that are more intuitive for end users. But it has not yet been applied to the problems of software designers, programmers, and maintainers. In fact, conventional programming languages do little to help client programmers develop good mental models of software subsystems. To constitute effective building blocks, modules must present simple mental models to the software professionals involved in assembling them into larger modules and ultimately into complete systems. Because a module in a conventional language has no real semantic denotation of its own, there is no effective way for such building blocks to contribute to the understandability of the software comprising them.
[Edwards 95c] * Edwards, S.H., Representation Inheritance: A Safe Form of "White Box" Code Inheritance technical report, Department of Computer and Information Science, The Ohio State University, OSU-CISRC-9/95-TR38, September 1995, 12 pp.; submitted for publication.
Abstract -- Inheritance as a programming language mechanism can be used to achieve several different goals, both in terms of expressing relationships between components and in terms of defining new components "by difference" from existing ones. For defining new component implementations in terms of existing implementations, there are several approaches to using "code inheritance." Black box code inheritance allows subclasses to reuse superclass implementations as-is, without direct access to their internals. Alternatively, white box code inheritance allows subclasses to have direct access to superclass implementation details, which may be necessary for the efficiency of some subclass operations. Unfortunately, white box code inheritance violates the encapsulation protection afforded to superclasses, opening up the possibility for subclasses to interfere with the correct operation of superclass methods. This paper proposes representation inheritance as a restricted form of white box code inheritance where subclasses have direct access to superclass implementation details, but are required to respect the representation invariant(s) and abstraction function(s) of their ancestor(s). This preserves the protection that encapsulation would have provided, while allowing the freedom of access that component implementers sometimes desire.
[Hartman 95] * Hartman, J. "Functional Representation of Executable Software Architectures", Technical Report, Laboratory For Artificial Intelligence Research, The Ohio State University, November, 1995.
Abstract -- Software architectures specify how high-level system
components interact and behave. Architecture evolution tasks require knowing
an architecture's design intentions. Existing architecture description
languages (ADL's), however, specify architectures without reference to
intentions. We describe the use of Functional Representation to capture
understanding of design intentions and their implementation in an architecture.
This approach will reduce the cost of designing, evolving, and implementing
architectures by improving human communication, and by providing more useful
tools and environments. Applications include prototyping, dynamic
documentation, design verification, simulation, execution analysis, and other
architecture activities.
Chandrasekaran's Functional Representation is
used to connect design intentions to an architecture's ADL specifications. The
result is a rich, hierarchical explanatory structure which is useful for many
purposes. Functional Representation is a theory and language for reasoning
about functionality and causal processes in devices. It has been successfully
applied to a large variety of tasks and devices, including software. Luckham's
Rapide is an executable ADL based on a rule-event execution model. FR-Rapide
applies Functional Representation to aid architecture prototyping with Rapide.
An example functional representation captures understanding of how part of
the Two-Phase Commit protocol is implemented in a Rapide prototype. Its
explanation incorporates understanding in domains such as transaction
processing, the X/Open standard, concurrent computing, and distributed
computing. The FR is a formal representation which helps humans understand and
communicate about the architecture. It also allows understanding to be
delivered and exploited by tools and environments.
The value of this
approach is demonstrated with an explanation tool which supports Rapide
prototyping and other architecture activities which can benefit from captured
understanding. Applications and tools include browsing, documentation,
debugging, simulation, design verification, and rationale capture.
[Hartman and Chandrasekaran 95] *
Hartman, J., and Chandrasekaran, B., "Functional Representation and Understanding of Software: Technology and Application", Proceedings of 5th Annual Dual-Use Technologies and Applications Conference, Mohawk IEEE and Rome Labs, Utica, NY (May 1995)
Abstract -- Government and industry spend over $100 billion a year to preserve and extend existing software. Existing tools have shallow analysis and limited impact. Improved tools with deeper, human-like program understanding will reduce the huge cost of activities involving existing software. We describe our automatic program understanding theory and technology. Our approach has two parts: understanding and representation. The UNPROG system uses programming plan knowledge to recognize deep programming concepts in existing programs. Functional Representation (FR) is a theory and language for representing understanding of devices, including programs. We use FR to capture program understanding to give the explanations required by applications. Automatic reverse engineering and reengineering tools can use this understanding to produce more useful program descriptions and reengineered code. We describe what has been accomplished so far, and discuss how this strategic dual-use technology can be further developed and applied.
[Hollingsworth 95] * Hollingsworth, J.E., and Weide, B.W., "One Architecture Does Not Fit All: Micro-Architecture Is As Important As Macro-Architecture," Proceedings 7th Annual Workshop on Software Reuse, St. Charles, IL, August 1995, 5 pp.
Abstract -- The field of study commonly known as "software architecture" should be split into two subareas: micro-architecture and macro-architecture. Work to date under the name "software architecture" has concentrated largely on macro-architecture. But micro-architecture, a.k.a. software component engineering, is of equal concern.
[Sitaraman 95] * Sitaraman, M., Weide, B.W., and Ogden, W.F., Using Abstraction Relations to Verify Abstract Data Type Representations, technical report, Department of Computer and Information Science, The Ohio State University, OSU-CISRC-9/95-TR39, September 1995, 30 pp.; submitted for publication.
Abstract -- In a typical data abstraction situation, the correspondence between the concrete representation and the abstract conceptual value of an ADT variable (object) is a many-to-one function. For example, many different pointer aggregates give rise to exactly the same binary tree. The theoretical possibility that this correspondence generally should be relational has long been recognized, but convincing examples have not been forthcoming. We show how such examples arise naturally in optimization problems.
[Weide 94] Weide, B.W., "Educating Software Engineers: Position Statement," Proceedings TRI-Ada '94, ACM, Baltimore, MD, November 1994, p. 225.
Abstract -- If the key "-ilities" are to be achieved for software in-the-large, they must be achieved in-the-small, i.e., at the level of software components, even those that serve as typical examples in a CS2 course. Existing textbook treatments of CS2-level programs serve primarily to illustrate how hard it is to design well. Their example designs are easy to criticize from the standpoint of good software engineering. The dearth of explicit and carefully-reasoned design principles in these texts makes it clear how little we as a community really understand about good software design.
[Weide 95a] * Weide, B.W., Heym, W.D., and Hollingsworth, J.E., "Reverse Engineering of Legacy Code Exposed," Proceedings 17th International Conference on Software Engineering, ACM, Seattle, WA, April 1995, 327-331.
Abstract -- Reverse engineering of large legacy software systems generally cannot meet its objectives because it cannot be cost-effective. There are two main reasons for this. First, it is very costly to "understand" legacy code sufficiently well to permit changes to be made safely, because reverse engineering of legacy code is intractable in the usual computational complexity sense. Second, even if legacy code could be cost-effectively reverse engineered, the ultimate objective -- reengineering code to create a system that will not need to be reverse engineered again in the future -- is presently unattainable. Not just crusty old systems, but even ones engineered today, from scratch, cannot escape the clutches of intractability until software engineers learn to design systems that support modular reasoning about their behavior. We hope these observations serve as a wake-up call to those who dream of developing high-quality software systems by transforming them from defective raw materials.
[Weide 95b] Weide, B.W., "Where is Software Headed? Challenges of Software Design and the Undergraduate Computing Curriculum," Computer 28, 8 (August 1995), 31-32.
Abstract -- Current CS curricula do not adequately address design. A big part of the problem is that it is at least as hard to teach good design as to do good design. Software engineers face the additional difficulty that most software engineering educators cannot even agree on what a well-designed piece of software should look like -- and the same is true for practitioners. So exactly what should we teach regarding software design?
[Weide 95c] * Weide, B.W., Edwards, S.H., Heym, W.D., Long, T.J., and Ogden, W.F., Characterizing Observability and Controllability of Software Components, technical report, Department of Computer and Information Science, The Ohio State University, OSU-CISRC-9/95-TR37, September 1995, 20 pp.; accepted to appear in Proceedings 4th International Conference on Software Reuse, April 1996.
Abstract -- Two important objectives when designing a specification for a reusable software component are understandability and utility. For a typical component defining a new abstract data type, a significant common factor affecting both of these objectives is the choice of a mathematical model of the (state space of the) ADT, which is used to explain the behavior of the ADT's operations to potential clients. There are subtle connections between the expressiveness of this mathematical model and the functions computable using the operations provided with the ADT, giving rise to interesting issues involving the two complementary system-theoretic principles of "observability" and "controllability". Previously we recommended a practical way to test compliance of a proposed design with these informally-defined principles: it should be possible to construct layered implementations of operations to test equality of and to copy variables of an ADT. This paper discusses problems associated with formalizing intuitively-stated observability and controllability principles in accordance with these tests. Although the example we use for illustration is simple, the analysis has implications for the design of reusable software components of larger scale and conceptual complexity.
[Zweben 95] * Zweben, S.H., Edwards, S.H., Weide, B.W., and Hollingsworth, J.E., "The Effects of Layering and Encapsulation on Software Development Cost and Quality," IEEE Transactions on Software Engineering 21, 3 (March 1995), 200-208.
Abstract -- Software engineers often espouse the importance of using abstraction and encapsulation in developing software components. They advocate "layering" of new components on top of existing ones, using only information about the functionality and interfaces provided by existing components. This layering approach is in contract to a "direct implementation" of new components, utilizing unencapsulated access to the representation data structures and code of existing components. By increasing the reuse of existing components, the layering approach intuitively should result in reduced development costs and in increased quality for new components. However, there is no empirical evidence that indicates whether the layering approach actually improves developer productivity or component quality. We discuss three controlled experiments designed to gather such empirical evidence. The results support the contention that layering significantly reduces the effort required to build new components. Furthermore, the quality of the components, in terms of the number of defects introduced during their development, is at least as good using the layered approach. Experiments such as these illustrate a number of interesting and important issues in statistical analysis. We also discuss these issues because, in our experience, they are not well-known to software engineers.