The Modular Structure of Complex Systems
SeyedMasoud Sadjadi and Wei Zhu
CSE870 Advanced Software Engineering MiniProject
Computer Science and Engineering
Instructor: Dr. B. Cheng
Michigan State University
Contact Information:
Abstract
David L. Parnas has been making great contribution to the world of software engineering. In [1], Parnas introduces module guide as that helps designers and maintainers of complex system to understand the software more accurately and more quickly. The main objective of [1] is to illustrate the modularity technique by demonstrating a real complex system, which is the Onboard Flight Program (OFP) for the A-7E aircraft. The purpose of this illustration is to convince the managers/developers of federal agencies and private software companies the usefulness and value of the principles of software engineering. So that the gap between academic research on software engineering and the application of software engineering in real industry could be filled up.
The key principles mentioned in this paper of a successful modularity are information hiding and good documentation called module guide. Parnas illustrated the use of information hiding and module guide throughout the demonstration of the modularity of OFP system.
Keywords
Modular, information hiding, module guide, hierarchy modularity, modular decomposition.
1. Overview of The Modular Structure of Complex Systems
Paper [1]attempts to illustrate that there was a biggap between the research being done in academia, which were mostly publishedin journals and conferences, and the use of this research in federal agencies and private software companies. They listeddifferent reasonable reasons for this gap and tried to proposepractical solutions by demonstrating a case that they studieddeeply. They picked a very successful software system to start with. OnboardFlight Program (OFP) for the A-7E aircraft is a real-time softwaresystem developed by the Navy and was selected as an example to illustrate the author’s ideas. Writing another equivalent software as a competitor to OFP is not atrivial task and it is actually very challenging. This original OFP software is an example of software developed without using the latest softwareengineering techniques such as modularity. The authors decided to redesign and rebuildthe entire software using modularization techniques. They had not actuallycompleted the entire software system at the time the paper was published, butthey had obtained enough promising results that they were able to use to convince people. In a later paper [10] Parnas explains that their fail was because of hardware constraints.
The main focus of this paper was on not only how to decompose a large complex system intosmall modules but also how to organize them into a hierarchy of modules to enable easy design and maintenance. One of the mainconcerns of this paper was how to develop modules that were less likelyto have changes of their interfaces. Of course, it will change during maintenance. A good modularization techniqueis one that frees the users of that module from the implementation details. These modules should hide their implementation details in a way that ifthe implementation changes during different phases of the softwarelifetime, there should be minimal changes needed for other modules. For small changes in the module, it is expected that other modules be not affected at all. Even significant changes should not require changes throughout.
A good modular software design should have a hierarchy of modules, whereeach intermediate node does not divide into more than a small manageablenumber of sub-modules. It should be easy for a developer to find the right place in the software where he should be aware of changes, once he has a well-defined descriptionof the changes that he is needed for the software.
The technique called information hiding was proposed in Parnas’s paper [2] that was published in 1972 and was emphasized in this paper for complex systems. According to the principles of information hiding, system details that are independent of other modules are hidden in separated modules. That is, other modules are unaware of system details that are not related to them. This technique is widely used currently. We can see this broadly in object-oriented and component-based software design principles. Some popular term now we can see in almost all kinds of object-oriented software design or programming languages articles or books such as ‘encapsulation’, ‘abstraction’ could be considered to be evolved from information hiding.
The other key point that the authors concluded to have great importance in a successful modularity is good documentation. The module guide is introduced in this paper is a key document to start with. A good module guide can reduce start-up time for new developers and hence reduce the cost of development and maintenance. The module guide was emphasized throughout the demonstration of the example and gave us a good lesson of the importance of the good documentation.
Although this is an old paper, the impact of this paper on software engineering is huge. In the following pages of this report, we can see a lot of work that are based on the techniques that were used in this paper. In sections 2 to 4, we introduced information transparency from [3], a semantically enhanced component trader architecture developed in [4], and the “Law of Demeter” to support design for change respectively and they are all follow up to [1]. Finally, in sections 5 and 6, we took a look at some other works that actually used Parnas’s techniques in [1] but did not explicitly cite it. This way, we can see the impact of one of Parnas’s ‘old’ works to the development of software engineering. Some of his works are now general rules in software engineering.
2. First Related Paper -- Coping With Software Change Using Information Transparency
The major objective of [3] is to overcome the obstacles of a successful designing for change. Traditional modular programming proposed by Parnas in [1] is not sufficient for designing for change as will be described later. Information transparency was proposed in [3] as the solution to incompleteness of modular programming in designing for change. Information transparency is a complement to information hiding modularity and not a competitor for it. The idea of information transparency is to use a signature of a changing to mark the code segments that should change with designing the change.
In [3], authors introduced an important problem with traditional modular programming in [1]. They claimed that changes that happen in a software system during development and maintenance phases might be beyond the scope of one module. In [1], Parnas gave a guideline to build modules in a way that they keep the design decisions that are most likely to change as secrets of modules and keep the related design decisions as local as possible in one module or adjacent modules, which are part of a higher-level module. Now what happens if a change happens that is on a crosscutting concern, which involves more than one module? Parnas introduced module guide as a document for developers and maintainers to look for modules that have been affected by a change without wasting time wondering around for finding the related module [1]. Unfortunately, this just works for design decisions that follow the hierarchy of modules designed in module guide. In complex systems that contain lots and lots of modules, looking for all of the modules involved in a crosscutting change would be very frustrating and time consuming. Moreover, there is no guarantee about finding all the modules involved in this change. Therefore, it is obvious that having some of the concerns and design decisions encapsulated as secrets into separate modules leaves out other concerns and design decisions (crosscutting concerns) scattered over many modules. Examples of these crosscutting concerns could be fault tolerance, logging, or security code, which are dispersed in many modules in existing systems.
Aspect-oriented programming (AOP) [6] gives a very good solution to this problem. AOP provides languages that either declaratively or reflectively you can define the crosscutting aspects. AOP weaves these crosscutting aspects into your application code. AOP is also a complementary solution to modular programming. Unfortunately, AOP does not help much when the system designer has no proper anticipation about the changes in the future. Moreover, there are lots of existing codes that are not written in AOP but are written in a traditional modular fashion. In [3], authors proposed a technique called information transparency that helps programmers to identify the dispersed elements of a crosscutting concern and bring them together into a single view for planning and carrying out the global change. This way the programmer can look at each crosscutting aspect as one module, because all the related codes to this aspect are gathered in one place. Information transparency is actually using the same techniques as AOP, but it uses them after the fact, i.e., it uses tools and utilities to find the crosscutting aspects in existing codes.
Authors in [3] claim that using information transparency in addition to information hiding modularity as a complementary technique enables a successful design of software systems for changes. As the authors mentioned, it is actually a difficult task to provide all the appropriate tools and utilities. This work is also just feasible in the software systems that programmers have good sense of writing program in a predefined style and with fully documented convention for variable names, class name, etc. Unfortunately, this is not the case in many existing applications, but still you can use more powerful utilities that can be configured and customized to your style of writing code.
In [3], authors removed the restriction of tree like hierarchy in the module guide proposed in [1]. Module guide was designed with a tree like structure to guide the programmers to locality of changes that might happen to code according to a change. Module guide also uses documentations to index the similarity of codes in other modules using different documents. However, information transparency does not need any of this tree structure and indexing in different documents. It actually uses the similarity of the code in different modules to bring together all the code involved in an aspect. The examples shown in [3] are promising, but we do not believe that this is a complete solution to the “design for changes” problem. Of course, these utilities and tools are very helpful for the transition time to a good solution and it may be used for existing codes for a while and then once all the codes are replaced with a newer technique like AOP or something more powerful, there will be no need for using these utilities as the main solution.
3. Second Related Paper -- Towards a Semantically Enhanced Component Trader Architecture
Parnas introduced modular programming and localizing design decisions that are more likely to change in close future as secrets of modules to provide software designers, developers, and maintainers to better cope with changes in software[1]. Moreover, interfaces to these modules shows those design decisions that are less likely to change. The same ideas are being used in developing component software, software that is built by composition of components. Components are examples of more abstracted and self-describing modules developed by different software developers that communicate with other components through their well-defined interfaces. In another word, a component is the unit of composition with well-defined interfaces and context dependencies that can be developed independently and used by third parties.
In a component-based software, one of the main players is component trader. A component trader is responsible to find the right component as a response to request for a service (component). In traditional systems, previous to the time of this paper’s publication, this matching for appropriate component was based on the appearance (interface) of the component. These trading systems are based on the Parnas’ original idea in [1] that introduces the interface for modules. This appearance matching is nothing more than matching the interface of the requested component (or module) to those in the repository. In [4], the authors extended this idea and introduced a semantically enhanced component trader architecture that finds components that are not only syntactically the right answer to the requested component (plug compatible), but also semantically appropriated for the system.
In this framework, dynamic configuration and re-configuration of components are possible through on-the-fly re-composition. As in Parnas’s paper[1], which was concerned about modularity in “complex” systems, the work in this paper is thought to be scalable. One of the big differences between [1] and [4] is that in [1] Parnas assumed that the whole system was done under single management, while in in contrast to [4] the authors assumed each component can be developed independently. Therefore, having just appearance-based (interface) information for components does not capture the encapsulated behavior inside the component. So that there is a need for behavior-based (semantic) information about the components developed by different authorities to make sure that we are composing the right components.
In [4], authors focused on how to define high-level semantic service description to select a service among all the components available in the repositories of the traders. They reintroduced the “name services” and “directory services” as previous approaches to finding the right service and showed their shortcomings. As the number of services (components) grows the naming services does not scale well. Directory services scale well as far as the services are predefined, but unfortunately the nature of open distributed systems makes this complete predefined information almost impossible. A trading service, on the other hand, uses a typing hierarchy, which makes it possible to locate a service without having the name of the service. Only the specification for the service is enough, which is all the prospective customers can provide in their request. Typing hierarchy reminds the module guide in [1] that helps a designer or a maintainer of a complex system to find the right modules to change or to extend without wasting time in looking into non-relevant modules. We believe the ideas in typing hierarchy come from module guide in [1].
The definition of the trading adopted in [4] is as follows: “the activity of choosing services, such that they match some service requirements. The choice is based on the comparison of the specification of a service required (provided by a prospective customer) and the service specification supplied by service providers or their agents” [5]. Therefore, a component should provide the trader not only the interfaces it has, but also the interfaces it requires, a list of consumed and produced events, and all the states that it may expose to. Moreover, to satisfy a service request, a component should support the expression of relationships between components. In [4], authors provided a component description language that helps locating a component without checking the component internals. This language is powerful enough to capture the encapsulated behavior in the component.
In this language both precision and usability were of concern. The authors in [4] came up with an approach in that favors both precision of component definition and its usage. Finally, they improved the traditional traders by replacing interface definitions with component descriptions (using the new language) and then replacing service type conformance with specification matching.
4. Third Related Paper -- Assuring Good Style for Object-Oriented Programs
In [7], authors introduced a useful independent styling rule for writing object-oriented programs named “Law of Demeter”. The whole objective of this rule is to help programmers to write programs that are easy to change both on development and maintenance phases. This rule is very easy to follow. It gives programmers the ability of using encapsulation and modularity in a “principled” (restricted) way. The main goal of Parnas in [1] was to develop a technique to make later changes to software less risky and less expensive. Parnas’ modular programming technique encouraged programmers to encapsulate design decisions that are “most likely” to change as secrets of modules. In his approach, Parnas recommended put the design decisions that are “less likely” to change into module’s interfaces. Now imagine if a change happens that needs change into an interface of a module. These changes should be rare, but they may happen. Unfortunately, because of poor modularization these changes are more likely to happen. This causes changing the module that its interface has to be changed and all other modules that import this interface (the ones that depend on this module). Now if there is no limit or principle on how to compose objects (modules) then it is very hard to find all the dependent modules, i.e., by looking at the code of a module it is not obvious to find all the dependencies. Parnas realized this problem and introduced module guide and other documents that have some indexes and references inside them to show these dependencies, but it is still hard to go through all the documents and pull out all the dependencies that may happen to be nested or even circular.