0% found this document useful (0 votes)
3 views

Lesson 3

Uploaded by

sudah15
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Lesson 3

Uploaded by

sudah15
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 29

Design of

Methods
A module is an independent program or code unit that can be
referenced by certain means. A method (as a programming
unit) is a module, so is a group of methods if a language has
a construct to reference such a collection. A class is a
module, as is a (Java) package containing a group of classes.
In this fashion, a module can also be a combination of
methods and classes. A method, with a name to represent
either a procedure (with no “value” returned) or a function
(to return a “value”), is usually the smallest unit of a module
that can be independently referenced. Thus, design of
methods is essential to module design. A method
encapsulates a computational task using the information
from the caller’s code environment. A method typically has
parameters to deliver the information or data the method
needs to complete the task. Overview
A method can be independent, part of a bigger module,
or associated with an object. When a method is
associated with a class, it is often an instance method.
An instance method is often a void method (like a
classic procedure) with a task resulting in modifications
to an object’s state (consisting of current values of
instance data fields). An independent method, often
with a modifier static, can be a function that returns
computed information through a return statement or
out-mode parameters (if the language supports). An
independent method can also be a void method to
update values of variables in an external scope.
Overview
Essential Characteristics of a
Our ability to decomposeMethod
a complex problem depends on our ability
to abstract away the details that can be considered later. Methods
provide a low-level abstraction to encapsulate process details such
as business rules, proprietary practices, algorithms, details for data
source connections, or basic data structures. A method can also use
other methods to delegate some of its implementation complexity.
Thus, methods can also provide higher level abstractions to work
collaboratively with lower-level counterparts. To appropriately design
a method to balance its role between detail encapsulation and high-
level modular abstraction, we need an understanding about general
module attributes expected and the design goals we intend to
achieve
Procedural Abstraction and
Modularity
We use the term procedural abstraction to
describe the notion of abstracting away variations
of method implementations with appropriately
designed parameters. Thus, an invocation of the
method only represents an execution of the
method with a particular set of parameter values.
Procedural abstraction has the following
characteristics (Liskov & Guttag, 2000):
Procedural Abstraction and
Modularity
Parametric abstraction: Parameters of a method abstract away
the input data the method uses, so that the method invoked repeatedly
with different values of parameters completes different variants of a task

Specification abstraction: A specification of a method abstracts


away the implementation details. It says what the method is to do, but
not how to do it. Thus, implementers are free to choose what might be
considered the most appropriate way to implement or alter an existing
implementation without necessarily affecting the applications where the
method is used. A method specification typically includes a description of
the effect of a method invocation, as well as pre and post conditions of
the method. A method has the described effect only when its
preconditions hold. What a method does can be extended, but only to
properties that can be derived by, or inferred from, its post conditions
Design Attributes of a
Method
A method is to abstract a highly concentrated software
action. The term method (or module) cohesion is used
to characterize the degree of interaction within a
module, i.e., the relatedness of code instructions of the
method. It is easy to see that a highly cohesive method
is easier to maintain and that a single task method is
likely cohesive. It does not follow, however, that a
method with multiple tasks would necessarily be less
cohesive or incohesive. Cohesion is not about the
number of tasks in a module.
Design Attributes of a
Method
Decomposition into modules means modules to work together
collaboratively. The further a decomposition is, the more
dependencies are between the modules. Thus, the term method
(or module) coupling is used to describe the degree of
dependency of a module with other modules. Functional
decompositions mitigate software complexity and improve code
comprehension, but decompositions result in module coupling
too. Good coupling is intentional and well thought. Ad hoc
coupling may lead to inappropriate module dependencies that
can increase the vulnerability of a module to potential changes
and reduce the reusability of the modules involved.
Design Attributes of a
Method
It might be intuitive that tighter coupling makes modification
to a method more difficult due to dependencies that changes
in one collaborator may affect others operationally.
Practically, cohesion and couple cannot be achieved optimally
(modules are all highly cohesive with least amount of
coupling); good modularity is to seek a balance between
module readability, reusability, and, more importantly, the
sustainability of the modules. In a balanced design
consideration, we often do give loose coupling a priority,
however, to maximize extendibility of a program.
Illustration of cohesion and
coupling
Cohesion of a Method
A method containing one simple task is likely
cohesive, whereas a method containing multiple
unrelated tasks is likely incohesive. But most
methods we write lie between these two extremes
in terms of cohesion. Indications of potential low
cohesion of a method include:
Cohesion of a Method
A method uses a relatively large of number of
parameters

Only a part of the implementation uses the


parameters

A significant number of code statements do not use


declared local variables
Cohesion of a Method
To quantify a cohesion assessment, we could construct
a flowchart of a method and determine the number of
independent paths that go through different
statements. If a module is of high cohesion, most of
local variables and parameters would be used in
statements in most paths. Thus, the highest cohesion
may be achieved when all independent paths use all
variables (including parameters) in a method. But
practically, a mental inspection is often adequate in
assessing the level of cohesion.
Cohesion of a Method
Module cohesion can be divided into seven levels
depending on the qualified amount of relatedness
of the tasks. The two extreme situations described
above would fit the descriptions of functional
cohesion (the highest cohesion level) and
coincidental cohesion (the lowest cohesion level).
The other five categories are described below in
the order of improved level of cohesion (though
not linearly):
Cohesion of a Method
Logical cohesion refers to a series of actions to be performed, but only
one is selected at a time by the calling module with a parametric indicator
evaluated in conditionals
Temporal cohesion means a series of actions to be performed, but all
related in time.
Procedural cohesion is like temporal cohesion with a difference that all
actions are related by a procedure or an algorithm
Communicational cohesion strengthens procedural cohesion with an
additional characteristic that all the actions operate on the same data.
Sequential cohesion strengthens communicational cohesion further
with an addition that one action uses the result of another.
Cohesion of a Method
Intuitively, a method that executes all tasks would be of
higher cohesion than one that invokes only some of the
tasks in any given call instance. A method with multiple
tasks in which one task relies on another in a sequence
without exception would be of higher cohesion, as the
tasks are inseparably related, than a method where tasks
merely operate on the same data. In other words, whether
a method is cohesive is measured by the relatedness of
the tasks, not by the number of tasks or by the level of
complexity of the code. Thus, we can characterize the
cohesion levels above in terms of relatedness of the tasks
in a method as follows:
Cohesion of a Method
Coincidental cohesion—Tasks are not at all related

Logical cohesion—Tasks may be unrelated, but each invocation


executes only one task
Temporal or procedural cohesion—Tasks are bundled together in time
or based on a procedure, though tasks may not be related to each other
Communicational cohesion—Tasks are not necessarily directly related
to each other yet share the same theme and use the same data and are
all executed in any single call
Sequential cohesion—One task can’t be completed without another,
typically in a sequential fashion
Functional cohesion—There is only one task (of possibly high
complexity with support modules)
Method Coupling
Functional decomposition inevitably leads to module coupling as
details are extracted into modules at different levels of a design.
Module coupling generally improves code reuse, code clarity, and
hence code readability. Module coupling also supports appropriate
code separation to allow independent code development and
update. Coupling is also a way to tame code complexity by
delegating complex tasks for other modules to handle. However, too
much coupling, especially harmful coupling, can make the code
more rigid, easy to break, and more difficult to change. Ad hoc
coupling may fragment the code with little long-term benefit.
Therefore, module coupling should always be appropriately devised
and assessed
Effects of Coupling
Tightly coupled modules tend to cause one or more of the
following effects:
A change in one module may result in a ripple effect of changes in other
modules
System integration may become more complex due to strong or tight
inter-module dependencies
Reuse of modules may become harder because of a tight dependency on
other modules
Unit testing becomes more difficult due to complex testing environment
setups to address module dependencies
Effects of Coupling
It’s easy to see the effect of bad module coupling when an algorithm is
fragmented into ad hoc pieces, buried in separate methods, resulting in code
rigidity. As mentioned earlier, a design of parametric abstraction also has
implications to module coupling. To make a module more independent,
reusable, reliable, sustainable, and clearly understood, design of parameters is
typically based on these considerations:
Provide adequate input information an implementation needs

Facilitate module reuse

Keep preconditions simple and easy to verify

Use intention-revealing names


Categorization of Coupling
In the literature (Stevens et al., 1974), module coupling is categorized with five
levels of coupling tightness as follows (listed in a decreased level of coupling):
Content Coupling occurs when one module uses the code of another
module when the content cannot be independently separated. Code
statements or blocks can be labeled in some programming languages,
and one can use traditional “GOTO” construct to create jumps between
distant statements, or jump in or out of code blocks, causing code
contents to couple. If we separate a coherent piece of code into modules
with no clear intent how each module would be used independently,
content coupling may also occur
Common Coupling occurs when several modules have access to the
same data in a larger scope. As discussed above, this level of coupling
can lead to uncontrolled error propagation and make debugging very
difficult.
Categorization of Coupling
Control Coupling occurs when a module’s code logic is controlled by
controlling parameters from a caller as discussed in detail earlier. Control
coupling and logical cohesion are connected to each other

Stamp Coupling occurs when modules share a composite data structure


and use only parts of it, possibly different parts. A commonly seen
situation of stamp coupling is to pass a composite data structure to
different methods that modify different parts of the data structure

Data Coupling occurs when modules share data through parameters.


Each data parameter is used in its entirety. There are no other forms of
information sharing between the modules. The computation of standard
deviation above using a method to compute the mean is a good example
Module Redesign and Code
Refactoring
Module redesign involves tradeoffs too.
Extracting code into new classes introduces
additional code layers to the program structure
and new code coupling (with potentially less
efficient code). In this example, code complexity
with poor readability is traded for some structural
complexity with much improved module
comprehension and (arguably) reduced code
complexity.
Module Redesign and Code
Refactoring
Professionals use the term code smell to refer to a
surface indication that may suggest a deeper
problem in the code or the design. Use of public or
global variables, nested loops, long list of
parameters, data-only classes, and making extensive
comments on a piece of code, among others, can all
be code smells. Code refactoring is a mechanism for
code improvement or for retrofitting the code to
implement changes to the software requirements
(Fowler, 2018).
Module Redesign and Code
Refactoring
Design paradigm may also have ramifications on module redesign or code
refactoring. Structured design decomposes processes into smaller ones
with functional modules to reduce complexity and increase reusability. It
addresses the behavioral aspect of a software system separately from its
data. Because of the separation of data from functional modules, module
redesign or code refactoring can be less consequential. Adding or
removing modules likely affects the design and code only locally if
essential decompositions remain unaltered. For object-oriented design,
however, adding or removing object types may require regrouping of data
and methods that are currently in different layers of the design, resulting
in possible changes to the program’s structure and inheritance
hierarchies. Such changes must be done manually. Therefore, sound initial
design decisions based on solid analysis and modeling are fundamentally
important to make module redesign and code refactoring meaningful.
Module Redesign and Code
A module’s Refactoring
specification is the basis for
understanding the module’s functionality and correct
construction of the module. Module specifications can
also be used to reason about system decomposition
and functional modularity. Software requirements
derive module specifications, which, in turn, validate
the requirements in a requirement engineering
process. A specification is also a technical contract,
based on which we engage with software estimation,
project planning, and business negotiations.
The Nature of a Module
Specification
Given all the stakes, a module specification must be not only correct but
also precise. Precision of a specification means the following (Parnas,
1972b):
The specification must provide to users all the information that they will
need to use the method correctly and nothing more

The specification must provide to implementers all the information about


the intended use to complete an implementation and nothing more (other
than a possible contextual impact when a call is made)
The specification must be sufficiently formal to avoid any potential
inconsistency, incompleteness (of all possible uses), and potential loss of
any desirable properties of a specification (such as clarity, conciseness,
specificity, etc.)
The Nature of a Module
Specification
A method specification involves pre- and postconditions.
Preconditions of a method are assertions (i.e.,
statements that are either true or false) generally about:

Operational constraints that must hold true at the time


the method is called

Conditions for data validity, where data includes the


arguments and external values the method may use
THANK
YOU!

You might also like