Modular Design and Data Structures in Software Development
Immediate Objectives
Modular Decomposition, Design, Decision Algorithms, and Basic Data Structures
Modular Decomposition: Depending on what we mean by module, we have the following classifications:
- Source: This is regarded as the most frequent and contains the source text writing.
- Data Table: Used to tabulate certain initialization data that are experimental or difficult to obtain.
- Configuration: We have put together in a single module all the information that can set the specific working environment.
- Other: A module used to group certain elements of the system that are interrelated and can be treated separately from the rest.
Only in exceptional cases will maintainability be sacrificed for the sake of processing speed or smaller code size.
Minimum Qualifications of a Modular Decomposition Methodology
Functional Independence
A module must perform a specific function or set of related functions, with little to no relation to the other modules of the system. Greater independence leads to greater maintainability and reusability. To measure functional independence among various modules, we have two criteria: Coupling and Cohesion.
Coupling
We have several types that can be strong, moderate, or weak. In order of decreasing strength, they are:
- Content Coupling (strong): From one module, it is possible to change local data and even code from another module.
- Common Coupling (strong): A common data area is used, and some or all modules of the system have access to it.
- External Coupling (strong): Here, the common area is constituted by an external device to which all devices are linked.
- Control Coupling (moderate): A control signal or data that is passed from one module to another (B) determines the execution line to be followed within B.
- Stamp Coupling (weak): The modules exchange data and the complete structure of the data.
- Data Coupling (the weakest): Modules only exchange data.
The goal is to have the weakest link possible.
Cohesion
The content of each module has to be as consistent as possible. We have several types that can be low, medium, or high. In order of increasing strength, they are:
- Coincidental Cohesion (the lowest): Any relationship between elements of the module is purely coincidental.
- Logical Cohesion (low): Elements in a module are grouped because they perform similar functions from the viewpoint of the user.
- Temporal Cohesion (low): Elements are grouped in the same module because they run at the same time.
- Communication Cohesion (average): All elements of the module work with the same input data set or have the same output data set.
- Sequential Cohesion (combined): All elements of the module work on a functional sequence.
- Functional Cohesion (highest in descending order design techniques): Each element is responsible for conducting a specific function.
- Abstractional Cohesion (highest, based on abstractions and object-oriented techniques): In abstraction-based design, this is achieved by designing a module as an abstract data type associated with some content for the transaction. In object-oriented design, this is achieved by designing a module as a class of objects, where certain attributes are associated with corresponding methods for their management.
The aim is to achieve high cohesion, facilitating maintenance and reuse.
Understandability
Apart from functional independence, understandability depends on other factors such as:
- Identification: Choosing a proper module name.
- Documentation: All aspects of design or implementation must be clarified.
- Simplicity: Simple algorithms are best.
Adaptability
In addition to functional independence and comprehensibility, adaptability depends on other factors such as:
- Forecasting: Modules that are expected to change should be grouped into modules with the weakest possible coupling to other modules.
- Accessibility: To adapt a system, it must be easy to access specification documents, design, and implementation. This requires meticulous organization, normally provided by CASE tools.
- Consistency: When modifying the source code, all involved documents should be changed. This can be done automatically with tools for version control and configuration. In object-oriented environments, such tools may not exist, so strict discipline within the library is necessary.
Top-Down Functional Design Techniques
Decomposition of the system is done from a functional standpoint. The system’s function is decomposed into simpler functions, which are assigned to separate modules.
Development by Progressive Refinement
This is structured programming, where clear and simple control structures such as sequence, selection, and iteration are used. The program is treated as a single global operation to be broken down into simpler operations. In the design stage, we are only at the early stages of refinement.
Jackson Structured Programming (JSP)
Similar to structured programming, the difference lies in the recommendations for building the program’s structure, which should be as similar as possible to the input and output structures. The steps of this technique are:
- Analyze the problem’s environment and describe the data structures to be processed.
- Construct the program structure based on the data structures.
- Define tasks in terms of elementary operations available and place them in the appropriate modules of the program structure.
Structured Design
The design task is to move from the Data Flow Diagram (DFD) to structure diagrams. The difficulty is that we must establish a hierarchy between the different modules not shown in the DFD. Sometimes, a coordination module is used to build this hierarchy. Two data-flow analyses are performed:
- Processing Flow Analysis: Identifies the global flow of information from input elements to the system’s output. Processes are divided into three regions: inflow, processing, and output. Modules are assigned to the operations of the diagram, and coordination modules are added to perform control in accordance with the flow distribution.
- Transaction Flow Analysis: Can be applied when the data flow can be decomposed into several separate lines. The analysis identifies the transaction center, from which flow lines and regions corresponding to each of these lines or transactions are derived.
Design Techniques Based on Abstractions
Abstraction-Based Modular Decomposition
This consists of expanding the existing language with new operations and data types defined by the user. Separate modules are dedicated to each abstract data type and each important applicable function. It can be applied in two ways:
- Top-Down: Similar to progressive refinement, each step of the operation to be refined is separately defined as a functional abstraction or abstract data type.
- Bottom-Up: We expand existing primitive programming language and libraries with new, higher-level operations and types that are more suitable for the scope being designed.
Abbott Method
Identify data types in the text description as nouns, and sometimes attributes as adjectives. Identify operations as verbs or names of actions. Make two lists, one for nouns and one for verbs. Reorganize the lists, extracting possible data and associating their attributes and operations. Eliminate synonyms and add elements involved in the design description. Assign a module for each data abstraction or group of interrelated abstractions. The module can correspond to a data package if a reference of that kind is used in the program. This method can be used both in abstraction-based design and object-oriented design.
Object-Oriented Design Techniques
Object-oriented design is similar to abstraction-based design, but it adds inheritance and polymorphism. Each module contains the description of a class of objects or several interrelated classes. Besides the modular diagram, we rely on expanded data model diagrams and structure diagrams.
Object-Oriented Design
Based on:
- Study the problem, reformulating the specifications to make them more precise.
- Develop a solution in general terms.
- Formalize in terms of classes of objects and their relationships as follows:
- Identify the objects (or classes), their attributes, and components.
- Identify the operations on the objects associated with the appropriate class or object.
- Implement inheritance where appropriate.
- Describe each operation in terms of the others and overcome potential omissions.
- Establish modular construction: Assign classes and objects to modules.
The result of this stage is the system structure diagram.
Data Design Techniques
In database organization, we can see three levels:
- External: Corresponds to the user’s vision.
- Conceptual Level: Establishes a logical organization of data through a data model diagram, either an ER diagram or an object model diagram.
- Physical Level: Organizes data according to the layout of the database manager. If it is a relational database, it would be a schema.
The transition from the external to the conceptual level is done during analysis. The transition from the conceptual to the physical level is done during design.
Designing Relational Databases
In the relational model, efficiency is considered from two points of view: normal forms to avoid duplication, and indexes to improve the speed of data access.
- Normal Forms:
- 1st Normal Form: The information associated with each column is a single value and not a collection of values of variable number.
- 2nd Normal Form: It is in 1st normal form, there is a primary key that distinguishes each row, and every column that is not the primary key depends on the entire primary key.
- 3rd Normal Form: It is in 2nd normal form, and the value of each column that is not the primary key depends directly on the primary key (i.e., no dependencies between columns that are not the primary key).
- Design Entities: Each entity class is a table, each element of that class is a row, and each attribute of that entity is a column. The reference number or code, if used, serves as the primary key.
Treatment of Relationships
In the object model, there are two special types of relationships: composition (or aggregation) and inheritance (or specialization). The others are association relationships. The general technique, valid for all cardinalities, is to translate the relationship into a table containing references to the tables of the related entities and attributes of the relationship, if any.
- If cardinality is 1-N: Include data linking in the same table of one of the related entities.
- If cardinality is 1-1: You can merge the tables of the two entities into one.
Treatment of Composition Relationships
The cardinality on the side of the composite object is almost always 1. The same criteria as above apply.
Treatment of Inheritance
When a class has several subclasses, there are three ways to store information in the tables of entities:
- Use a table for the superclass with common attributes inherited by subclasses, plus one table per subclass with its specific attributes.
- Common attributes are repeated in the tables of each subclass, so the superclass table disappears.
- Extend the superclass table with all attributes of each subclass, regardless of the tables of each subclass.
Index Design
Allows quick access to specific data at the expense of increasing storage space and the time to store new data and change the value of an indexed attribute. If data must be accessed through its relations with others, it is desirable to maintain indexes on primary keys and reference columns of the related entities.
Designing Object Databases
There is a greater variety of structures available, but they differ in each case. We can see two approaches in the design:
- When the object database can use a variety of structures. The management system provides database to supplement the data persistence.
- When there is no such variety of structures, and the object database is analogous to a relational database. The management system database provides the implicit existence of object identifiers, making unnecessary the explicit reference codes or numbers in columns.