0% found this document useful (0 votes)
30 views40 pages

Part 5

The document provides an overview of software design principles, focusing on the importance of modularity, cohesion, and coupling in creating effective software architectures. It discusses the design phases, including high-level and detailed design, and emphasizes the need for clear module interfaces and functional independence. Additionally, it introduces the open-closed principle, which advocates for extending functionality without modifying existing code to maintain system integrity.

Uploaded by

hasinidhoni1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views40 pages

Part 5

The document provides an overview of software design principles, focusing on the importance of modularity, cohesion, and coupling in creating effective software architectures. It discusses the design phases, including high-level and detailed design, and emphasizes the need for clear module interfaces and functional independence. Additionally, it introduces the open-closed principle, which advocates for extending functionality without modifying existing code to maintain system integrity.

Uploaded by

hasinidhoni1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Software Design

Review
Introduction to software engineering
Life cycle models
Requirements Analysis and Specification:
1) Requirements gathering and analysis
2) Requirements specification

Design phase transforms SRS document into a form easily implementable


in some programming language.

SRS Document Design Activities Design Documents


Review: The waterfall model
Items Designed During Design
Phase: Module
Module Structure
In essence, module consists of several
Control relationship among
functions and associated data structures.
the modules:call relationship
or invocation relationship

Interface among different


modules: data items
exchanged among different
modules

Data structures of individual


modules D1 ..
D2 .. Data
D3 ..
Algorithms for individual
F1 .. Functions
modules F2 ..
F3 ..
F4 ..
F5 ..
Detailed design
Good software designs seldom arrived
through a single step procedure but
through a series of steps and iterations.

Design activities are usually classified into


two stages: preliminary (or high-level)
design and detailed design.
Meaning and scope of the two stages
vary considerably from one methodology
to another.
High-level design
Identify: modules, control relationships among
modules and interfaces among modules.

The outcome of high-level design:


program structure (or software
d1 d2
architecture).
Several notations are available to
d3 d1 d4 represent high-level design:
Usually a tree-like diagram called
structure chart is used.
Good vs bad design

How to distinguish between good and bad designs?


Unless we know what a good software design is, we
can not possibly design one.

There is no unique way to design a system.

Even using the same design methodology: different


engineers can arrive at very different design
solutions.
We need to distinguish between good and bad
designs.
What Is Good Software Design?
Should implement all functionalities of the system correctly.
Should be easily understandable.
Understandability determines goodness of design. An easy
to understand design is
∙ Easy to maintain
∙ Embrace change
∙ Easy to code
∙ Easy to test
∙ And so on….
Improving Understandability
Use consistent and meaningful names for modules
Arrange different modules in a hierarchy like tree-like
diagram.
Decompose modules such that the modules are almost
independent of each other, i.e, modularity. It is a
fundamental attributes of any good design and based on
divide and conquer principle.
If modules are independent: modules can be understood
separately and it reduces the complexity greatly.
Why?
It is very difficult to break a bunch of sticks but very easy
to break the sticks individually.
Example of Cleanly and Non-cleanly
Decomposed Modules

Which one is better?

Consider case of bug in a module.


How many modules we need to test?
Modularity
Modularity means as set of independent modules, which
are impractical to achieve.
Better characterization of modularity in technical terms,
modules should display: high cohesion and low coupling.
These can be useful to tell which design alternative is
better.

Neat arrangement of modules in a hierarchy means low


fan-out
Cohesion and Coupling
Cohesion provides the functional strength of a module. A
cohesive module performs a single task or function.

Coupling between two modules measures the degree of


interdependence or interaction between the two modules.

A module having high cohesion and low coupling is


functionally independent of other modules, i.e., it has
minimal interaction with other modules.
Advantages of Functional Independence

Better understanding. Design complexity is reduced. Different modules are


easy to understand in isolation.

Functional independence reduces error propagation because:


∙ degree of interaction between modules is low
∙ an error existing in one module does not directly affect other modules.

A functionally independent module can be easily taken out and reused


because:
● each module does some well-defined and precise function
● the interfaces of a module with other modules is simple and minimal.

Unfortunately, there are no ways to quantitatively measure the degree of


cohesion and coupling. Hence, classification of different kinds of cohesion
and coupling is useful.
Classification of Cohesiveness
functional
sequential
communicational
Degree of
procedural cohesion

temporal

logical
coincidental

Classification is often subjective:


By examining the type of cohesion exhibited by a module, one can comment whether it
displays high cohesion or low cohesion.
Worst: Coincidental cohesion
The module performs a set of tasks which relate to each other
very loosely, if at all.
The module contains a random collection of functions.
Functions have been put in the module out of pure coincidence
without any thought or design.

Note easy to define the working of module.


Logical cohesion
All elements of the module perform similar operations
like error handling, data input, data output, etc.

An example of logical cohesion is to arrange a set of


print functions to generate an output report arranged
into a single module.
Temporal cohesion
The module contains tasks that are related by the fact
that all the tasks must be executed in the same time
span.

Example: The set of functions responsible for


initialization, start-up, shut-down of some process,
etc.
Procedural cohesion
The set of functions of the module can be decided based
on all part of a procedure (algorithm)
It certain sequence of steps have to be carried out in a
certain order for achieving an objective, e.g. the algorithm
for decoding a message.
Communicational cohesion

All functions of the module sharing common


reference or update the same data structure.
Example: the set of functions defined on an array
or a stack.
Sequential cohesion

Elements of a module form different


parts of a sequence. That is, output
from one element of the sequence is input
to the next.
Example:
sort

search

display
Best: Functional cohesion
Different elements of a module cooperate to achieve
a single function,
e.g. managing an employee's pay-roll.

When a module displays functional cohesion, we can


describe the function using a single sentence.
Determining Cohesiveness

Write down a sentence to describe the function of the module:


● If the sentence is compound, then it has a sequential or
communicational cohesion.
● If it has words like “first”, “next”, “after”, “then”, etc., then
it has sequential or temporal cohesion.
● If it has words like initialize, then it probably has temporal
cohesion.
● Functionally cohesive module can always be described by a simple
statement
High-level Design

High-level design maps functions into


modules such that:
∙ Each module has high cohesion
∙ Coupling among modules is as low as
possible
∙ Modules are organized in a neat hierarchy
Determining Cohesiveness
Coupling

Coupling indicates how closely two modules


interact or how interdependent they are.

The degree of coupling between two modules


depends on their interface complexity.

There are no ways to precisely determine coupling


between two modules but classification of different types
of coupling will help us to approximately estimate the
degree of coupling between two modules.
Classes of coupling

data
stamp
control Degree of
coupling
common
content

Five types of coupling can exist between any


two modules.
Best: Data coupling
Two modules are data coupled, if they
communicate via a parameter:
Example an elementary data item, like an
integer, a float, a character, etc.
Stamp coupling
Two modules are stamp coupled, if they
communicate via a composite data item.
Example a record in PASCAL or a structure in
C.
Control coupling
Data from one module is used to
direct order of instruction execution in
another.
Example of control coupling: a flag set
in one module and tested in another
module.
Common Coupling

Two modules are common coupled,


if they share some global data.
Worst: Content coupling
Content coupling exists between two
modules: if they share code. For e.g,
branching from one module into another
module.
The degree of coupling increases from
data coupling to content coupling.
Neat Hierarchy
Control hierarchy or program structure represents organization of
modules. Most common notation: a tree-like diagram called structure
chart.

Neat arrangement means low fan-out and abstraction. Abstraction is


one of the key concepts of object-oriented programming (OOP)
languages. Its main goal is to handle complexity by hiding unnecessary
details from the user. That enables the user to implement more complex
logic on top of the provided abstraction without understanding or even
thinking about all the hidden complexity.

Fan-out is a measure of the number of modules directly controlled


by given module.

Fan-in indicates how many modules directly invoke a given


module. High fan-in represents code reuse and is in general
encouraged.
Module Structure
Fan out=2

Fan out=1
Fan in=1

Fan in=2
Fan out=0
Goodness of Design

A design having modules with high fan-out numbers is not a good


design as it lacks cohesion.
A module that invokes a large number of other modules likely to
implement several different functions and not likely to perform a
single cohesive function.
Control Relationships:
A module that controls another module is said to be superordinate to it.
Conversely, a module controlled by another module is said to be
subordinate to it.
A module A is said to be visible by another module B, if A directly or
indirectly calls B.
The layering principle requires modules at a layer can call only the
modules immediately below it.
Bad Design

Layered design requires lower-level modules do


not invoke functions of higher level modules.
High-level Design

• f1
• f2
• f3 d1 d2


• d3 d1 d4

• fn
High-level Design

High-level design maps functions into


modules such that:
∙ Each module has high cohesion
∙ Coupling among modules is as low as
possible
∙ Modules are organized in a neat hierarchy
∙ Follow abstraction
∙ Follow open-closed principle
Open-closed Principle
● Besides cohesion and coupling, open closed principle also
helps in achieving modularity
● Principle: A module should be open for extension but
closed for modification
− Behavior can be extended to accommodate new requirements, but
existing code is not modified
− I.e. allows addition of code, but not modification of existing code
− Minimizes risk of having existing functionality stop working due to
changes – a very important consideration while changing code
− Good for programmers as they like writing new code
Open-closed Principle…
● In OO this principle is satisfied by using
inheritance and polymorphism
● Inheritance allows creating a new class to extend
behavior without changing the original class
● This can be used to support the open-closed
principle
● Consider example of a client object which
interacts with a object for accessing GPU
services from COLAB.
Thanks

You might also like