Design Principles Patterns
Design Principles Patterns
Once the requirements document for the software to be developed is available, the software
design phase begins. While the requirements 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 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 make to achieve the desired
functionally 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.
Software design should correspond to the analysis model: Often a design element
corresponds to many requirements therefore we must know how the design model
satisfies all the requirements represented the analysis model.
Software design should be flexible: Software sign should be flexible enough to adapt
changes easily. To achieve the flexibility, the basic design concepts such as abstraction,
refinement, and modularity should be applied effectively.
Software design should ensure minimal conceptual (semantic) errors: The design team
must ensure that major conceptual errors of design such as ambiguousness and
inconsistency are addressed in advance before dealing with the syntactical errors
present in the design model.
Software design should represent correspondence between the software and real-
world problem: The software design should be structured in such away that it always
relates with the real-world problem.
Software reuse: Software engineers believe on the phrase: ‘do not reinvent the wheel’.
Therefore, software components should be designed in such a way that they can be
effectively reused to increase the productivity.
Designing for testability: A common practice that has been followed is to keep the
testing phase separate from the design and implementation phases. That is, first the
software is developed (design and implemented) and then handed over to the testers
who subsequently determine whether the software is fit for distribution and subsequent
use by the customer. However, it has become apparent that the process of separating
testing is seriously flawed, as if any type of design or implementation errors are found
after implementation, then the entire or a substantial part of the software requires to
be redone. Thus, the test engineers should be involved from the initial stages. For
example, they should be involved with analysis to prepare tests for determining
whether the user requirements are being met.
Prototyping: Prototyping should be used when the requirements are not completely
defined in the beginning. The user interacts with the developer to expand and refine the
requirements as the development proceeds. Using prototyping, a quick ‘mock-up’ of the
system can be developed. This mock-up can be used as a effective means to give the
users a feel of what the system will look like and demonstrate functions that will be
included in the developed system. Prototyping also helps in reducing risks of designing
software that is not in accordance with the customer’s requirements.
Note that design principles are often constrained by the existing hardware configuration, the
implementation language, the existing file and data structures, and the existing organizational
practices. Also, the evolution of each software design should be meticulously designed for
future evaluations, references and maintenance.
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 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 in important things at a time. As an entity,
it refers to a model or view of an item.
Each step in the software process is accomplished through various levels of abstraction. At the
highest level, an outline of the solution to the problem is presented whereas at the lower
levels, the solution to the problem is presented in detail. For example, in the requirements
analysis phase, a solution to the problem is presented using the language of problem
environment and as we proceed through the software process, the abstraction level reduces
and at the lowest level, source code of the software is produced.
There are three commonly used abstraction mechanisms in software design, namely,
functional abstraction, data abstraction and control abstraction. All these mechanisms allow
us to control the complexity of the design process by proceeding from the abstract design
model to concrete design model in a systematic manner.
Data abstraction: This involves specifying data that describes a data object. For
example, the data object window encompasses a set of attributes (window type,
window dimension) that describe the window object clearly. In this abstraction
mechanism, representation and manipulation details are ignored.
Control abstraction: this states the desired effect, without stating the exact mechanism
of control. For example, if and while statements in programming languages (like C and
C++) are abstractions of machine code implementations, which involve conditional
instructions. In the architectural design level, this abstraction mechanism permits
specifications of sequential subprograms and exception handlers without the concern
for exact details of implementation.
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 among them. The software architecture enable the software engineers to analyse
the software design efficiently. In addition, it also helps them in decision-making and handling.
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.
Note that software architecture comprises two elements of design model, namely, data design
and architectural design.
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 and insight to designer whoi can determine the following
Software engineer can use the design pattern during the entire software design process. When
the analysis model is developed, the designer can examine the problem description at
different levels of abstraction to determine whether it complies with one or more of the
following types of design pattern.
Architectural patterns: These patterns are high-level strategies that refer to the overall
structure and organization of a software system. That is, they define the elements of a
software system such as subsystems, components, classes, etc. In addition, they also
indicate the relationship between the elements along with the rules and guidelines for
specifying these relationships. Note that architectural patterns are often considered
equivalent to software architecture.
Design patterns: These patterns are medium-level strategies that are used to solve
design problems. They provide a means for the refinement of the elements (as defined
by architectural pattern) of a software system or the relationship among them. Specific
design elements such as relationship among components or mechanisms that affect
component-to-component interaction are addressed by design patterns. Note that
design patterns are often considered equivalent to software components.
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 effect required to integrate the modules.
Modularizing a design helps to plan the development in a more effective manner,
accommodate change easily, conduct testing and debugging effectively and efficiently, and
conduct maintenance work without adversely affecting the functioning of the software.
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 techniques 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.
Stepwise Refinement
Stepwise refinement is a top-down design strategy used for decomposing a system from a high
level abstraction into a more detailed level (lower 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.
INPUT
PROCESS
OUTPUT
This is the first step in refinement. The input phase can be refined further as given here.
INPUT
o Get user’s name through a prompt.
o Get user’s grade through a prompt.
o 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 behavior 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
conhesion (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.
Structureal 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
contrik modules are used to communicate between functions and execute the functions.
Structural partitioning provides the following benefits.
Besides these advantages, horizontal partitioning has some disadvantage also. It requires to
pass more data across the module interface, which makes the control flow of the problem
more complex. This usually happens in cases where data moves rapidly from one function to
another.
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 concurrently 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 ebent to occur, the system must execute
some other process in the mean time.
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 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.
Developing a Design Model
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 syste, that
interoperates with it and with the end –users.