Software Design
Software design is a mechanism to transform user requirements into some suitable form, which
helps the programmer in software coding and implementation. It deals with representing the
client's requirement, as described in the SRS (Software Requirement Specification) document, in
a form, i.e., easily implementable using programming language.
The software design phase is the first step in SDLC (Software Design Life Cycle), which moves
the concentration from the problem domain to the solution domain. In software design, we
consider the system to be a set of components or modules with clearly defined behaviors &
boundaries.
Objectives of Software Design
Following are the purposes of Software design:
1. Correctness:Software design should be correct as per requirement.
2. Completeness:The design should have all components like data structures, modules, and
external interfaces, etc.
3. Efficiency:Resources should be used efficiently by the program.
4. Flexibility:Able to modify on changing needs.
5. Consistency:There should not be any inconsistency in the design.
6. Maintainability: The design should be so simple so that it can be easily maintainable by
other designers.
Software Design Principles
Software design principles are concerned with providing means to handle the complexity of the
design process effectively. Effectively managing the complexity will not only reduce the effort
needed for design but can also reduce the scope of introducing errors during design.
Following are the principles of Software Design
Problem Partitioning
For small problem, we can handle the entire problem at once but for the significant problem,
divide the problems and conquer the problem it means to divide the problem into smaller pieces
so that each piece can be captured separately.
For software design, the goal is to divide the problem into manageable pieces.
Benefits of Problem Partitioning
1. Software is easy to understand
2. Software becomes simple
3. Software is easy to test
4. Software is easy to modify
5. Software is easy to maintain
6. Software is easy to expand
These pieces cannot be entirely independent of each other as they together form the system. They
have to cooperate and communicate to solve the problem. This communication adds complexity.
Note: As the number of partition increases = Cost of partition and complexity increases
Abstraction
An abstraction is a tool that enables a designer to consider a component at an abstract level
without bothering about the internal details of the implementation. Abstraction can be used for
existing element as well as the component being designed.
Here, there are two common abstraction mechanisms
1. Functional Abstraction
2. Data Abstraction
Functional Abstraction
i. A module is specified by the method it performs.
ii. The details of the algorithm to accomplish the functions are not visible to the user of the
function.
Functional abstraction forms the basis for Function oriented design approaches.
Data Abstraction
Details of the data elements are not visible to the users of data. Data Abstraction forms the basis
for Object Oriented design approaches.
Modularity
Modularity specifies to the division of software into separate modules which are differently
named and addressed and are integrated later on in to obtain the completely functional software.
It is the only property that allows a program to be intellectually manageable. Single large
programs are difficult to understand and read due to a large number of reference variables,
control paths, global variables, etc.
The desirable properties of a modular system are:
• Each module is a well-defined system that can be used with other applications.
• Each module has single specified objectives.
• Modules can be separately compiled and saved in the library.
• Modules should be easier to use than to build.
• Modules are simpler from outside than inside.
Advantages and Disadvantages of Modularity
In this topic, we will discuss various advantage and disadvantage of Modularity.
Advantages of Modularity
There are several advantages of Modularity
• It allows large programs to be written by several or different people
• It encourages the creation of commonly used routines to be placed in the library and used by
other programs.
• It simplifies the overlay procedure of loading a large program into main storage.
• It provides more checkpoints to measure progress.
• It provides a framework for complete testing, more accessible to test
• It produced the well designed and more readable program.
Disadvantages of Modularity
There are several disadvantages of Modularity
• Execution time maybe, but not certainly, longer
• Storage size perhaps, but is not certainly, increased
• Compilation and loading time may be longer
• Inter-module communication problems may be increased
• More linkage required, run-time may be longer, more source lines must be written, and more
documentation has to be done
Modular Design
Modular design reduces the design complexity and results in easier and faster implementation by
allowing parallel development of various parts of a system.
1. Functional Independence: Functional independence is achieved by developing functions that
perform only one kind of task and do not excessively interact with other modules. Independence
is important because it makes implementation more accessible and faster. The independent
modules are easier to maintain, test, and reduce error propagation and can be reused in other
programs as well. Thus, functional independence is a good design feature which ensures
software quality.
It is measured using two criteria:
• Cohesion: It measures the relative function strength of a module.
• Coupling: It measures the relative interdependence among modules.
2. Information hiding: The fundamental of Information hiding suggests that modules can be
characterized by the design decisions that protect from the others, i.e., In other words, modules
should be specified that data include within a module is inaccessible to other modules that do not
need for such information.
The use of information hiding as design criteria for modular system provides the most significant
benefits when modifications are required during testing's and later during software maintenance.
This is because as most data and procedures are hidden from other parts of the software,
inadvertent errors introduced during modifications are less likely to propagate to different
locations within the software.
Strategy of Design
A good system design strategy is to organize the program modules in such a method that are easy
to develop and latter too, change. Structured design methods help developers to deal with the
size and complexity of programs. Analysts generate instructions for the developers about how
code should be composed and how pieces of code should fit together to form a program.
To design a system, there are two possible approaches:
1. Top-down Approach
2. Bottom-up Approach
1. Top-down Approach: This approach starts with the identification of the main components
and then decomposing them into their more detailed sub-components.
2. Bottom-up Approach: A bottom-up approach begins with the lower details and moves
towards up the hierarchy, as shown in fig. This approach is suitable in case of an existing system.
Coupling and Cohesion
Module Coupling
In software engineering, the coupling is the degree of interdependence between software
modules. Two modules that are tightly coupled are strongly dependent on each other. However,
two modules that are loosely coupled are not dependent on each other. Uncoupled modules have
no interdependence at all within them.
The various types of coupling techniques are shown in fig:
A good design is the one that has low coupling. Coupling is measured by the number of relations
between the modules. That is, the coupling increases as the number of calls between modules
increase or the amount of shared data is large. Thus, it can be said that a design with high
coupling will have more errors.
Types of Module Coupling
1. No Direct Coupling: There is no direct coupling between M1 and M2.
In this case, modules are subordinates to different modules. Therefore, no direct coupling.
2. Data Coupling: When data of one module is passed to another module, this is called data
coupling.
3. Stamp Coupling: Two modules are stamp coupled if they communicate using composite data
items such as structure, objects, etc. When the module passes non-global data structure or entire
structure to another module, they are said to be stamp coupled. For example, passing structure
variable in C or object in C++ language to a module.
4. Control Coupling: Control Coupling exists among two modules if data from one module is
used to direct the structure of instruction execution in another.
5. External Coupling: External Coupling arises when two modules share an externally imposed
data format, communication protocols, or device interface. This is related to communication to
external tools and devices.
6. Common Coupling: Two modules are common coupled if they share information through
some global data items.
7. Content Coupling: Content Coupling exists among two modules if they share code, e.g., a
branch from one module into another module.
Module Cohesion
In computer programming, cohesion defines to the degree to which the elements of a module
belong together. Thus, cohesion measures the strength of relationships between pieces of
functionality within a given module. For example, in highly cohesive systems, functionality is
strongly related.
Cohesion is an ordinal type of measurement and is generally described as "high cohesion" or
"low cohesion."
Types of Modules Cohesion
1. Functional Cohesion: Functional Cohesion is said to exist if the different elements of a module,
cooperate to achieve a single function.
2. Sequential Cohesion: A module is said to possess sequential cohesion if the element of a
module form the components of the sequence, where the output from one component of the
sequence is input to the next.
3. Communicational Cohesion: A module is said to have communicational cohesion, if all tasks of
the module refer to or update the same data structure, e.g., the set of functions defined on an
array or a stack.
4. Procedural Cohesion: A module is said to be procedural cohesion if the set of purpose of the
module are all parts of a procedure in which particular sequence of steps has to be carried out
for achieving a goal, e.g., the algorithm for decoding a message.
5. Temporal Cohesion: When a module includes functions that are associated by the fact that all
the methods must be executed in the same time, the module is said to exhibit temporal
cohesion.
6. Logical Cohesion: A module is said to be logically cohesive if all the elements of the module
perform a similar operation. For example Error handling, data input and data output, etc.
7. Coincidental Cohesion: A module is said to have coincidental cohesion if it performs a set of
tasks that are associated with each other very loosely, if at all.
Differentiate between Coupling and Cohesion
Coupling Cohesion
Coupling is also called Inter-Module
Cohesion is also called Intra-Module Binding.
Binding.
Coupling shows the relationships
Cohesion shows the relationship within the module.
between modules.
Coupling shows the relative
Cohesion shows the module's relative functional strength.
independence between the modules.
While creating you should aim for high cohesion, i.e., a cohesive
While creating, you should aim for
component/ module focuses on a single function (i.e., single-
low coupling, i.e., dependency among
mindedness) with little interaction with other modules of the
modules should be less.
system.
In coupling, modules are linked to the
In cohesion, the module focuses on a single thing.
other modules.
Cyclomatic Complexity
Cyclomatic complexity is a source code complexity measurement that is being
correlated to a number of coding errors. It is calculated by developing a Control
Flow Graph of the code that measures the number of linearly-independent paths
through a program module.
A Control Flow Graph (CFG) is the graphical representation of control flow or computation
during the execution of programs or applications.
Flow graph notation for a program:
Flow Graph notation for a program defines several nodes connected through the edges. Below
are Flow diagrams for statements like if-else, While, until and normal sequence of flow.
Example: Control Flow Graph (CFG)
2!=3
1. while (a!=b) {
2. if(a>b)
3. a=a-b;
4. else
5. b=b-a; }
return a;
Cyclomatic Complexity = CC = E-N+2 = 6-5+2= 3
Why Is Cyclomatic Complexity Important?
It can be used in two ways, to:
• Limit code complexity.
• Determine the number of test cases required.
Cyclomatic complexity can be one of the most difficult code metrics to understand. And that
makes it difficult to calculate.
Lower Cyclomatic Complexity = Better Code
Higher numbers of CYC are bad. Lower numbers are good.
That's because code with high complexity is difficult to test. And it's likely to result in errors.
So, code with low complexity is easier to test. And it's less likely to produce errors.
Steps that should be followed in calculating Cyclomatic complexity and test
cases design are:
Construction of graph with nodes and edges from code.
• Identification of independent paths.
• Cyclomatic Complexity Calculation
• Design of Test Cases
Lower the Program's Cyclomatic complexity, lower the risk to modify and easier to understand.
It can be represented using the below formula:
How to Calculate Cyclomatic Complexity?
Cyclomatic complexity = E - N + 2*P
where,
E = number of edges in the flow graph.
N = number of nodes in the flow graph.
P = number of nodes that have exit
points
Let a section of code and Control Flow Graph of such code below:
A = 10
IF B > C
THEN
A = B
ELSE
A = C
ENDIF
Print A
Print B
Print C
The Cyclomatic complexity calculated for above code will be from control flow graph. The
graph shows seven shapes (nodes), seven lines (edges),
hence Cyclomatic complexity is 7-7+2 = 2.
Use of Cyclomatic Complexity:
• Determining the independent path executions thus proven to be very helpful for
Developers and Testers.
• It can make sure that every path has been tested at least once.
• Thus help to focus more on uncovered paths.
• Code coverage can be improved.
• Risk associated with program can be evaluated.
• These metrics being used earlier in the program helps in reducing the risks.
Advantages of Cyclomatic Complexity:.
• It can be used as a quality metric, gives relative complexity of various designs.
• It is able to compute faster than the Halstead’s metrics.
• It is used to measure the minimum effort and best areas of concentration for testing.
• It is able to guide the testing process.
• It is easy to apply.
Disadvantages of Cyclomatic Complexity:
• It is the measure of the programs control complexity and not the data the data complexity.
• In this, nested conditional structures are harder to understand than non-nested structures.
• In case of simple comparisons and decision structures, it may give a misleading figure.
Properties of Cyclomatic complexity:
Following are the properties of Cyclomatic complexity:
1. V (G) is the maximum number of independent paths in the graph
2. V (G) >=1
3. G will have one path if V (G) = 1
4. Minimize complexity to 10