Chapter 1 Introduction-2
Chapter 1 Introduction-2
Introduction
Software maintainability is critical to the Software Development Life
Cycle (SDLC), as poor code quality, defects, and dead code significantly
increase maintenance costs and effort. Just as a failing heart endangers life,
neglecting maintainability renders software difficult to modify, effectively
"killing" the codebase. While various metrics exist for aspects like
coupling and cohesion, no single metric fully captures maintainability. To
combat this, developers use automatic and semi-automatic solutions to
prevent bad design practices and remove "code smells" surface indicators
of deeper problems that degrade software quality. These smells, often
resulting from violating Object-Oriented (OO) principles due to budget
constraints or inexperience, make code complex and expensive to manage.
Refactoring Sequencing is a crucial method for improving internal code
quality without altering external behavior, thereby reducing complexity,
detecting bugs, and enhancing maintainability and extensibility.
Companies like Microsoft have demonstrated the value of refactoring, and
its integration into methodologies like Extreme Programming highlights its
growing importance. As refactoring is a sequential process, applying it
intelligently in small, controlled cycles is vital to avoid introducing new
bugs and to achieve optimal results within time and budget. Current
research is increasingly focused on two key areas: understanding the
impact of refactorings on code quality and, more advanced, identifying
optimal refactoring sequences in advance to streamline maintenance
efforts.
1
1.1 Software Maintenance
The goal of software maintenance is to modify and update application programs
after they have been delivered, in order to correct errors and enhance
performance. Software changes should be made whenever necessary. Once a
software product has been delivered to the customer, any modifications are
carried out through the process of software maintenance. This process is essential
for the following reasons:
1. To correct existing errors.
2. To improve compatibility and integration with other systems.
3. To ensure the software can function with various types of hardware,
software, system features, and telecommunications equipment.
4. To update and modernize obsolete software.
3. The third step is to enquire the Updation that the user wants to include
in the software application that made the quest before accepting the
process.
2
Thus, hence the updated as well as changed product is handed to the
customer afterwards. The updated software needs to be changed
whenever feasible. The figure1.1 shows the software maintenance step by
step.
1
[Link]
3
Analysis
Design
Implementation
Updation Modify
System Testing
Delivery
Analysis Testing
4
operation.
5
These are four categories of software that help ensure the software as a
whole operates as intended is as shown in figure 1.2 with the amount of
percentage of their respective purpose.
Software quality refers to how well a product aligns with its original design and
how effectively that design was created. It is often described in terms of the
software’s overall suitability. One of the essential phases of the software lifecycle
is software maintenance. Understanding what software maintenance is and
recognizing its importance is crucial for any software organization, as it plays a
central role in the overall application development process.
The software development lifecycle does not end once the software is built. After
deployment, the software must be continually monitored and maintained. It is the
responsibility of developers to ensure that the software continues to run smoothly
and that users can access and utilize all features effectively. This ongoing support
6
is the function of software maintenance.
Software maintenance ensures the continued operation of the system and allows it
to adapt to future changes. It also enhances features and makes improvements to
meet evolving user needs. As the final phase of the software lifecycle, its primary
objective is to implement necessary modifications to correct errors, address bugs,
and maintain optimal performance.
8
2. Non sensual timetables: Sound software development practices are
9
possess comprehensive expertise across all these layers.
Misunderstandings or incorrect assumptions about how unfamiliar
platforms function often result in non-functional defects, which can
cause serious issues such as system failures, data breaches, and
unauthorized access during operation.
10
1.1.5 Need of Software Maintenance
Software maintenance is required for a variety of reasons, as noted below:
1. Errors to be removed:
One of the most essential functions of software maintenance is correcting errors,
commonly referred to as "bugs." Ensuring that the software operates without
faults is critical for its reliability and effectiveness. Prioritizing this task is
important, as it involves identifying and fixing issues within the code. These
problems can originate from hardware, operating systems, or any other software
component. This maintenance activity helps retain the functionality of legacy
systems and prevents disruptions in operations.
4. Enhancement of performance:
To meet growing user demands and improve system productivity, performance
upgrades are often necessary. Software maintenance may include optimizing data
processing, refining encoding standards, and even undertaking re-engineering
initiatives. These improvements help enhance the system’s stability and security,
making it more resilient to failures and vulnerabilities. Maintaining performance
is key to ensuring that the software evolves safely without introducing harmful or
disruptive behavior.
Code smells are now widely used to identify weaknesses in user interface design
and system architecture that could lead to complications during future
development. Consequently, it is commonly recommended to refactor problematic
code to prevent or mitigate such risks. However, refactoring introduces both
financial costs and potential risks, highlighting the need for empirical studies to
better understand the connection between code smells and the necessity for
software maintenance.
"What you cannot measure, you cannot control" Thus software needs to
be maintained and measured timely with the purpose to get utmost
enforcement of the software. To accurately assess the size of software,
several key factors must be considered—such as code reusability,
development effort, data redundancy, and complexity. Even when two
systems provide similar functionalities, the perceived complexity may
vary depending on the developers involved. For example, an experienced
programmer may produce a smaller and more efficient application, yet
the overall functionality and development effort may remain comparable
or even increase due to greater complexity, data repetition, and reuse of
components.
The traditional procedural programming approach has evolved into the
more advanced object-oriented paradigm. Object-oriented programming
(OOP), which models software around real-world entities, is now a
widely adopted methodology. Java is a notable example that supports
both procedural and object-oriented programming styles.
Table 1 outlines two main classifications of software metrics:
12
Traditional Approach
Object-Oriented Approach
________________________________________
1. Traditional Approach:
This approach is commonly used in projects developed through
imperative programming techniques. It employs straightforward
procedures such as code interpretation, application composition, and
testing. The selection of this method is often determined by the size and
type of the project. Large-scale projects may require extended timelines
and substantial financial investment.
Among the commonly used traditional software metrics are:
Lines of Code (LOC): Measures the total number of lines in the program.
Cyclomatic Complexity (CC): Evaluates the complexity of a program’s
control flow.
These metrics are foundational but often limited by the constraints of the
classic software development life cycle, which can make them less
adaptable for modern, dynamic applications.
________________________________________
2. Object-Oriented Approach:
This approach focuses on modeling software using real-world entities,
relying heavily on Object-Oriented Programming (OOP) principles. It
utilizes Unified Modeling Language (UML) tools such as:
Use Case Diagrams
Class Diagrams
Sequence Diagrams
While this methodology offers better alignment with real-world systems
and more modular, reusable code, it is often more time-intensive and
expensive than the traditional approach.
Common metrics used in object-oriented software development include:
13
MOOD (Metrics for Object-Oriented Design): Evaluates aspects such as
encapsulation, inheritance, and coupling.
QMOOD (Quality Model for Object-Oriented Design): Focuses on design
quality attributes such as reusability, flexibility, and understandability.
These metrics aim to assess the quality and maintainability of object-
oriented designs more effectively than traditional methods.
Both approaches incorporate the classic phases of software engineering:
analysis, design, and implementation. However, the object-oriented
approach offers a more robust framework for building scalable and
maintainable systems in modern software development environments.
Metric
s
Traditional Object -Oriented
Depth of conditional nesting Number of children
14
1.1.7 The following are the two other sorts of Software Metrics:
1. Internal Metrics
Internal metrics are used to evaluate properties within the software that are especially
relevant to developers. These metrics help assess software performance, development
planning, productivity, and various tasks carried out during the software lifecycle.
One common example is the Lines of Code (LOC) metric, which measures the size of
the codebase and is often used to estimate effort, complexity, or maintainability.
2. External Metrics
External metrics focus on evaluating software from an outside perspective, typically
in scenarios where system performance or usage needs to be assessed in real-world
environments. These metrics are particularly important for monitoring and reporting
purposes, such as evaluating application behavior on cloud infrastructure. Cloud
monitoring is a prime example of external metric usage, providing insights into
performance, availability, and user experience at runtime.
15
1.2.1 Taxonomy of Code Smell
The term code smell was introduced by Martin Fowler and Kent Beck in 1999, who
identified 22 types of smells in a flat list without categorization. In 2003, Mäntylä and
colleagues classified these smells into seven categories based on shared
characteristics to enhance clarity and usability.
Each category focuses on a specific kind of system component—such as methods or
classes—and examines the nature of its design flaws. The seven categorized groups
are:
Bloaters: Code that has grown excessively large and complex (e.g., long methods,
large classes).
Couplers: Components that are overly dependent on others, reducing modularity.
Object-Orientation Abusers: Misuse or violation of object-oriented principles.
Encapsulators: Poor handling of data encapsulation or access modifiers.
Change Preventers: Code that makes modifications difficult due to tight coupling or
poor structure.
Dispensables: Redundant or unnecessary code that could be removed without
affecting functionality.
Others: Smells that do not fit into the above categories are grouped here.
These classifications help developers systematically identify and refactor problematic
areas in codebases, improving long-term maintainability and code quality.
16
Figure 1.4: T a x o n o m y o f Code Smell
Bloaters
Bloaters refer to classes, methods, or blocks of code that have expanded
to an unmanageable size, making them difficult to maintain and
understand. These elements often accumulate excessive functionality or
data, leading to increased complexity. Common code smells classified
under this category include Data Clumps, Long Method, Primitive
Obsession, Large Class, and Long Parameter List [9,10,11,43].
Data Clumps
Data Clumps occur when a group of variables consistently appears
17
together in multiple places throughout the code. This smell typically
indicates poor encapsulation or missed opportunities for abstraction. It
can be identified by observing recurring sets of variables or parameters
that are repeatedly passed together between methods or classes,
suggesting they could be better represented as a single object or structure.
[Link] Method: These are the methods that accomplish multiple actions and
are comprised of multiple lines of code. Any method that contains greater than
15 lines of program is considered as a Long Method. Modifying or
understanding a single ’Long Method’ is more difficult than numerous smaller
methods. The example of this code smell is shown in Fig.1.5. Java example of
a Large Class code smell still demonstrating multiple responsibilities.
18
Fig 1.5: Example of Long Method code smell
19
Fig 1.6: Example of Long Parameter List code smell
[Link] Envy: It is a signal that a method makes extensive usage of other class
rather than the class in which it is currently located. Fig. 1.7 shows the example of
Feature Envy code smell.
[Link]: Below is a Java source code example that demonstrates the Blob Code
Smell (also known as God Object). This smell occurs when a class does too much,
holds excessive data, and performs multiple unrelated responsibilities, violating
the Single Responsibility Principle. The example of this code smell is shown in
Fig.1.6.
20
Fig 1.6: Example of Blob code smell
[Link] class: A class that encompass too many lines of code, methods
or fields and has many duties is called a Large Class. This type of code
smell is difficult to recite, recognize and troubleshoot. It is also called
as God Class or Blob and its example is given in Fig. 1.7.
21
Fig 1.7: Example of Large Class smell
22
In 2006, Mäntylä et al. [44] proposed an updated version of the original code smell
taxonomy. Additionally, Wake et al. [45] contributed by introducing their own
classification of code smells. These code smells are often considered indicators of
design-level deficiencies within a software system.
Brown et al. further expanded on this concept by introducing the idea of Anti-
Patterns in his comprehensive workbook [33]. Anti-Patterns refer to recurring poor
design choices or practices that result in suboptimal solutions. Brown and his
colleagues categorized a total of 40 Anti-Patterns into three broad groups:
development Anti-Patterns, architecture Anti-Patterns, and management Anti-
Patterns.
Recognizing the broader impact of these structural flaws, some researchers have
shifted focus toward detecting code Anti-Patterns rather than isolated code smells, as
Anti-Patterns represent more generalized and system-wide issues. In this context,
three prominent Anti-Patterns are described below [9]:
23
Also known as a God Class, a Blob is characterized by its excessive size and low
cohesion. It tends to monopolize control, delegating other classes to passive roles as
mere data holders. The Blob centralizes behavior that ideally should be distributed
across multiple classes, leading to reduced modularity and maintainability.
2. Functional Decomposition
This Anti-Pattern is typically introduced by inexperienced developers. It manifests
when a class is designed to perform a single task, containing multiple private fields
but utilizing only a few. There is minimal application of object-oriented principles
such as polymorphism and inheritance. As a result, the class functions more like a
procedural routine than a modular component of an object-oriented system.
3. Spaghetti Code
Spaghetti Code describes a disorganized class structure that relies heavily on global
variables and lengthy methods with little or no parameterization. This form of code
ignores fundamental object-oriented principles such as inheritance and
polymorphism, making the system difficult to read, test, and maintain.
24
The terminology of distinctive code smell tendencies is shown below in table 1.2.
1. Application-Level Smells
25
Table 1.2: Taxonomy of Code Smell
Category Code
Smells
Object orientation control statements, l i m i t e d field, other
abusers
classes with alternative connection, refused
bequest, inheritance hierarchies working
simultaneously
Couplers in-appropriate intimacy, class which use
other class
methods excessively
Encapsulators message chains, intermediary
Bloaters large class, long parameter list, data
clumps, long
method, primitive obsession
Change preventers divergent change, shotgun surgery
Dispensable duplicate code, data class, lazy class,
s p e c u l a t i v e generality
Others in complete library class, comments
1. Application-Level Smells
26
labels and extreme or distended subject matter that, certainly, is quickly
fixed. Table 1.4 explains various types of method level smells.
27
Code Explanation
Smell
Name
Variable genetic variations that diverge so substantially
mutations
that refactoring the code can become
incredibly hard
Contrive unnecessarily complex specifications are obligated
d to be used when simplified sequence diagrams might
complexi well fulfill
ty
Duplicated code same code resides in more than one spot
Code Explanation
Smell
Name
Long method method is too much long to use and number of
parameters are there
Odd ball solutions here many objects can be there in single code
that creates incompatibility in them
28
Excessive an approach which delivers so much details than
returner
does the dispatcher needs
Identifier size Size of identifier varies
29
Message chains here procedure demanding a further procedure
that considers a further procedure that keeps
calling a further procedure so on
Too many a very long list of parameters
parameters
smells.
Table 1.5: Class Level Smells
Code Explanation
Smell
Name
Cyclomat category including an extreme quantity of branches
and loops
ic
complexi
ty
Freeloader category that does minimal
Down casting type cast violates the abstraction model
Middleman a category with far too many processes outsourced to
the next category
Large class a long class that has many perimeters
Refused be quest a child class ignores functionality of parent class
Feature envy one class that use too much functionality of other class
31
1.2.6 Advantages of Code Smells
1. It is quick and ready to use method of inscribing the needs of change.
2. Refactoring is an excellent tool for the maintenance of the code.
3. May it be a part of the main program or a different task; it's a
calls. Assist in the application such as SOLID, GRASP and others [13].
32
5. Higher maintenance cost: Code smells increase the time and man-months
required for maintenance, which raises the cost of maintaining software.
[Link]
simple one. These are typically quite challenging to execute because they
affect the entire system design. When faced with the addition of a new
capability that would interfere with existing functionality, they become
necessary during the development of the software system. This can be
interpreted as meaning that the system’s initial design cannot, or only
very slowly can, tolerate updates. They should be viewed as significant
project milestones rather than a symptom of poor design. You will have
additional milestones like this as the system becomes more complicated.
3. Execution path changes: These more complicated refactoring
34
typically alter the software system execution strategy and path. They
are typically used in particular
35
classes and techniques. Although the execution path varies, the system
continues to function in a largely consistent way. You must have a
system in place for these refactoring that can recognize when you are
compromising the functionality of the original code.
4. Duplicate code: Typically has the ability to spawn one or more
methods, not always in the same class. The single responsibility principle
is also violated for that class, so take caution if the repeated code is not
really a result of several duties.
5. Unused method/variable: Without any issues or concerns that
something might go wrong, we should remove it. Despite the method
having obviously been utilized at some point, the code base did not
remove it. This kind of behavior is problematic, especially when you can
eventually find that you have more unused code than genuine code. With
the capabilities that source control systems now afford us, we should at
all costs avoid maintaining outdated or inactive code.
6. Unnecessary comments: Remove any comments that are either no
37
Star
Select Select
refactoring refactoring
Behavior No
preservation
Refactoring
Application
Yes
Apply
refactoring
Image on
quality
Negative
Positive
Consistency with
other software
Stop artefacts
38
activities instead of heir priority and thus the programmers are bit
confused on which technique to apply first and which to last. Hence the
implementation of refactoring also affects the future refactoring
processes which yet to come.
39
Thus, there is a need to refactor sequencing activities that will help developers
to give them the sequence which activity is performed earlier so as to improve
the standard regarding software and refactoring.
1.3.4 Search Based Refactoring
Search based refactoring helps in application prioritizing process by searching
the design. A wide investigation has been done so as generate optimal result
of refactoring applied.
The need for this approach arises from several key challenges in software
development, especially for large and evolving systems:
42
identifying the most impactful changes and the safest order to apply
them. It can help predict the impact of refactorings and guide developers
towards a less error-prone process.
43
that makes locally optimal choices at each step with the hope of finding
a global optimum solution. This means that at every stage of the
algorithm, the choice that appears to be the best at that specific moment
is selected, without considering the long-term consequences of that
decision [21].
44
simultaneously and collaboratively [23].
45
to navigate a maze by giving it positive feedback (reward) for correct
turns and negative feedback (penalty) for wrong ones. Unlike supervised
learning, RL doesn't rely on labeled data; instead, it learns through trial
and error, interacting with its environment and refining its decision-
making process based on the feedback it receives [26].
46
- Dependencies and Interactions: Refactorings are not independent.
Applying one refactoring can enable, disable, or alter the impact of
another. Modeling these intricate dependencies and predicting their
ripple effects across the entire codebase is a significant challenge.
- Context-Dependency: The effectiveness of a refactoring often
depends on the specific context of the code. A refactoring that works
well in one part of the system might be detrimental in another.
3. Accuracy of Code Smell Detection and Impact Prediction:
- False Positives/Negatives: Automated tools for code smell detection
are not perfect. They can produce false positives (identifying a smell
where none exists) or false negatives (missing actual smells), which
can lead to suboptimal or unnecessary refactoring recommendations.
- Predicting Impact: Accurately predicting the quantitative impact of
a refactoring (e.g., how much "Extract Method" will reduce
cyclomatic complexity or improve cohesion) is a complex task, as it
depends on the specifics of the code.
4. Maintaining Behavioral Equivalence:
- Behavior Preservation: A fundamental principle of refactoring is
that it should not change the external behavior of the software.
Ensuring this property for an automatically generated sequence of
complex refactorings is extremely difficult and often requires
extensive (and expensive) automated testing.
- Regression Testing: Even with careful planning, refactoring
introduces the risk of new bugs. The need for comprehensive
regression testing after each significant refactoring step adds to
the effort and cost, potentially negating some of the optimization
benefits.
5. Integration with Development Workflow and Developer Acceptance:
- Tooling Limitations: Many research prototypes for optimization-
based refactoring sequencing are not robust enough for real-world
use. Integrating them seamlessly into existing IDEs and build
pipelines, and making them user-friendly for developers, is a
practical challenge.
- Trust and Explainability: Developers often need to understand why
a particular refactoring sequence is recommended. Black-box
optimization algorithms can be hard to interpret, leading to a lack of
trust and reluctance to adopt the suggestions. Explainable AI (XAI)
is an emerging field trying to address this.
- Human Expertise vs. Automation: Experienced developers possess
a deep understanding of the system's design, domain, and historical
context. Purely automated solutions might miss critical nuances that
a human would consider, leading to less effective or even harmful
refactorings.
47
6. Scalability and Performance:
- Large Codebases: Analyzing and optimizing refactoring
sequences for extremely large and complex codebases (millions
of lines of code) demands significant computational resources and
can be time-consuming.
- Dynamic Environments: Software systems are constantly
evolving. An "optimal" sequence calculated at one point in time
might become suboptimal as new features are added or
requirements change. Re-running the optimization frequently can
be computationally expensive.
7. Data Availability and Quality:
- Lack of Labeled Data: Training machine learning models for
predicting refactoring impacts or identifying optimal sequences often
requires large datasets of successful refactoring operations and their
effects. Such well-labeled data is often scarce.
- Historical Data Bias: If historical data is used, it might reflect past
refactoring practices that were not necessarily optimal, potentially
perpetuating suboptimal patterns.
Addressing these challenges requires a multi-disciplinary approach, combining
advances in search-based software engineering, machine learning, program
analysis, and human-computer interaction. The goal is not necessarily to fully
automate the entire refactoring process but rather to provide intelligent,
explainable recommendations that assist developers in making more informed and
effective refactoring decisions.
48
there in elderly one, therefore it is not
anticipated
afterwards
4. Detection the code smell must be secured and found if any
5. Reliable the coding must be reliable to clear all the
bugs after
testing
6. Maintainabilit maintenance of code should be cost effective and
y easy
7. Usability the code used should be user friendly
8. Portability the code used must be portable in order to move
from one
device o another
9. Correctness the code used must fulfill all the functional
requirements
10. Integrity the code used must be secure and must be
prevented from
any loss of data
11. heterogeneous arrangements must work
on distinct
Interoperabilit
y platforms, databases and protocols situations
12. the code used must be durable, in case if the
system crash,
Durability
the code is not affected
50
3. Compiling methods: The compiling methods are used to make the
1. Inline methods
2. Extraction methods
3. Variables removed
5. Algorithms replaced
the methods or attributes are being moved. We can move attribute within
different classes by following methods: -
1. Shift function
2. Shift features
classes clearly. Thus, the links that are not required in classes must be
removed in order to maintain the functionality of classes [31]. Examples of
techniques includes:
1. Encapsulation of attributes
2. Renewal of object reference
51
3. Linking data
4. Renewal of dataset
52
1. Condition be for cement
53
Figure 1.10. A refactoring categorization model for software quality
improvement
A refactoring categorization model for software quality improvement
systematically organizes refactoring techniques based on their objectives and the
quality attributes they enhance. It includes categories such as structural
refactoring, which focuses on code organization; behavioral refactoring, aimed at
altering functionality without changing external behavior; performance
refactoring for optimizing efficiency; and readability refactoring to enhance code
clarity. Additionally, it categorizes techniques by quality attributes like
maintainability, scalability, testability, and reliability, while also considering the
scale of changes (small, medium, large) and frequency of use (common vs.
advanced techniques). This model serves as a guide for developers to select
appropriate refactoring strategies that effectively improve software quality.
54
significant role in enhancing the quality and maintainability of software. By
implementing these techniques, developers can ensure that their code remains
clean, efficient, and adaptable to evolving requirements, thereby contributing to
the overall success of software projects in the fast-paced Indian IT industry.
55
length of Source Code. Software size is defined as PUSH UP,
the sum total of lines within programme,
Size typically measured in PARENT
56
thousand lines of code (KLOC). The size of the CLASS
application expands along thousand lines of
code.
interdependency of class. Coupling is a measure of
Coupling how closely two procedures or modules are EXTRAC
coupled and up to which level software modules T,
are connected with each other. Through coupling, INLINE
the strength of the connections
within modules is also evaluated.
Legacy
code/
Attributes Explanati
on Refactori
ng
change
the degree of work needed to do updations. Two changes
Working in
Maintainabil
ity on the project in various working contexts each
and conditions is how software reliability is compone
tested nt
The code structure used must be efficient Single
Efficiency to work and gives quality performance. change in
Efficiency refers to how quickly the each
software should do the task. The software component
must efficiently use memory, disc space
and processor resources.
The reuse of applications in different tasks. Two changes
Reusability The application must be simple. Easy to in each
57
navigate. The method must be simple to component
learn to utilize for new or
occasional users [35].
The given task must be completed in Three
Performance allotted time. The programme should be components
capable of handling process
unforeseen circumstances with ease.
58
[Link] Refactoring: Advantages and Disadvantages
Advantag Disadvantages
es
Improved legibility makes Imperfect refactoring may
software maintenance and include new errors in the existing
extensibility easier. code.
Nothing such neat clear code is
It is possible to restructure the there.
source code without affecting the
functionality [36].
60
[Link] Reasons for Refactoring
1. Makes the code simple and easy to understand
61
[Link] to decrease the technical debt
The price of any software is not finalized when the first version is
released. If the software is not updated on a regular basis, it may stop
working after a few months. This may result in technical debt, and in
order to reduce it, you must constantly refactor the code.
[Link] code
Updation in software increases the performance of the software. We use
different types of libraries which have to be updated with the passage of
time. The code will generate different types of bugs and might not
execute due to updation in the libraries. It can create different types of
issues in case the software uses the older libraries. It may create lots of
errors and may stop working.
[Link] to inspect the bugs
It becomes easy to inspect the errors if you know the proper functioning
and the purpose for which the application had been created. It becomes
easy to do the trials of the software and find the bugs as you know the
purpose and the working of the software.
[Link] the system blueprint
Change is the rule of the technology. After, sometime the technology
changes with time. With the passage of time, these changes become easy
to adapt and learn. Refactoring a code, improve the structure of the
software by using different exercises.
If an application is not designed properly, it will only use for short term
rather than for long run and can create different problems. Code
refactoring helps to avoid these problems and rather than shortcuts they
make the app clear, simple and easy to understand and can work for long
period of time. Thus, the main purpose of refactoring is to make code
flexible, readable, understandable and reliable as shown in figure 4.
There are many tools available, such as Sonar Qube, Visual Studio Intelli
62
Code, Rider, and Eclipse IDE, to automate the process of working code.
Programmers can perform code restructuring using several of these
technologies concurrently with the development process, which can assist
teams in code when necessary.
• After identifying the code smells, our proposed algorithm generated an optimal
63
refactoring sequence, prioritizing the detected smells based on their impact on
software quality.
1.6.1 Hybridization
64
Object-Oriented (OO) metrics. Different approaches often combine these
metrics uniquely, and each combination necessitates distinct threshold
values. Even when using the same metrics, the optimal threshold can
vary, meaning a slight adjustment can drastically alter the number of
detected smells. Consequently, the chosen threshold profoundly impacts
the detector's performance [40].
Further complicating matters is the accuracy of results. Rule-based
methods frequently produce high rates of false positives or false
negatives because they often fail to account for crucial contextual
information, such as the size, design, domain, and specific environment
of the analyzed dataset [41]. The ever-increasing volume and variety of
software information make it impractical for programmers to manually
identify every potential code smell. This growing complexity highlights
the critical need for hybridization. Hybrid approaches, which combine
different methodologies, offer a more effective solution. They are
relatively cost-effective and faster [42,43, 44], capable of detecting and
correcting errors and bugs with reduced human intervention.
Furthermore, these techniques possess the ability to learn from past
experiences, enabling them to proactively prevent future defects.
1.6.1Hybrid Algorithm
65
exploration (finding promising areas in a large search space), while another might
be highly efficient at local exploitation (fine-tuning solutions within a discovered
promising area).
2. Same Problem Domain: Crucially, a hybrid algorithm combines methods that are
designed to solve the same underlying problem. It's not just using multiple
algorithms to achieve different parts of a larger task, but rather integrating them to
enhance the solution for a single problem.
66
A novel hybrid approach utilizing the hybrid spotted hyena and emperor
penguin (HSHEP) optimization-based algorithm. This approach aims to
optimize the sequence of code smell bugs by incorporating maintainer
opinions and requirements, thereby maximizing the resolution of critical
code smells. Unlike existing technologies, the HSHEP algorithm
combines the strengths of two optimization strategies, offering a unique
and innovative solution to refactoring challenges. To validate the
effectiveness of the proposed method, it was applied to various largescale
open-source systems, analyzing five different types of code smells.
Results demonstrated a significant improvement in maintenance
efficiency and system evolution, confirming the superior performance
and practical applicability of the HSHEP-based approach.
[Link].2 Advantages (Shared by both EPO and SHO, and many other metaheuristics):
- Ability to Escape Local Optima: Both algorithms, being population-based
metaheuristics, are designed to avoid getting trapped in suboptimal solutions, unlike
some traditional gradient-based optimization methods.
- Flexibility: They can be applied to a wide variety of continuous and discrete
optimization problems across different domains, by simply changing the fitness
function.
- No Gradient Information Required: Unlike traditional calculus-based optimization
methods, metaheuristics do not require derivative information about the objective
function, making them suitable for problems where such information is unavailable or
computationally expensive.
- Handling of Complex Objective Functions: They can optimize problems with
complex, non-linear, and even noisy objective functions.
- Heuristic Nature: While not guaranteeing the absolute global optimum, they can find
very good, near-optimal solutions within a reasonable computational time, which is
often sufficient for practical applications.
68
[Link].3 Performance Metrics
To calculate the gain this algorithm uses Fitness, Information Gain, and Gain Ratio
metrics.
1. Start: Beginning of the algorithm.
2. Initial Problem Setup: Defines the context for optimization.
3. Identify Code Smells & Candidate Refactorings (Static Analysis): This is the crucial
pre-processing hybrid step. Automated tools analyze the code to detect smells and
propose a list of possible refactoring operations (e.g., "Extract Method for X," "Move
Field Y to Z").
4. Initialize Population of Refactoring Sequences (Hyenas/Penguins): Create a set of
random initial sequences. Each sequence is a potential solution.
5. Define Fitness Function: Establish the objective function that quantifies the
"goodness" of a refactoring sequence (e.g., using software metrics to measure
maintainability improvement, smell reduction, etc., while considering cost/risk).
6. Evaluate Initial Population Fitness: Calculate the fitness score for each randomly
generated sequence.
7. Find Global Best Solution (G_best): Identify the sequence with the best fitness score
from the initial population.
8. Loop: Until Max_Iterations or Convergence: The main iterative process of the
optimization.
9. Phase 1: Spotted Hyena Optimization (SHO): The first sub-phase of each iteration,
primarily for global exploration.
10. Update Hyena Positions (Sequences) based on G_best and other Hyenas: Each
hyena (solution) adjusts its refactoring sequence based on the best solution found so far
by the entire population and potentially other hyenas' positions. This uses SHO's
specific mathematical models for movement.
11. Perform Chaining Behavior (SHO-specific exploration): Implement SHO's unique
mechanism for information exchange and exploration, where hyenas "chain" to the best
solution.
12. Evaluate new Hyena Population Fitness: Calculate the fitness for all
sequences generated in this SHO sub-phase.
13. Update Individual Best Solutions (P_best) for Hyenas: Each hyena
remembers the best sequence it has ever found.
69
14. Update G_best if a better solution is found: If any hyena found a new global
best, update G_best.
15. Phase 2: Emperor Penguin Optimization (EPO): The second sub-phase,
potentially for local refinement or enhancing diversity within promising areas.
16. Current Hyena Population becomes Penguin Population: The refined
sequences from the SHO phase are passed to the EPO phase.
17. Update Penguin Positions (Sequences) based on P_best and G_best (Huddle
Dynamics): Each penguin adjusts its sequence based on its own best and the
global best, using EPO's huddling-inspired movement equations.
18. Perform Huddle Reshuffling/Exploration (EPO-specific refinement):
Implement EPO's mechanisms for maintaining diversity and escaping local
optima within the huddle.
19. Evaluate new Penguin Population Fitness: Calculate the fitness for all
sequences generated in this EPO sub-phase.
20. Update Individual Best Solutions (P_best) for Penguins: Each penguin
remembers the best sequence it has ever found.
21. Update G_best if a better solution is found: If any penguin found a new global
best, update G_best.
22. (Loop back): The process continues for the next iteration.
9. End Loop: The optimization process stops when the termination criteria are met.
10. Return Global Best Refactoring Sequence: The best sequence found across all
iterations is the algorithm's output.
11. End: Algorithm termination.
70
The pursuit of optimal solutions is driven by a single fitness. The primary objective is to maximize the
system’s overall quality. By doing so, the approach becomes cost-effective; as it effectively
minimizes cost of the rework that may arise in the future. The primary objective of any software system,
from a software engineering standpoint, is to achieve exceptional software quality. However, by
detecting and correcting these software smells through refactoring, the system’s overall quality
can be significantly enhanced proactively, before these undesirable traits spread to other phases
and incur additional maintenance costs [46].
Subsequently, here we present a set of 4 prioritizing criteria (severity, priority, risk, and
importance) that is included into the methodology for resolving code smells during refactoring.
- Risk: An essential factor to take into account is the vulnerability score. Therefore, this
was posited that as code strays further from established best practices, its susceptibility
to risk increases. Consequently, during the correction phase, the code smells posing the
highest level of risk should be given precedence. Each identified code smell is
accompanied by a vulnerability score, reflecting the degree of departure from well-
structured code design.
71
The integration of Particle Swarm Optimization (PSO), Deep Learning
techniques, and hybrid optimization methods to enhance software
maintainability. By combining PSO’s global search capabilities with Deep
Learning’s predictive power and various hybrid strategies, the research aims to
optimize code refactoring and performance improvement processes. Through
extensive case studies and
experiments, the study reveals significant advancements in maintenance
efficiency, accuracy, and system evolution. The integration of PSO and Deep
learning has led to enhanced identification and correction of code smells, while
hybrid models have improved performance metrics such as accuracy, precision,
and execution time. The findings validate the practical applicability and
effectiveness of these advanced optimization approaches, demonstrating their
potential to address complex software maintenance challenges effectively.
▪ If the TSA rule suggests moving towards X best t, apply permutation operators
(e.g., swaps, insertions) that make X it more similar to X best t.
75
▪ If the TSA rule suggests random movement, apply random permutation
operators.
2. Asexual Reproduction (Random Perturbations - applied to a small subset of
PTSA): For a small percentage of individuals in PTSA:
o X jt+1=Apply random permutation operators to X jt (e.g., a single random swap,
insertion).
3. SHO Phase (Exploitation - Applied to a selected subset of the updated
PSHO:
o Encircling Prey / Attacking Prey / Searching for Prey (based on SHO logic):
▪ Calculate A and C vectors.
▪ Determine target (either X best t or a randomly chosen hyena).
▪ Update X jt+1 using SHO rules, but applying permutation operators.
▪ If SHO rule suggests moving towards X best t, apply permutation operators that
make X jt more similar to X best t.
▪ If SHO rule suggests forming a cluster and attacking, apply permutation
operators that generate variations of X jt that are close to X best t.
4. Combine and Select:
o P combined t+1 = All updated individuals from TSA and SHO phases.
o Select the N best individuals from P combined t+1 based on their fitness (cost) to
form P t+1. This step includes elitism (keeping the overall best).
5. Update Global Best:
o X best t+1= Best individual in P t+1 and X best t.
Chapter 1: Introduction
Maintaining high-quality software systems requires timely identification and resolution of code
smells, which are indicative of deeper design issues. This study presents a novel approach for
code smell detection and refactoring sequencing using a hybrid search-based algorithm
combined with machine learning classifiers (HSHEP, PSDL, HTSA-SHO). Initially, existing
techniques involving machine learning, metaheuristics, and hybrid models were reviewed to
establish a foundation. The proposed method was evaluated on object-oriented sample
applications, with the source code, quality metrics, and predefined smell specifications serving
as inputs. Upon detection of code smells, the algorithm generated an optimal refactoring
sequence by ranking the smells based on their impact on code quality and maintainability. An
empirical study was conducted to assess the influence of code smell on the refactoring
sequencing process. The results demonstrate that the proposed sequencing approach improves
the effectiveness of refactoring decisions and outperforms existing methods in both accuracy
and practical applicability. This research contributes a systematic solution for guiding
developers through efficient and informed refactoring workflows.
Chapter 4: Particle Swarm Optimization (PSO), Deep Learning, and hybrid optimization
The integration of Particle Swarm Optimization (PSO), Deep Learning, and hybrid optimization
techniques has significantly improved software maintainability and refactoring efficiency. By
combining PSO’s global search abilities, Deep Learning’s pattern recognition, and hybrid
strategies’ diverse optimization capabilities, the proposed approach (EM-MM-iRe-iRTS-oEC)
achieves superior accuracy, precision, and recall, with minimal trade-offs in execution time.
This hybrid model enhances performance metrics by balancing global and local search
strategies, enabling faster processing and better handling of complex maintenance tasks. The
synergy between optimization techniques and Deep Learning leads to more accurate, efficient,
and reliable refactoring outcomes.
Chapter 5: HTSA-SHO
Hybrid optimization approaches like HTSA-SHO play a crucial role in automating and
improving code smell refactoring sequencing. The proposed best sequence EM > EC > MM >
RPMC > IO demonstrates that optimal refactoring order varies by algorithm. Traditional
techniques often lack scalability and efficiency, whereas hybrid methods combining heuristics,
metaheuristics, and machine learning effectively enhance maintainability, modularity, and
performance. Empirical results show that techniques such as genetic algorithms, PSO, ACO,
and deep learning outperform conventional methods in detecting and refactoring smells like
long methods, large classes, and feature envy. While genetic algorithms and NSGA-II improve
structural quality, swarm intelligence optimizes sequencing, and deep learning ensures high
detection accuracy.
79