Software Design
Contents
• Overview
• Good characteristics of software design
• Function oriented design
• Object oriented design
• UML diagrams
• Design patterns
Introduction
• Software design is a process to transform user
requirements into some suitable form, which helps the
programmer in software coding and implementation.
• For assessing user requirements, an SRS (Software
Requirement Specification) document is created
whereas for coding and implementation, there is a
need of more specific and detailed requirements in
software terms.
• The output of this process can directly be used into
implementation in programming languages.
• Software design is the first step in SDLC
(Software Design Life Cycle), which moves the
concentration from problem domain to
solution domain. It tries to specify how to
fulfill the requirements mentioned in SRS.
Software Design Levels
Software design yields three levels of results:
Architectural Design -
• The architectural design is the highest abstract version of the system.
• It identifies the software as a system with many components interacting
with each other. At this level, the designers get the idea of proposed
solution domain.
High-level Design-
• The high-level design breaks the ‘single entity-multiple component’
concept of architectural design into less-abstracted view of sub-systems
and modules and depicts their interaction with each other.
• High-level design focuses on how the system along with all of its
components can be implemented in forms of modules. It recognizes
modular structure of each sub-system and their relation and interaction
among each other.
Detailed Design-
• Detailed design deals with the implementation
part of what is seen as a system and its sub-
systems in the previous two designs.
• It is more detailed towards modules and their
implementations. It defines logical structure of
each module and their interfaces to
communicate with other modules.
Modularization
• Modularization is a technique to divide a software system into
multiple discrete and independent modules, which are
expected to be capable of carrying out task(s) independently.
These modules may work as basic constructs for the entire
software.
• Designers tend to design modules such that they can be
executed and/or compiled separately and independently.
• Modular design unintentionally follows the rules of ‘divide and
conquer’ problem-solving strategy this is because there are
many other benefits attached with the modular design of a
software.
Advantage of modularization:
• Smaller components are easier to maintain
• Program can be divided based on functional aspects
• Desired level of abstraction can be brought in the
program
• Components with high cohesion can be re-used
again
• Concurrent execution can be made possible
• Desired from security aspect
Concurrency
• Back in time, all software are meant to be executed
sequentially. By sequential execution we mean that the coded
instruction will be executed one after another implying only
one portion of program being activated at any given time. Say,
a software has multiple modules, then only one of all the
modules can be found active at any time of execution.
• In software design, concurrency is implemented by splitting
the software into multiple independent units of execution, like
modules and executing them in parallel. In other words,
concurrency provides capability to the software to execute
more than one part of code in parallel to each other.
• It is necessary for the programmers and
designers to recognize those modules, which
can be made parallel execution.
Example
• The spell check feature in word processor is a
module of software, which runs along side the
word processor itself.
Coupling and Cohesion
• When a software program is modularized, its tasks are divided into
several modules based on some characteristics.
• As we know, modules are set of instructions put together in order to
achieve some tasks. They are though, considered as single entity but
may refer to each other to work together.
• There are measures by which the quality of a design of modules and
their interaction among them can be measured. These measures are
called coupling and cohesion.
Cohesion
• Cohesion is a measure that defines the degree of intra-dependability
within elements of a module. The greater the cohesion, the better is
the program design.
There are seven types of cohesion, namely –
• Co-incidental cohesion - It is unplanned and random cohesion, which
might be the result of breaking the program into smaller modules for
the sake of modularization. Because it is unplanned, it may serve
confusion to the programmers and is generally not-accepted.
• Logical cohesion - When logically categorized elements are put
together into a module, it is called logical cohesion.
• Temporal Cohesion - When elements of module are organized such
that they are processed at a similar point in time, it is called temporal
cohesion.
• Procedural cohesion - When elements of module are grouped
together, which are executed sequentially in order to perform a task, it
is called procedural cohesion.
• Communicational cohesion - When elements of module are
grouped together, which are executed sequentially and work
on same data (information), it is called communicational
cohesion.
• Sequential cohesion - When elements of module are grouped
because the output of one element serves as input to another
and so on, it is called sequential cohesion.
• Functional cohesion - It is considered to be the highest
degree of cohesion, and it is highly expected. Elements of
module in functional cohesion are grouped because they all
contribute to a single well-defined function. It can also be
reused.
Coupling
• Coupling is a measure that defines the level of inter-
dependability among modules of a program. It tells at what
level the modules interfere and interact with each other. The
lower the coupling, the better the program.
• There are five levels of coupling, namely -
• Content coupling - When a module can directly access or
modify or refer to the content of another module, it is called
content level coupling.
• Common coupling- When multiple modules have read and
write access to some global data, it is called common or global
coupling.
• Control coupling- Two modules are called control-coupled
if one of them decides the function of the other module or
changes its flow of execution.
• Stamp coupling- When multiple modules share common
data structure and work on different part of it, it is called
stamp coupling.
• Data coupling- Data coupling is when two modules interact
with each other by means of passing data (as parameter).
If a module passes data structure as parameter, then the
receiving module should use all its components.
• Ideally, no coupling is considered to be the best.
Design Verification
• The output of software design process is
design documentation, pseudo codes, detailed
logic diagrams, process diagrams, and detailed
description of all functional or non-functional
requirements.
• The next phase, which is the implementation
of software, depends on all outputs
mentioned above.
• It is then becomes necessary to verify the output before
proceeding to the next phase. The early any mistake is
detected, the better it is or it might not be detected until
testing of the product. If the outputs of design phase are
in formal notation form, then their associated tools for
verification should be used otherwise a thorough design
review can be used for verification and validation.
• By structured verification approach, reviewers can detect
defects that might be caused by overlooking some
conditions. A good design review is important for good
software design, accuracy and quality.
Good Characteristics of Software Design
• For good quality software to be produced, the software
design must also be of good quality. Now, the matter of
concern is how the quality of good software design is
measured? This is done by observing certain factors in
software design. These factors are:
• Correctness
• Understandability
• Efficiency
• Maintainability
Now, let us define each of them in detail,
1) Correctness
• First of all, the design of any software is evaluated for
its correctness.
• The evaluators check the software for every kind of
input and action and observe the results that the
software will produce according to the proposed
design.
• If the results are correct for every input, the design is
accepted and is considered that the software produced
according to this design will function correctly.
2) Understandability
• The software design should be understandable so that the
developers do not find any difficulty to understand it.
• Good software design should be self- explanatory. This is
because there are hundreds and thousands of developers
that develop different modules of the software, and it
would be very time consuming to explain each design to
each developer.
• So, if the design is easy and self- explanatory, it would be
easy for the developers to implement it and build the same
software that is represented in the design.
3) Efficiency
• The software design must be efficient.
• The efficiency of the software can be estimated from the
design phase itself, because if the design is describing
software that is not efficient and useful, then the developed
software would also stand on the same level of efficiency.
• Hence, for efficient and good quality software to be
developed, care must be taken in the designing phase itself.
4) Maintainability
• The software design must be in such a way that modifications
can be easily made in it.
• This is because every software needs time to time
modifications and maintenance. So, the design of the software
must also be able to bear such changes.
• It should not be the case that after making some modifications
the other features of the software start misbehaving.
• Any change made in the software design must not affect the
other available features, and if the features are getting
affected, then they must be handled properly.
Software Design Strategies
• Software design is a process to conceptualize the
software requirements into software
implementation.
• Software design takes the user requirements as
challenges and tries to find optimum solution.
• While the software is being conceptualized, a plan is
chalked out to find the best possible design for
implementing the intended solution.
• There are multiple variants of software design. Let
us study them briefly:
• Structured Design
• Function Oriented Design
• Object Oriented Design
Structured design
• Structured design is a conceptualization of problem into several well-
organized elements of solution. It is basically concerned with the
solution design.
• Benefit of structured design is, it gives better understanding of how
the problem is being solved.
• Structured design also makes it simpler for designer to concentrate on
the problem more accurately.
• Structured design is mostly based on ‘divide and conquer’ strategy
where a problem is broken into several small problems and each small
problem is individually solved until the whole problem is solved.
• The small pieces of problem are solved by means of solution modules.
Structured design emphasis that these modules be well organized in
order to achieve precise solution.
• These modules are arranged in hierarchy. They
communicate with each other. A good structured
design always follows some rules for communication
among multiple modules, namely -
• Cohesion - grouping of all functionally related
elements.
• Coupling - communication between different
modules.
• A good structured design has high cohesion and low
coupling arrangements.
Function Oriented Design
• In function-oriented design, the system is comprised of many
smaller sub-systems known as functions. These functions are
capable of performing significant task in the system. The
system is considered as top view of all functions.
• Function oriented design inherits some properties of structured
design where divide and conquer methodology is used.
• This design mechanism divides the whole system into smaller
functions, which provides means of abstraction by concealing
the information and their operation.. These functional modules
can share information among themselves by means of
information passing and using information available globally.
• Another characteristic of functions is that
when a program calls a function, the function
changes the state of the program, which
sometimes is not acceptable by other
modules.
• Function oriented design works well where
the system state does not matter and
program/functions work on input rather than
on a state.
Design Process
• The whole system is seen as how data flows in
the system by means of data flow diagram.
• DFD depicts how functions changes data and
state of entire system.
• The entire system is logically broken down into
smaller units known as functions on the basis of
their operation in the system.
• Each function is then described at large.
Object Oriented Design
• Object oriented design works around the entities and their characteristics
instead of functions involved in the software system. This design strategies
focuses on entities and its characteristics. The whole concept of software
solution revolves around the engaged entities.
• Let us see the important concepts of Object Oriented Design:
• Objects - All entities involved in the solution design are known as objects.
For example, person, banks, company and customers are treated as
objects. Every entity has some attributes associated to it and has some
methods to perform on the attributes.
• Classes - A class is a generalized description of an object. An object is an
instance of a class. Class defines all the attributes, which an object can have
and methods, which defines the functionality of the object.
• In the solution design, attributes are stored as variables and functionalities
are defined by means of methods or procedures.
• Encapsulation - In OOD, the attributes (data variables) and methods
(operation on the data) are bundled together is called encapsulation.
Encapsulation not only bundles important information of an object together,
but also restricts access of the data and methods from the outside world. This
is called information hiding.
• Inheritance - OOD allows similar classes to stack up in hierarchical manner
where the lower or sub-classes can import, implement and re-use allowed
variables and methods from their immediate super classes. This property of
OOD is known as inheritance. This makes it easier to define specific class and
to create generalized classes from specific ones.
• Polymorphism - OOD languages provide a mechanism where methods
performing similar tasks but vary in arguments, can be assigned same name.
This is called polymorphism, which allows a single interface performing tasks
for different types. Depending upon how the function is invoked, respective
portion of the code gets executed.
Design Process
• Software design process can be perceived as series of well-
defined steps. Though it varies according to design approach
(function oriented or object oriented, yet It may have the
following steps involved:
• A solution design is created from requirement or previous
used system and/or system sequence diagram.
• Objects are identified and grouped into classes on behalf of
similarity in attribute characteristics.
• Class hierarchy and relation among them is defined.
• Application framework is defined.
Software Design Approaches
Here are two generic approaches for software designing:
Top Down Design
• We know that a system is composed of more than one sub-systems and it contains
a number of components. Further, these sub-systems and components may have
their on set of sub-system and components and creates hierarchical structure in
the system.
• Top-down design takes the whole software system as one entity and then
decomposes it to achieve more than one sub-system or component based on some
characteristics. Each sub-system or component is then treated as a system and
decomposed further. This process keeps on running until the lowest level of system
in the top-down hierarchy is achieved.
• Top-down design starts with a generalized model of system and keeps on defining
the more specific part of it. When all components are composed the whole system
comes into existence.
• Top-down design is more suitable when the software solution needs to be
designed from scratch and specific details are unknown.
Bottom-up Design
• The bottom up design model starts with most specific and
basic components. It proceeds with composing higher level of
components by using basic or lower level components. It keeps
creating higher level components until the desired system is
not evolved as one single component. With each higher level,
the amount of abstraction is increased.
• Bottom-up strategy is more suitable when a system needs to
be created from some existing system, where the basic
primitives can be used in the newer system.
• Both, top-down and bottom-up approaches are not practical
individually. Instead, a good combination of both is used.
Unified Modeling Language (UML)
• Unified Modeling Language (UML) is a general purpose modelling
language. The main aim of UML is to define a standard way
to visualize the way a system has been designed. It is quite similar to
blueprints used in other fields of engineering.
• UML is not a programming language, it is rather a visual language. We
use UML diagrams to portray the behavior and structure of a system.
UML helps software engineers, businessmen and system architects
with modelling, design and analysis.
• The Object Management Group (OMG) adopted Unified Modelling
Language as a standard in 1997. Its been managed by OMG ever since.
• International Organization for Standardization (ISO) published UML as
an approved standard in 2005. UML has been revised over the years
and is reviewed periodically.
Do we really need UML?
• Complex applications need collaboration and planning
from multiple teams and hence require a clear and
concise way to communicate amongst them.
• Businessmen do not understand code. So UML becomes
essential to communicate with non programmers
essential requirements, functionalities and processes of
the system.
• A lot of time is saved down the line when teams are able
to visualize processes, user interactions and static
structure of the system.
• UML is linked with object oriented design and analysis. UML
makes the use of elements and forms associations between
them to form diagrams. Diagrams in UML can be broadly
classified as:
• Structural Diagrams – Capture static aspects or structure of a
system. Structural Diagrams include: Component Diagrams,
Object Diagrams, Class Diagrams and Deployment Diagrams.
• Behavior Diagrams – Capture dynamic aspects or behavior of
the system. Behavior diagrams include: Use Case Diagrams,
State Diagrams, Activity Diagrams and Interaction Diagrams.
Additions in UML 2.0 –
• Software development methodologies like agile have been
incorporated and scope of original UML specification has been
broadened.
• Originally UML specified 9 diagrams. UML 2.x has increased
the number of diagrams from 9 to 13. The four diagrams that
were added are : timing diagram, communication diagram,
interaction overview diagram and composite structure
diagram. UML 2.x renamed state chart diagrams to state
machine diagrams.
• UML 2.x added the ability to decompose software system into
components and sub-components.
Design Patterns
• In software engineering, a design pattern is a
general repeatable solution to a commonly
occurring problem in software design.
• A design pattern isn't a finished design that
can be transformed directly into code.
• It is a description or template for how to solve
a problem that can be used in many different
situations.
Uses of Design Patterns
• Design patterns can speed up the development
process by providing tested, proven development
paradigms.
• Effective software design requires considering
issues that may not become visible until later in the
implementation.
• Reusing design patterns helps to prevent subtle
issues that can cause major problems and improves
code readability for coders and architects familiar
with the patterns.
• people only understand how to apply certain software
design techniques to certain problems. These techniques
are difficult to apply to a broader range of problems.
• Design patterns provide general solutions, documented
in a format that doesn't require specifics tied to a
particular problem.
• In addition, patterns allow developers to communicate
using well-known, well understood names for software
interactions.
• Common design patterns can be improved over time,
making them more robust than ad-hoc designs.
• There are 23 classic design patterns, although there
are at least 26 design patterns discovered to date.
• These design patterns gained popularity after the
publication of Design Patterns: Elements of
Reusable Object-Oriented Software, a 1994 book
published by the “Gang of Four” (GoF): Erich
Gamma, Richard Helm, Ralph Johnson, and John
Vlissides.
• Due to this, the 23 design patterns are often known
as the gang of four design patterns.
• Design patterns can be broken down into
three types, organized by their intent into
creational design patterns, structural design
patterns, and behavioral design patterns.
Creational Design Patterns
• A creational design pattern deals with object creation and
initialization, providing guidance about which objects are created
for a given situation. These design patterns are used to increase
flexibility and to reuse existing code.
• Factory Method: Creates objects with a common interface and lets
a class defer instantiation to subclasses.
• Abstract Factory: Creates a family of related objects.
• Builder: A step-by-step pattern for creating complex objects,
separating construction and representation.
• Prototype: Supports the copying of existing objects without code
becoming dependent on classes.
• Singleton: Restricts object creation for a class to only one instance.
Structural Design Patterns
• A structural design pattern deals with class and object composition, or
how to assemble objects and classes into larger structures.
• Adapter: How to change or adapt an interface to that of another
existing class to allow incompatible interfaces to work together.
• Bridge: A method to decouple an interface from its implementation.
• Composite: Leverages a tree structure to support manipulation as one
object.
• Decorator: Dynamically extends (adds or overrides) functionality.
• Façade: Defines a high-level interface to simplify the use of a large
body of code.
• Flyweight: Minimize memory use by sharing data with similar objects.
• Proxy: How to represent an object with another object to enable
access control, reduce cost and reduce complexity.
Behavioral Design Patterns
• A behavioral design pattern is concerned with communication
between objects and how responsibilities are assigned between
objects.
• Chain of Responsibility: A method for commands to be delegated to
a chain of processing objects.
• Command: Encapsulates a command request in an object.
• Interpreter: Supports the use of language elements within an
application.
• Iterator: Supports iterative (sequential) access to collection elements.
• Mediator: Articulates simple communication between classes.
• Memento: A process to save and restore the internal/original state of
an object.
• Observer: Defines how to notify objects of changes
to other object(s).
• State: How to alter the behavior of an object when
its stage changes.
• Strategy: Encapsulates an algorithm inside a class.
• Visitor: Defines a new operation on a class without
making changes to the class.
• Template Method: Defines the skeleton of an
operation while allowing subclasses to refine certain
steps.
Why Do We Need Design Patterns?
Design patterns offer a best practice approach to support object-oriented software design,
which is easier to design, implement, change, test and reuse. These design patterns provide best
practices and structures.
1. Proven Solution
• Design patterns provide a proven, reliable solution to a common problem, meaning the
software developer does not have to “reinvent the wheel” when that problem occurs.
2. Reusable
• Design patterns can be modified to solve many kinds of problems – they are not just tied to a
single problem.
3. Expressive
• Design patterns are an elegant solution.
4. Prevent the Need for Refactoring Code
• Since the design pattern is already the optimal solution for the problem, this can avoid
refactoring.
5. Lower the Size of the Codebase
• Each pattern helps software developers change how the system works without a full
redesign. Further, as the “optimal” solution, the design pattern often requires less code.