![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Setting Up a Development This chapter presents the concepts associated with getting a development effort started and includes the following topics:
- Developing a System Architecture
- Setting Up the Initial Architecture
- Models
- Creating Subsystems
- Creating Views (Apex/Summit)
- Steps in Setting Up the Initial Architecture
- Setting Up the Development Environment
The Problem
Once Rational subsystems and views (Apex/Summit) are understood, the system to be developed must be divided into subsystems. Then the subsystems and views (Apex/Summit) must be created. The the development environment may be customized.
Developing a System ArchitectureOnce Rational subsystems and Apex views (Apex/Summit) are understood, the system to be developed must be divided into subsystems. This chapter presents suggestions for architecting a software system being developed using Apex by dividing the system into subsystems.
Dividing a System into Subsystems
Rational subsystems are like modules, but they are at a higher level of abstraction in a system. Subsystems support abstraction, encapsulation, modularization, and the reuse of code.
One of the hardest and most important steps in implementing a large complex system is decomposing the system into subsystems. Program units are placed into one of the subsystems of the system. Decomposing a system into subsystems is difficult because it must be done at the beginning of the implementation phase, when understanding of the entire system is immature. Decomposition fundamentally affects how the system is developed and understood during its entire lifetime. Decomposition changes can be very easy to make at the beginning of a project when there is not much code and other artifacts. Later, a change in decomposition may require great expense in reorganizing program units and interfaces and delays as the new organization is learned by all of the project members.
There are a number of well-understood principles for decomposing systems into subsystems. Still, many issues must be considered, including, but not limited to:
- The nature of the project being undertaken
- The organization that is producing it
- The size of the project
- The number and kind of deliverables
- The technology used in the project
- The geographical distribution of the organization producing the project
The purpose of decomposing the project must be understood.
Purpose of Decomposition
The fundamental purpose of decomposing a system into subsystems is to control and manage complexity. Each of the smaller pieces (the subsystems) of the system can be more easily understood on its own since it is smaller, and the system can be understood in terms of its major pieces and their interfaces while ignoring the internal details of each of the subsystems.
However, an architect who makes the decomposition must have a deep understanding of the entire system, including the details of the implementation of individual subsystems. Inadequate understanding of global issues can lead to performance and organization problems.
Another reason for decomposition is to make it possible for multiple developers to work on a system in parallel. To do this, tasks must be divided so that developers can work without constantly having to edit each other's files. There must be common agreement on interfaces. Once that is done, individual developers can implement various parts of the system. Depending on the target execution platform and the system structure, developers can independently test their parts of the system.
Additional reasons for decomposing a system are:
- To facilitate reuse. A system is broken into parts that might be reused for, or obtained from, other similar projects.
- To facilitate testing. A system is broken into parts that can be tested and/or certified most easily.
- To isolate dependencies on the execution platform, devices, or other factors likely to change.
- To help maintain software that evolves over time.
In summary, decompositions work best if the reasons for the decomposition are well understood and prioritized, and the decomposition is performed by an architecture team that has a good understanding of the problem domain.
Criteria for Decomposition
The management of complexity is the primary goal of decomposing systems into subsystems. This section discusses some of the specific ways systems can be decomposed into sub-systems to help achieve this and some of the other goals of decomposition.
The example for this section is a system that runs avionics on board a commercial airliner. There are many computer systems involved and many performance reliability issues. Flexibility and configurability are issues, as well as long-term maintenance.
Presented here is a simplified (and probably not very realistic) analysis of the system. The plane has to fly; its crew must talk to the ground. Various services are provided on board for the crew and passengers. Sensors, displays, controls, and actuators control physical functions.
As a general architecture, this is a distributed, embedded control system. Since physical devices are involved, some of the structure will be influenced by physical characteristics of devices and interconnections. Still, the architect(s) need to isolate the physical characteristics, because devices will change over the 40-year life of the plane and the same software may be used in a subsequent plane. Therefore, reusability is an issue.
First, there is separation of high-level functions. For example, controlling flaps as a function is distinct from controlling cabin lighting. Both may use a common substrate to control actuators, read sensors, and communicate across an on-board network.
Second, a basic message-based distributed system architecture can be used. Processes in different parts of the system can send messages to one another to obtain information or control actuators. Since displaying altitude information for the pilot is more important than displaying interactive video entertainment for the passengers, there will be different levels of service in the messaging system. Basic architectural decisions such as these have a significant effect on the structure and operation of the software, and on its flexibility, reliability, reusability, and performance.
Finally, device characteristics can be abstracted for most functions. That is, the basic Air-Phone function for passengers doesn't need to know many details of the actual transmission medium and can be programmed against a general radio-packet interface, whereas functions such as airborne radar and collision avoidance are more sensitive to all of their devices and need to be more integrated with them. Thus, many functions on the plane can be implemented to work with certain classes of devices. The functions and devices can be interchanged with other functions and devices as long as they present compatible interfaces. Other functions are highly integrated and need to be implemented, tested, and validated together.
Figure 28 Subsystems of the Avionics Example
![]()
Figure 28 is a sketch of the basic subsystems (or groups of subsystems) that will be presented. Each of these might be one or several subsystems. Some of these subsystems clearly make use of interfaces for services from other subsystems. Others provide stand-alone functions. Some subsystems provide infrastructure for the system as a whole, and others are vertical applications that solve some specific problem or provide some specific service.
To solve this problem, the architect(s) need to carefully analyze:
- The objects represented by this decomposition
- Their interfaces
- The data they provide and need to communicate to other parts of the system
- The physical connections for that communication
Because this is only an example, it is possible to proceed without having to be aviation experts. Here are some of the principles employed in this subsystem decomposition.
First is the management of complexity. Significant decisions about the interconnection architecture in the system have been made. This allows focusing on parts of the system individually and in small groups. Certain global issues need to be resolved (for example, overall network bandwidth). But many problems can now be considered individually. In addition, having subsystems with specific interfaces allows making and changing implementation decisions independently. If new radio equipment is installed in a newer model plane, there need be no other changes than the Radio Data Communications subsystem as long as the interface presented by the new equipment is upward-compatible.
A second goal is to allow parallel work by multiple developers. The decomposition into subsystems with well-defined interfaces greatly facilitates this. Once the interfaces are defined, independent groups can work on the implementation of each subsystem. Individual subsystems can be tested by constructing appropriate test scaffolding.
A third goal is to facilitate reuse. By minimizing interconnections and interdependencies in the system, individual pieces can be used in subsequent systems. For example, math functions and common data structures can be easily reused. A more significant slice of function, such as the cockpit console, can be reused if it is designed to be configurable and have interfaces that are connectable to different sensors and actuators. Vertical functions that are implemented against the interface of a specific sensor can be reused if another kind of sensor presents a compatible interface. Thus, reuse is a function of both the subsystem decomposition and the specific style and content of the interfaces in a subsystem.
A fourth goal is to facilitate testing. As mentioned above, individual subsystems can be tested with appropriate test scaffolding, and groups of subsystems or slices of function can also be tested. Testability is a property of subsystem decomposition and of the specifics of the design of the interfaces.
Another goal is to isolate and factor configuration parameters, which leads to the grouping of dependencies on a specific device, function, or other entity. For example, if establishing a packet radio connection requires sending signals on three different frequencies, this fact should not be distributed all over the code. It should exist in only one place so that if the protocol is changed, the code needs to be changed only in one place. Another example is machine dependencies. If the basic platform on which the system or a part of the system is to run changes, there should be minimal impact on the software. Computer technology is likely to undergo several changes over the 40-year life of a plane or the possible longer life of the software that runs in it.
Isolation and factoring is a property of subsystem decomposition and the design of the system. Characteristics that are to be factored are placed in the implementation of a single or small number of subsystems. Then, when changes are needed, the scope of what is affected is limited to those subsystems that have knowledge of the characteristic that is changed.
Subsystem decomposition also supports variants of a system. A variant is a version of a system that has some different characteristics but is mostly the same. A common example is having a variant of the system for each hardware platform. Some planes might use one kind of computer and others might use a another kind of computer. Variants are discussed in more detail in the chapter on Establishing a Development Process (Apex/Summit).
Architecture
There are very general patterns that occur commonly in systems. More than one organization might be applicable to a given system.
Layering
A system can be decomposed into subsystems using layering. abstractions in the system are placed into a hierarchy based on their use of other abstractions. In the bottom layer are abstractions that are self-contained. In the next higher layer are abstractions that make use of only the layer below them, and so on. Some logical grouping is usually applied as well.
In the example system, Math Functions, Process Management, and Network Drivers may be placed in the bottom layer. IPC Communications might be in the next layer, with abstractions for devices in the layer above that. Initialization would be in one of the top-most layers as illustrated in Figure 29.
Figure 29 Layered Subsystems of the Avionics Example
![]()
Thus, a hierarchy is formed based on usage relationships between subsystems. These usage relationships are embodied by importing relationships between library contexts. In this way, Apex can represent and enforce a hierarchical layered architecture.
Infrastructure and Applications
Often a complex system performs several different functions or performs functions for different clients. There can be multiple applications in a system from a client's point of view. For example, the avionics system provides both cockpit navigation and passenger entertainment. While there are many similarities between these functions and they may be built on a common infrastructure, there are also significant differences. A common architecture for building such systems is to have a layered infrastructure that is common to several vertical applications. The vertical applications themselves may also be layered internally. The vertical applications may import one or more subsystems in the infrastructure layers, but do not import subsystems in other vertical applications as illustrated in Figure 30.
Figure 30 Application and Infrastructure Subsystems
![]()
Device and Data Abstractions
A common design principle for creating basic abstractions is to encapsulate physical or data objects, thus creating packages or classes that hide the details of a device or data object. The same principle can be applied at a larger scale for creating subsystems. Some devices or sets of devices require multiple data abstractions or encapsulations to be fully packaged. Similarly, a complex data object may involve many abstractions and protocols to define a complete and appropriate interface to access it.
In the example system, packet radio may involve establishing connections, packets of various kinds, transactions and recovery, financial verification (if passengers are arranging credit card purchases, for example), and different levels of service. Such an interface may consist of many individual abstractions, which are then grouped as a whole in a subsystem.
Mutual and Hierarchical Grouping
One of the goals of subsystem decomposition is to divide a system into parts so that multiple developers can effectively work in parallel. Sometimes a large body of code has no other logical basis for decomposition, so it is divided into different subsystems only to keep individual subsystems from being too large and to create dividing lines enabling developers to work in parallel.
In such a situation, all of the units in the subsystems would want visibility to each other. Such a set of subsystems is called a mutual import set. Apex supports mutually importing systems and automatically makes all the units in each such subsystem visible to other members of the mutual import set. The set of subsystems is logically treated as a single subsystem as illustrated in Figure 31.
Figure 31 Subsystems Sets with a Mutual Import
![]()
Distributed Organizations
Many systems are distributed in nature. That is, they consist of multiple processes that communicate with one another using some mechanism, and these processes may be physically distributed. The process and interprocess communication functions are often found near the bottom of the hierarchy in such distributed systems. There are a number of interfaces present in such a layer, covering issues such as process management, message transmission, fault tolerance, and other related services. This layer is the backbone of most distributed applications. It is likely to be used by most of the other layers in one way or another.
Generic Software Architecture
When decomposing a system, a software architecture might be as illustrated in Figure 32.
Figure 32 Generic Software Architecture
![]()
The project subsystem contains the system description discussed in System Description.
Placement of Executables in a System Configuration
Parameterless procedures that are to be linked to produce executables can be placed in any subsystem that has sufficient imports to compile them. Often, small test procedures are scattered throughout a system configuration and these test procedures can be linked to execute parts of a system.
It is often advantageous to place the main executables that will be the delivered programs from a system in their own subsystem. This means that there is a subsystem, in the generic example, called executables, where the main procedures/functions are located. Linking, execution, and debugging are done from views of this subsystem (Apex/Summit) or from this Rational subsystem (Apex/ClearCase). The reasons for doing this are:
- Developers may have their own copy of only a few subsystems, but will always need a place to link and execute the system. If executables are distributed among various subsystems, all developers would need their own library context that has an executable.
- Executables are often large and separating them from the bulk of the source and object files makes it easier to manage the disk space involved. Library contexts containing the executables can be placed on different UNIX file systems.
- There is often the need to keep executables even if the source changes and is not explicitly kept. Having a separate subsystem for executables allows keeping all the required executables without having to keep any significant amount of the source code.
When doing system builds or recombinant testing, users often link against a variety of different library contexts. Separating the executables from the bulk of the source makes this easier.
Setting Up the Initial ArchitectureAfter the architecture of software is determined, the Apex structure must be created using the concepts of models, subsystems, views (Apex/Summit), exports, and imports.
Models
Models provide a mechanism to coordinate the characteristics of library contexts. Models are especially useful for initialization of library contexts. A model is a view (Apex/Summit) or Rational subsystem (Apex/ClearCase) that serves as a prototype for another library context. A detailed description of models is found in Models. Rational recommends setting up and using a view model.
Creating Subsystems
A subsystem is the first component to be created. Each subsystem represents a component of a larger software system that can be developed, tested, and released independently. A detailed description of subsystems can be found in Subsystems.
Creating Views (Apex/Summit)
Once a subsystem is created, a view is created within the subsystem. Each view is an alternative specification or implementation of the subsystem. A detailed description of views can be found in Subsystem Structure (Apex/ClearCase). Apex provides a method to customize the default structure and contents of views using models. Rational recommends setting up and using a view model.
Steps in Setting Up the Initial Architecture
Once the concepts of imports, exports, switches, and models are understood and the architecture is defined, the default library context can be created. This library context will be used for initializing all library contexts. It is recommended to start with the Apex default library context and then create your project's default library context. The process for setting up the architecture is:
- Create the model library context:
- Create a subsystem
- Create a view (Apex/Summit)
- Update the imports/exports
- Set up the default switches
- Create all the subsystems.
- Create an initial view in each subsystem (Apex/Summit)
- Develop a prototype of each subsystem
- Update the imports/exports
- Place the units under version control
Setting Up the Development EnvironmentTo facilitate development, the Apex environment can be customized.
Customization Options
The following items can be customized in Apex:
- The X windows Resources (colors, fonts, default window geometry)
- Templates (provide initial values for various files that are created by Apex)
- Summit/CM Reports (Apex/Summit only)
- Switches (define defaults for commands)
- The menus displayed by the GUI
Details on customization can be found in the Using and Customizing the GUI.
Rational Software Corporation http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2002, Rational Software Corporation. All rights reserved. |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |