1 - Software Design Concepts
1 - Software Design Concepts
1 - Software Design Concepts
Once the requirements document for the software to be developed is available, the
software design phase begins. While the requirement specification activity deals
entirely with the problem domain, design is the first phase of transforming the
problem into a solution. In the design phase, the customer and business requirements
and technical considerations all come together to formulate a product or a system.
The design process comprises a set of principles, concepts and practices, which allow
a software engineer to model the system or product that is to be built. This model,
known as design model, is assessed for quality and reviewed before a code is
generated and tests are conducted. The design model provides details about software
data structures, architecture, interfaces and components which are required to
implement the system. This chapter discusses the design elements that are required
to develop a software design model. It also discusses the design patterns and various
software design notations used to represent a software design.
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.
Every software process is characterized by basic concepts along with certain practices
or methods. Methods represent the manner through which the concepts are applied.
As new technology replaces older technology, many changes occur in the methods
that are used to apply the concepts for the development of software. However, the
fundamental concepts underlining the software design process remain the same,
some of which are described here.
Abstraction
Abstraction refers to a powerful design tool, which allows software designers to
consider components at an abstract level, while neglecting the implementation details
of the components. IEEE defines abstraction as ‘a view of a problem that extracts the
essential information relevant to a particular purpose and ignores the remainder of
the information.’ The concept of abstraction can be used in two ways: as a process and
as an entity. As a process, it refers to a mechanism of hiding irrelevant details and
representing only the essential features of an item so that one can focus on important
things at a time. As an entity, it refers to a model or view of an item.
Architecture
Software architecture refers to the structure of the system, which is composed of
various components of a program/ system, the attributes (properties) of those
components and the relationship amongst them. The software architecture enables
the software engineers to analyze the software design efficiently. In addition, it also
helps them in decision-making and handling risks. The software architecture does the
following.
• Provides an insight to all the interested stakeholders that enable them to
communicate with each other
• Highlights early design decisions, which have great impact on the
software engineering activities (like coding and testing) that follow the
design phase
• Creates intellectual models of how the system is organized into
components and how these components interact with each other.
Currently, software architecture is represented in an informal and unplanned
manner. Though the architectural concepts are often represented in the
infrastructure (for supporting particular architectural styles) and the initial stages of
Patterns
A pattern provides a description of the solution to a recurring design problem of some
specific domain in such a way that the solution can be used again and again. The
objective of each pattern is to provide an insight to a designer who can determine the
following.
▪ Whether the pattern can be reused
▪ Whether the pattern is applicable to the current project
▪ Whether the pattern can be used to develop a similar but functionally or
structurally different design pattern.
Modularity
Modularity is achieved by dividing the software into uniquely named and addressable
components, which are also known as modules. A complex system (large program)
is partitioned into a set of discrete modules in such a way that each module can be
developed independent of other modules. After developing the modules, they are
integrated together to meet the software requirements. Note that larger the number
of modules a system is divided into, greater will be the effort required to integrate the
modules.
Information Hiding
Modules should be specified and designed in such a way that the data structures and
processing details of one module are not accessible to other modules. They pass only
that much information to each other, which is required to accomplish the software
functions. The way of hiding unnecessary details is referred to as information
hiding. IEEE defines information hiding as ‘the technique of encapsulating software
design decisions in modules in such a way that the module’s interfaces reveal as little
as possible about the module’s inner workings; thus each module is a ‘black box’ to
the other modules in the system.
Information hiding is of immense use when modifications are required during the
testing and maintenance phase. Some of the advantages associated with information
hiding are listed below.
▪ Leads to low coupling
▪ Emphasizes communication through controlled interfaces
Stepwise Refinement
Stepwise refinement is a top-down design strategy used for decomposing a system
from a high level of abstraction into a more detailed level (lower level) of abstraction.
At the highest level of abstraction, function or information is defined conceptually
without providing any information about the internal workings of the function or
internal structure of the data. As we proceed towards the lower levels of abstraction,
more and more details are available.
Software designers start the stepwise refinement process by creating a sequence of
compositions for the system being designed. Each composition is more detailed than
the previous one and contains more components and interactions. The earlier
compositions represent the significant interactions within the system, while the later
compositions show in detail how these interactions are achieved.
To have a clear understanding of the concept, let us consider an example of stepwise
refinement. Every computer program comprises input, process, and output.
▪ INPUT
• Get user’s name (string) through a prompt.
• Get user’s grade (integer from 0 to 100) through a prompt and validate.
▪ PROCESS
▪ OUTPUT
This is the first step in refinement. The input phase can be refined further as given
here.
▪ INPUT
• Get user’s name through a prompt.
• Get user’s grade through a prompt.
• While (invalid grade)
Ask again:
▪ PROCESS
▪ OUTPUT
Note: Stepwise refinement can also be performed for PROCESS and OUTPUT phase.
Refactoring
Refactoring is an important design activity that reduces the complexity of module
design keeping its behaviour or function unchanged. Refactoring can be defined as a
process of modifying a software system to improve the internal structure of design
without changing its external behavior. During the refactoring process, the existing
design is checked for any type of flaws like redundancy, poorly constructed algorithms
and data structures, etc., in order to improve the design. For example, a design model
might yield a component which exhibits low cohesion (like a component performs
four functions that have a limited relationship with one another). Software designers
may decide to refactor the component into four different components, each exhibiting
high cohesion. This leads to easier integration, testing, and maintenance of the
software components.
Structural Partitioning
When the architectural style of a design follows a hierarchical nature, the structure of
the program can be partitioned either horizontally or vertically.
In horizontal partitioning, the control modules are used to communicate
between functions and execute the functions. Structural partitioning provides the
following benefits.
• The testing and maintenance of software becomes easier.
• The negative impacts spread slowly.
• The software can be extended easily.
Concurrency
Computer has limited resources and they must be utilized efficiently as much as
possible. To utilize these resources efficiently, multiple tasks must be executed
concurrently. This requirement makes concurrency one of the major concepts of
software design. Every system must be designed to allow multiple processes to
execute concurrently, whenever possible. For example, if the current process is
waiting for some event to occur, the system must execute some other process in the
mean time.
However, concurrent execution of multiple processes sometimes may result in
undesirable situations such as an inconsistent state, deadlock, etc. For example,
consider two processes A and B and a data item Q1 with the value ‘200’. Further,
suppose A and B are being executed concurrently and firstly A reads the value of Q1
(which is ‘200’) to add ‘100’ to it. However, before A updates es the value of Q1, B
reads the value ofQ1 (which is still ‘200’) to add ’50’ to it. In this situation, whether A
or B first updates the value of Q1, the value of would definitely be wrong resulting in
an inconsistent state of the system. This is because the actions of A and B are not
synchronized with each other. Thus, the system must control the concurrent
execution and synchronize the actions of concurrent processes.
One way to achieve synchronization is mutual exclusion, which ensures that two
concurrent processes do not interfere with the actions of each other. To ensure this,
mutual exclusion may use locking technique. In this technique, the processes need to
lock the data item to be read or updated. The data item locked by some process cannot
be accessed by other processes until it is unlocked. It implies that the process, that
needs to access the data item locked by some other process, has to wait.
To develop a complete specification of design (design model), four design models are
needed. These models are listed below.
▪ 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.
▪ 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.
▪ Component-level design: This provides the detailed description of
how structural elements of software will actually be implemented.
▪ Interface design: This depicts how the software communicates with the
system that interoperates with it and with the end-users.