Basic of Software Design
Software design is a phase in software engineering, in which a blueprint is developed to serve as
a base for constructing the software system. IEEE defines software design as a process of
defining, the architecture, components, interfaces, and other characteristics of a system or
component and the result of that process.
In the design phase, many critical and strategic decisions are made to achieve the desired
functionality and quality of the system. These decisions are taken into account to successfully
develop the software and carry out its maintenance in a way that the quality of the end product is
improved.
Principles of Software Design
Developing design is a cumbersome process as most expansive errors are often introduced in this
phase. Moreover, if these errors get unnoticed till later phases, it becomes more difficult to
correct them. Therefore, a number of principles are followed while designing the software. These
principles act as a framework for the designers to follow a good design practice.
To develop a complete specification of design (design model), four design models are needed.
These models are listed below.
1. Data design: This specifies the data structures for implementing the software by
converting data objects and their relationships identified during the analysis phase.
Various studies suggest that design engineering should begin with data design, since this
design lays the foundation for all other design models.
2. Architectural design: This specifies the relationship between the structural elements of
the software, design patterns, architectural styles, and the factors affecting the ways in
which architecture can be implemented.
3. Component-level design: This provides the detailed description of how structural
elements of software will actually be implemented.
4. Interface design: This depicts how the software communicates with the system that
interoperates with it and with the end-users.
Data Design
Data design is the first design activity, which results in less complex, modular and efficient
program structure. The information domain model developed during analysis phase is
transformed into data structures needed for implementing the software. The data objects,
attributes, and relationships depicted in entity relationship diagrams and the information stored in
data dictionary provide a base for data design activity. During the data design process, data types
are specified along with the integrity rules required for the data. For specifying and designing
efficient data structures, some principles should be followed.
These principles are listed below.
1. The data structures needed for implementing the software as well-as the operations that
can be applied on them should be identified.
2. A data dictionary should be developed to depict how different data objects interact with
each other and what constraints are to be imposed on the elements of data structure.
3. Stepwise refinement should be used in data design process and detailed design decisions
should be made later in the process.
4. Only those modules that need to access data stored in a data structure directly should be
aware of the representation of the data structure.
5. A library containing the set of useful data structures along with the operations that can be
performed on them should be maintained.
6. Language used for developing the system should support abstract data types.
The structure of data can be viewed at three levels, namely, program component level,
application level, and business level. At the program component level, the design of data
structures and the algorithms required to manipulate them is necessary, if high-quality software
is desired. At the application level, it is crucial to convert the data model into a database so that
the specific business objectives of a system could be achieved. At the business level, the
collection of information stored in different databases should be reorganized into data
warehouse, which enables data mining that has an influential impact on the business.
Architectural Design
Requirements of the software should be transformed into an architecture that describes the
software’s top-level structure and identifies its components. This is accomplished through
architectural design (also called system design), which acts as a preliminary ‘blueprint’ from
which software can be developed. IEEE defines architectural design as ‘the process of defining a
collection of hardware and software components and their interfaces to establish the framework
for the development of a computer system.’ This framework is established by examining the
software requirements document and designing a model for providing implementation details.
These details are used to specify the components of the system along with their inputs, outputs,
functions, and the interaction between them. An architectural design performs the following
functions.
1. It defines an abstraction level at which the designers can specify the functional and
performance behavior of the system.
2. It acts as a guideline for enhancing the system (whenever required) by describing those
features of the system that can be modified easily without affecting the system integrity.
3. It evaluates all top-level designs.
4. It develops and documents top-level design for the external and internal interfaces.
5. It develops preliminary versions of user documentation.
6. It defines and documents preliminary test requirements and the schedule for software
integration.
7. The sources of architectural design are listed below.
8. Information regarding the application domain for the software to be developed
9. Using data-flow diagrams
10. Availability of architectural patterns and architectural styles.
Architectural design is of crucial importance in software engineering during which the essential
requirements like reliability, cost, and performance are dealt with. This task is cumbersome as
the software engineering paradigm is shifting from monolithic, stand-alone, built-from-scratch
systems to componentized, evolvable, standards-based, and product line-oriented systems. Also,
a key challenge for designers is to know precisely how to proceed from requirements to
architectural design. To avoid these problems, designers adopt strategies such as reusability,
componentization, platform-based, standards-based, and so on.
Though the architectural design is the responsibility of developers, some other people like user
representatives, systems engineers, hardware engineers, and operations personnel are also
involved. All these stakeholders must also be consulted while reviewing the architectural design
in order to minimize the risks and errors.
Architectural Design Representation
Architectural design can be represented using the following models.
1. Structural model: Illustrates architecture as an ordered collection of program
components
2. Dynamic model: Specifies the behavioral aspect of the software architecture and
indicates how the structure or system configuration changes as the function changes due
to change in the external environment
3. Process model: Focuses on the design of the business or technical process, which must
be implemented in the system
4. Functional model: Represents the functional hierarchy of a system
5. Framework model: Attempts to identify repeatable architectural design patterns
encountered in similar types of application. This leads to an increase in the level of
abstraction.
Architectural Design Output
The architectural design process results in an Architectural Design Document (ADD). This
document consists of a number of graphical representations that comprises software models
along with associated descriptive text. The software models include static model, interface
model, relationship model, and dynamic process model. They show how the system is organized
into a process at run-time.
Architectural design document gives the developers a solution to the problem stated in the
Software Requirements Specification (SRS). Note that it considers only those requirements in
detail that affect the program structure. In addition to ADD, other outputs of the architectural
design are listed below.
1. Various reports including audit report, progress report, and configuration status accounts
report
2. Various plans for detailed design phase, which include the following
3. Software verification and validation plan
4. Software configuration management plan
5. Software quality assurance plan
6. Software project management plan.
Component-level Design
As soon as the first iteration of architectural design is complete, component-level design takes
place. The objective of this design is to transform the design model into functional software.
To achieve this objective, the component-level design represents the internal data structures and
processing details of all the software components (defined during architectural design) at an
abstraction level, closer to the actual code. In addition, it specifies an interface that may be used
to access the functionality of all the software components.
The component-level design can be represented by using different approaches. One approach is
to use a programming language while other is to use some intermediate design notation such as
graphical (DFD, flowchart, or structure chart), tabular (decision table), or text-based (program
design language) whichever is easier to be translated into source code.
The component-level design provides a way to determine whether the defined algorithms, data
structures, and interfaces will work properly. Note that a component (also known as module) can
be defined as a modular building block for the software. However, the meaning of component
differs according to how software engineers use it. The modular design of the software should
exhibit the following sets of properties.
Provide simple interface: Simple interfaces decrease the number of interactions. Note that the
number of interactions is taken into account while determining whether the software performs
the desired function. Simple interfaces also provide support for reusability of components which
reduces the cost to a greater extent. It not only decreases the time involved in design, coding, and
testing but the overall software development cost is also liquidated gradually with several
projects. A number of studies so far have proven that the reusability of software design is the
most valuable way of reducing the cost involved in software development.
Ensure information hiding: The benefits of modularity cannot be achieved merely by
decomposing a program into several modules; rather each module should be designed and
developed in such a way that the information hiding is ensured. It implies that the
implementation details of one module should not be visible to other modules of the program. The
concept of information hiding helps in reducing the cost of subsequent design changes.
Modularity has become an accepted approach in every engineering discipline. With the
introduction of modular design, complexity of software design has considerably reduced; change
in the program is facilitated that has encouraged parallel development of systems. To achieve
effective modularity, design concepts like functional independence are considered to be very
important.
Functional Independence
Functional independence is the refined form of the design concepts of modularity, abstraction,
and information hiding. Functional independence is achieved by developing a module in such a
way that it uniquely performs given sets of function without interacting with other parts of the
system. The software that uses the property of functional independence is easier to develop
because its functions can be categorized in a systematic manner. Moreover, independent modules
require less maintenance and testing activity, as secondary effects caused by design modification
are limited with less propagation of errors. In short, it can be said that functional independence is
the key to a good software design and a good design results in high-quality software. There exist
two qualitative criteria for measuring functional independence, namely, coupling and cohesion.
Coupling
Coupling measures the degree of interdependence among the modules. Several factors like
interface complexity, type of data that pass across the interface, type of communication, number
of interfaces per module, etc. influence the strength of coupling between two modules. For better
interface and well-structured system, the modules should be loosely coupled in order to minimize
the ‘ripple effect’ in which modifications in one module results in errors in other modules.
Module coupling is categorized into the following types.
No direct coupling: Two modules are said to be ‘no direct coupled’ if they are independent of
each other.
Data coupling: Two modules are said to be ‘data coupled’ if they use parameter list to pass
data items for communication.
Stamp coupling: Two modules are said to be ‘stamp coupled’ if they communicate by
passing a data structure that stores additional information than what is required to perform
their functions.
Control coupling: Two modules are said to be ‘control coupled’ if they communicate (pass a
piece of information intended to control the internal logic) using at least one ‘control flag’.
The control flag is a variable whose value is used by the dependent modules to make
decisions.
Content coupling: Two modules are said to be ‘content coupled’ if one module modifies
data of some other module or one module is under the control of another module or one
module branches into the middle of another module.
Common coupling: Two modules are said to be ‘common coupled’ if they both reference a
common data block.
Cohesion
Cohesion measures the relative functional strength of a module. It represents the strength of bond
between the internal elements of the modules. The tighter the elements are bound to each other,
the higher will be the cohesion of a module. In practice, designers should avoid a low level of
cohesion when designing a module. Generally, low coupling results in high cohesion and vice
versa.
Various types of cohesion are listed below.
Functional cohesion: In this, the elements within the modules are concerned with the execution
of a single function.
Sequential cohesion: In this, the elements within the modules are involved in activities in such a
way that the output from one activity becomes the input for the next activity.
Communicational cohesion: In this, the elements within the modules perform different
functions, yet each function references the same input or output information.
Procedural cohesion: In this, the elements within the modules are involved in different and
possibly unrelated activities.
Temporal cohesion: In this, the elements within the modules contain unrelated activities that
can be carried out at the same time.
Logical cohesion: In this, the elements within the modules perform similar activities, which are
executed from outside the module.
Coincidental cohesion: In this, the elements within the modules perform activities with no
meaningful relationship to one another.
After having discussed various types of cohesions, the procedure which can be used in
determining the types of module cohesion for software design.