0% found this document useful (0 votes)
5 views79 pages

Chapter 1 Introduction-2

The document discusses the importance of software maintainability within the Software Development Life Cycle (SDLC), emphasizing that poor code quality can significantly increase maintenance costs. It outlines the software maintenance process, types of maintenance, and the concept of code smells, which indicate deeper issues in code quality. Additionally, it highlights the need for effective refactoring techniques and the measurement of software metrics to enhance maintainability and reduce complexity.

Uploaded by

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

Chapter 1 Introduction-2

The document discusses the importance of software maintainability within the Software Development Life Cycle (SDLC), emphasizing that poor code quality can significantly increase maintenance costs. It outlines the software maintenance process, types of maintenance, and the concept of code smells, which indicate deeper issues in code quality. Additionally, it highlights the need for effective refactoring techniques and the measurement of software metrics to enhance maintainability and reduce complexity.

Uploaded by

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

1.

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.

The present chapter begins with describing the idea of software


maintenance, steps of maintenance and characteristics and Section 1.1
describes software quality. Next section focuses on software metrics as one
of the is a quantifiable or countable measure of a characteristic of a
software system, process, or project. Different types of software
maintenance are also discussed. Later, the basic concept of code smells is
explained in Section 1.2 and the refactoring techniques are discussed in
Section 1.3. In this chapter, we have introduced a concept of finding the
refactoring technique sequences well in advance and its explained in
Section1. 3. Additionally, this chapter discusses Optimization-Based
Refactoring Sequencing Approach in Object-Oriented Systems and the
different algorithms used. Finally, the goal(s) and organization of this
thesis are presented in the Section1.8 and Section 1.9 respectively.

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.

1.1.1 Software Maintenance Process steps:


1. The first and foremost step in maintenance is to plan, which

involves software preparation, problem diagnosis, and product


configuration management.

2. The second step is the problem analysis process, which involves

verifying the validity of the problem, thoroughly examining it,


developing an appropriate solution, and securing all necessary approvals
and support to formally request a modification to the 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.

4. The next process relocation, which is used when software needs to be

moved from one platform to another without losing functionality [1].

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

Figure 1.1: Software Maintenance Process

1.1.2 Classification of Software Maintenance:


Each type of software maintenance serves a specific purpose. A particular
component of an application may undergo one, several, or even all categories of
maintenance at different points throughout its lifecycle.

1. Adaptive: To ensure the system’s adaptability with changing

environments, some adjustments are made to it.

2. Perfective: Checks for fine-tuning of all system features,


functionality, and capabilities in order to optimize system
performance.

3. Corrective: Detection and rectification of faults as well as

inaccuracy in the present solution to ensure the system’s proper

4
operation.

4. Preventive: Aids in the prevention of potential system flaws.

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.

Figure 1.2: Software Maintenance Categories

1.1.3 Software Quality

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.

The term “software maintenance” broadly includes bug fixes, enhancements to


current functionalities, process upgrades, and transitioning from outdated methods
to newer systems. In an ever-changing technological environment, software must
evolve accordingly. Therefore, software maintenance requires careful planning in
terms of budgeting, scheduling, and implementing timely updates.

Significantly, 50% to 75% of a software’s reliability depends on this maintenance


phase, and it can represent a considerable portion of the overall development cost.
However, focusing on effective maintenance strategies can ultimately result in
substantial cost savings.

1.1.4 Implications for the Decline in Software Quality

Declining software quality refers to the software’s failure to perform tasks as


expected by the user. These shortcomings may involve both functional and non-
functional aspects. There are several reasons behind poor software quality, and its
manifestations can vary. One of the most significant contributing factors is:
1. Lack of domain knowledge: A major cause of substandard software is

that many developers do not possess adequate expertise in the specific


domain for which the software is being developed. While they may
eventually gain deeper understanding over time, much of this learning
often occurs through identifying and correcting errors that stem from
7
misinterpreting the functional requirements.

8
2. Non sensual timetables: Sound software development practices are

often compromised by developers in an effort to meet unrealistic


deadlines, which rarely leads to positive outcomes. When developers
are rushed, they face increased challenges and have limited time to
properly gather and analyze requirements, leading to flawed or
incomplete implementations.

3. Poorly crafted software: The majority of software development

tasks involve modifying or enhancing existing code, often accounting


for nearly two-thirds of the work. Research shows that approximately
half of the time spent on maintaining existing software is devoted to
understanding the current code. When code is overly complex, it
becomes difficult to comprehend, and making changes to it often
introduces numerous errors and unintended negative consequences.

4. Low grade procurement procedures: Most large-scale enterprise

programs are developed and operated by teams, many of which may be


outsourced to external companies. As a result, the organization that
commissions the software often has limited insight into or control over
its overall quality.

5. Lack of technological expertise: While most developers are

proficient in multiple programming languages and technologies,


modern multi-tier enterprise systems are highly complex, involving a
mix of different programming languages and software platforms.
These systems typically include layers such as desktop interfaces,
application logic, and data processing. However, few developers

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.

2. Expanding opportunities in a changing world:


To remain relevant and efficient in a rapidly evolving technological landscape,
software must be continuously evaluated and improved. Enhancements may
include refining existing features and implementing changes that enable
compatibility with newer systems and technologies. This process involves
upgrading application capabilities, optimizing workflows, updating hardware,
integrating new compilers, and improving overall system efficiency. Keeping the
software maintained and current ensures better performance and adaptability.

3. Remove obsolete functions:


Features that no longer serve a useful purpose can unnecessarily consume system
resources. Removing outdated or redundant functionalities is essential to
streamline the software. This involves eliminating legacy code and unused
components, thereby creating room for implementing advanced technologies and
improved features. As a result, the system becomes more agile and better
equipped to handle new challenges and requirements.

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.

Therefore, software maintenance is not optional—it is essential. Consider the


example of a vehicle: without regular maintenance, it may develop multiple issues
over time, and the cost of neglect can be significantly higher. Similarly, failing to
maintain software can impede business growth and limit system capabilities.
11
In today’s digital era, maintaining increasingly large and complex software
systems poses significant challenges. Although several methods have been
developed to predict software maintainability, accurately measuring the
relationship between maintainability and quantifiable software characteristics—
such as "code smells"—remains elusive.

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.

1.1.6 Types of Software Metrics/Measuring Maintainability

"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.

Table 1.1: Software Metrics Hierarchy

Metric
s
Traditional Object -Oriented
Depth of conditional nesting Number of children

Cyclomatic complexity Coupling between objects

Fan-in/Fan-out Weighed methods per class

Fog index Number of overriding operations

Lines of code Response for a class

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.

1.2 Code Smell


Code smells are not the same as bugs or functional errors. Instead, they represent
structural issues in the code that degrade its quality and maintainability. Code smells
indicate violations of sound software development principles and may not
immediately cause program failure but often lead to long-term problems.
In the mid-1980s, languages like C and C++ began to dominate the programming
landscape. At the time, coding was often seen merely as a means of producing output,
with little concern for structure or efficiency. As a result, poor coding practices
became common, with minimal focus on maintainability or scalability. Code smells
are subtle indicators of deeper design issues—they do not necessarily prevent the
software from running but can lead to increased processing time, higher risk of bugs,
and long-term maintenance challenges.
Code smells are typically easy to detect, especially with automated tools. They often
appear as elements in the codebase that hint at more significant underlying problems
—such as a class containing data but lacking meaningful behavior. Although they
don’t always affect immediate functionality, they compromise code readability,
efficiency, and future adaptability.

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.

The diagrammatic description of this taxonomy of code smell is given in


Fig. 1.4.

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

2. Long Parameter List : When a method is passed more than three


parameters, it is called as Long Parameter List. A method with great
number of parameters is more complex. It is better to limit number
of parameters passed because Long Parameter Lists are inconsistent,
difficult to learn and tough to use. Example of Long Parameter List is
shown in Fig. 1.6.

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.

Fig 1.7: 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.

Some notable Anti-Patterns include: Functional Decomposition, Spaghetti Code,


Walking through a Minefield, Continuous Obsolescence, Lava Flow, Ambiguous
Viewpoint, Poltergeists, Mushroom Management, Dead End, Golden Hammer, Input
Kludge, Cut-and-Paste Programming, Boat Anchor, Swiss Army Knife, Reinvent the
Wheel, The Grand Old Duke of York, Autogenerated Stovepipe, Stovepipe
Enterprise, Jumble, Cover Your Assets, Vendor Lock-In, Wolf Ticket, Warm
Bodies, Design by Committee, Blowhard Jamboree, Analysis Paralysis, Viewgraph
Engineering, Death by Planning, Fear of Success, Corncob, Intellectual Violence,
Irrational Management, Smoke and Mirrors, Project Mismanagement, Throw It Over
the Wall, Fire Drill, The Feud, and E-mail Is Dangerous.

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]:

1. Blob (God Class)

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.2.3 Classification According to Code Smell Level

Code smells are divided into three categories such as:

1. Application-Level Smells

2. Method Level Smells

3. Class 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

Application-level programming smells is dispersed throughout the


application and affects all layers. At the application level of a program,
there are only a few stands out code smells that don't infringe on design
smell territory. Table 1.3 explains various types of application-level
smells.

2. Method Level Smells


Method level smells connected with tiny code like identifiers or variables
as well as methods. The issues in such regions are caused mainly by

26
labels and extreme or distended subject matter that, certainly, is quickly
fixed. Table 1.4 explains various types of method level smells.

Table 1.3: Application-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

Uncontrolled adverse reactions of programming which create


serious computation exclusions, of test cases
side effects refusing to determine the precise reason for the issue
Boolean easy to assert on the opposite value and still type
blindness checks
Shotgun survey a tiny suggestion should be extended to different
classes all at once

Table 1.4: Method Level Smells

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

God line an elongated line of code

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

1.2.4 Class Level Smells


Class-level code smells mainly focus on same block of the class. This type of class
involves processes like cyclomatic complexity and depth of inheritance, high
coupling, and low cohesion. Table 1.5 explains various types of class level

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

1.2.5 Reasons of Code Smell Occurrence


30
Since the copying and then using data programmes are the wrong methods of
software maintenance. The coders have a large number of hindrances while
coding. The programmers always not get the optimize coding and the time
constraints for programmers are always there. Thus, the programmers always
face time boundation during software evaluation, even if they are skilled one,
so the last option that remains is copy paste code [10][11][12]. Complex large
system always gives the restriction in coding and thus the promotion of copy
pastes of logics, methods and functions exist. The language is always a
boundary for the programmer. So, number of times the coders have to
deliberately copy paste the code and thus reason for code smell. Some
language is not bounded to the reuse of coding and thus leads to redundancy.
Also, the coders are not much confident in bringing new code, as they have the
risk of failure of the length and in software development life cycle (SDLC)
phase.

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

fascinating thing to accomplish.


4. Some of the prototypes in the application encourage the use of multiple
templates.
5. In the absence of reconstruction of code and extraction the only

option left to enhance function and method of code.


6. The clone number of time increases the parameter list and procedure

calls. Assist in the application such as SOLID, GRASP and others [13].

1.2.7 Disadvantages of Code Smells


Software developers and users will encounter numerous issues in the
future with the use of the software and the code's maintainability.
1. Program modification: The majority of the time, the software is not
maintained by the person who developed it. Additionally, the
complexity of updates has increased, and code smell reduces
comprehension.

2. Software quality: The existence of code smell is one of the biggest


hazards to software quality, yet many academics think it has more good
effects than bad ones, while others think it has no effect at all, therefore
the impact is uncertain.
3. Impact on design: Code smells give a big effect to the design of
software which should be detected and refactored [14, 15].
[Link] propagation: The reuse of code that contains code smells leads to
an issue with bugs spreading throughout the entire software since the
smelly code is called frequently throughout the programme.

32
5. Higher maintenance cost: Code smells increase the time and man-months
required for maintenance, which raises the cost of maintaining software.

[Link]

As we all know coding is a time-consuming task in which number of


programmers are involved. The code that is being coded will be gone
through number of times, updated and can be increased or decreased
during coding [16, 17]. Thus, the programmers do their job under lot of
pressure and there might be chances of getting redundancy or lengthy
coding. Such cumbersome tasks in coding lead to code smells. So, this
weakness of coding which makes it unreliable and not easy to understand
leads to disastrous and time and space consuming programming. In order
to remove such decline in programming, refactoring is needed.
Refactoring is the technique of changing a part of application
structure rather than its nature. Refactoring is a methodical process of

reconstructing a framework of existing program while maintaining inner


organization and exterior behavior. The term refactoring is coined by Ralph
Johnson and William Opdyke in 1990 [18, 19]. Even though the software
industry had undergone many changes, the requirement for software
refactoring remained. Refactoring strong impact on software quality
causes it to become a hot topic of study. Software restructuring and
software quality have been the subject of significant amounts of research.
Refactoring frequently also makes it easier to spot issues and bad code.
This has a favorable impact on the software’s quality. Software
applications include many coding and so the programmers and those
highly skilled coders develop very big codes. As the programming run in
different hands and through different techniques, so there are more
chances of errors and not an easy task in case the issue has progressed a
long way, code refactoring can be delayed.
33
Figure 1.8: The Purpose of Refactoring

3.3.1 Need of Refactoring


1. Simple changes: If changes are simple to do on the code than they

leave a minor effect on code. These consist of renaming, removing code,


compressing instructions, etc. The changes done in these codes are
slightly appearing. Thus, the simple rule is that every time there is no
requirement of testing when the code is broken for refactoring.
2. Design changes: The design changes are typical hard as compared to

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

longer relevant to the code or don't offer any valuable information.


Generally speaking, the code should be concise and simple enough to
speak for itself, negating the need for any comments. The necessity for
comments alone is a strong sign that the code is not clean. The main
method comprises comments starting at the top that attempt to describe
what the methods below them perform. The name of the method in this
situation should indicate everything that the comments tell, and also that
the comments don’t tell.
1.3.2 Process of Refactoring
A typical refactoring process has the following stages and the figure 1.9
will give a view of flow chart that represents the process:
1. Identify the code smell location where the refactoring can be done.

2. Selection of best refactoring approach by using quality requirements.


36
3. The applied refactoring approach preserves program functionality.

4. Optimal refactoring approach is used.

5. Response of restructuring code at software standard has been checked.

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

Figure 1.9: Flow Chart Representing Refactoring


Opportunity

1.3.3 The Refactoring Sequencing

The refactoring process identifies process produces number of


applications as a resulting output. Also, sometimes the refactoring
exceeds from budget and is asked the programmers to develop a whole
refactoring process. Since all the refactoring activities are not beneficial
in terms of quality attributes. Fowler has introduced 72 refactoring

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.

[Link] The Need of Refactoring Sequencing

Main objective of refactoring is to get best of coding. Impressive coding


allows for better integration of new code elements without introducing new
errors. Developers who are very much skilled can detect and correct code
easily and in no time. Thus, the aim of refactoring also includes improved
maintainable code and easily bug free. Therefore, effective coding leads to
integration of different modules of coding.
The refactoring sequence is categorized in the two ways given below: -
In single section, the blocks are removed in the particular section.
In set of section, the blocks are searched in the particular
section and the
optimized result is the chosen one.
So, in refactoring the functions are introduced only when the present code is
not changed and the alternative source code carries refactoring without
adding new functions and methods.

Optimization-based refactoring sequencing approaches have emerged as a


promising solution to automate and optimize the refactoring process. These
approaches leverage metaheuristic algorithms, machine learning, and multi-
objective optimization techniques to identify the best sequence of refactorings
that maximize software quality while minimizing effort and risk. This
literature review explores existing research on optimization-based refactoring
40
sequencing in object-oriented systems, highlighting key methodologies,
challenges, and future directions.

1.3.5 Refactoring in Object-Oriented Systems

Refactoring involves applying small, behavior-preserving transformations to


improve software design. Fowler [6] introduced a catalog of refactorings,
such as Extract Method, Move Method, and Replace Conditional with
Polymorphism, which are widely used in object-oriented programming.
However, manually selecting and applying refactorings is time-consuming
and error-prone, necessitating automated approaches.

[Link] Need for Optimization-Based Refactoring Sequencing

Optimization-based refactoring sequencing is a technique that aims to find the


best order in which to apply refactoring operations to a software system. It
treats the problem of refactoring a complex codebase as an optimization
problem, seeking to achieve specific goals (e.g., improved maintainability,
reduced technical debt, enhanced performance) while minimizing costs (e.g.,
development effort, risk of introducing new bugs).

The need for this approach arises from several key challenges in software
development, especially for large and evolving systems:

1. Overwhelming Number of Code Smells: In large-scale software


systems, code can accumulate a vast number of "code smells" –
indicators of potential design flaws. These can include duplicated code,
long methods, large classes, tangled hierarchies, and more. Manually
identifying, prioritizing, and addressing all of them can be an incredibly
complex and time-consuming task.
41
2. Interdependencies and Conflicts: Refactoring operations are not
isolated. Applying one refactoring can impact the effectiveness or
necessity of another. For example, extracting a method from a large
class might make other refactorings on that class easier, or it might
introduce new code smells if not done carefully. Without a strategic
sequence, developers might:

o Perform redundant work.

o Introduce new issues while fixing old ones.

o Miss opportunities for more impactful changes.

o Experience conflicts between refactorings.

3. Resource Constraints and Technical Debt: Refactoring requires effort


and resources. In a real-world development environment, time and
budget are always limited. Developers need to prioritize refactorings
that will yield the most significant benefits with the least effort or risk.
Technical debt, the cost incurred by making short-term decisions that
compromise code quality, also needs to be managed effectively, and
refactoring is a key tool for this.

4. Maximizing Quality Attributes: Software quality is multi-faceted.


Developers often want to improve not just one aspect (e.g., readability)
but several (e.g., modularity, maintainability, performance, testability).
An optimal refactoring sequence can help achieve a balanced
improvement across these different quality attributes, potentially
conflicting, by finding the best trade-offs.

5. Minimizing Risk and Effort: Unplanned or haphazard refactoring can


introduce new bugs, break existing functionality, or even increase
complexity. An optimized sequence aims to minimize these risks by

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.

6. Automation and Scalability: As systems grow, manual refactoring


becomes impractical. Optimization-based sequencing often leverages
automated tools and algorithms (e.g., heuristic search, metaheuristic
algorithms, machine learning) to analyze the codebase, identify code
smells, propose refactoring opportunities, and even suggest optimal
sequences. This automates a significant portion of the process, making it
scalable for large projects.

1.3.6 Optimization Techniques in Refactoring Sequencing

Several optimization techniques have been applied to refactoring sequencing,


including:

[Link] Single-Objective Optimization

Early approaches focused on single-objective optimization, primarily


targeting code quality metrics. For example:

1. Genetic Algorithms (GA): Genetic algorithms (GAs) are a class of


optimization algorithms inspired by natural selection and
genetics. They are used to find optimal or near-optimal solutions to
problems by evolving a population of candidate solutions over
successive generations. This evolution is driven by genetic operators
like selection, crossover, and mutation. [20].

2. Greedy Algorithms: A greedy algorithm is an algorithmic paradigm

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].

However, single-objective approaches may overlook trade-offs between


different quality attributes.

[Link] Multi-Objective Optimization

Real-world refactoring involves multiple conflicting objectives, leading to the


adoption of multi-objective optimization techniques:

1. NSGA-II (Non-dominated Sorting Genetic Algorithm): NSGA-II

(Non-dominated Sorting Genetic Algorithm II) is a widely used


evolutionary algorithm for solving multi-objective optimization
problems. It efficiently identifies a diverse set of optimal solutions,
known as the Pareto front, by leveraging techniques like non-dominated
sorting, crowding distance, and elitism. This makes it a popular choice
for problems where multiple, potentially conflicting, objectives need to
be considered simultaneously [22].

2. MOEA/D (Multi-Objective Evolutionary Algorithm Based on


Decomposition): MOEA/D, or Multiobjective Evolutionary Algorithm
based on Decomposition, is a type of evolutionary algorithm used for
solving multi-objective optimization problems. It works by breaking
down the complex multi-objective problem into simpler, single-
objective subproblems. These subproblems are then solved

44
simultaneously and collaboratively [23].

[Link] Search-Based Refactoring

Search-based software engineering (SBSE) techniques have been widely used


for refactoring optimization:

1. Particle Swarm Optimization (PSO): Particle Swarm Optimization

(PSO) is a computational method inspired by the social behavior of bird


flocks or fish schools, used to find optimal solutions for complex
problems. It works by initializing a population of "particles" that
represent potential solutions, each with a velocity and position. These
particles iteratively adjust their position and velocity based on their own
past best position and the best position found by the entire swarm,
aiming to converge towards the optimal solution [24].

2. Simulated Annealing (SA): Simulated Annealing (SA) is a


probabilistic metaheuristic algorithm used for approximating the global
optimum of a given function, particularly in large search spaces with
numerous local optima. It is inspired by the annealing process in
metallurgy, where a material is heated and then slowly cooled to reduce
defects and achieve a stable, low-energy state [25].

[Link] Machine Learning-Assisted Refactoring

Recent studies integrate machine learning (ML) to enhance optimization:

1. Reinforcement Learning (RL): Reinforcement Learning (RL) is a type

of machine learning where an agent learns to make decisions in an


environment to maximize a cumulative reward. It's like teaching a robot

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].

2. Deep Learning: Deep learning is a specialized area within machine

learning that employs artificial neural networks with multiple layers to


analyze data and extract complex patterns. It is inspired by the structure
and function of the human brain and excels at tasks like image
recognition, natural language processing, and more [27].

[Link] Key Challenges in Optimization-Based Refactoring Sequencing


While optimization-based refactoring sequencing offers significant advantages, it
also faces several key challenges that limit its widespread adoption and
effectiveness in real-world software development:
1. Defining and Quantifying "Optimal":
- Multi-Objective Nature: Software quality is not a single metric.
Refactoring can aim to improve maintainability, readability,
performance, testability, security, and more. These objectives can be
conflicting (e.g., optimizing for performance might reduce
readability). Defining a clear "fitness function" that balances these
often-competing goals is highly complex and domain-specific.
- Subjectivity: What constitutes "good" code can be subjective and
vary among developers, teams, and project contexts. Capturing this
human intuition and expertise in an objective, quantifiable manner
for an optimization algorithm is difficult.
- Long-Term vs. Short-Term Benefits: Some refactorings provide
immediate benefits, while others might lay the groundwork for future
improvements or prevent long-term technical debt. Quantifying these
long-term impacts in an optimization model is challenging.
2. Large and Complex Search Space:
- Combinatorial Explosion: Even for moderately sized systems, the
number of possible refactoring operations and their sequences can be
astronomically large. Exhaustively searching this space is
computationally infeasible.

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.

[Link] Quality Issues in Refactoring


The table 1.6 describes the different quality issues that arise in refactoring:
Table 1.6 Quality Issues

Sr. No. Quality Issue


s
1. Simple the code used must be simple and easy to
code understand.
2. Flexible the code used can be easily changed, when and
wherever
needed
3. Testing structure of program is dispersed upon refactoring
quickly

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

[Link] Refactoring Techniques


1. Red green development: Red-green development is an agile software
development method that is test-driven. Whenever a new function is unified with
previous code, then this module is used. The color red denotes the first experiment
done before adding a new function to the code. The color green denotes the
straight forward program section for the method to go through the test. Thus, an
expansion is built in frequent trial taken to weed away bad program in order to
improve the performance.

2. Branching by abstraction: Thus, this abstraction is done by the

converting the former executed program in up to date accommodate


modules. It is utilized in bigger tools that which include class
hierarchies, inheritance and extraction. Thus, implementation of
49
extraction combines both old execution and new one. By pull- up or
push-down methods the functions work with the abstraction as well as
links are being transferred. So, either archived class is converted to
parent class for further child classes. Thus, the previous functions are
deleted without affecting the original functions.

50
3. Compiling methods: The compiling methods are used to make the

code as useful as possible. The programmers use the interior philosophy

of a function while going through program [28,29,30]. Also, the number

of methods is used in compiling a program efficiently. Thus, the

objective is to eliminate repeated modules and number of large methods

in different blocks and to be used further. Such techniques include:

1. Inline methods

2. Extraction methods

3. Variables removed

4. Descriptive variables introduced

5. Algorithms replaced

6. Assignment of parameter list

4. Moving attributes between classes: In order for the efficiency of coding

the methods or attributes are being moved. We can move attribute within
different classes by following methods: -
1. Shift function
2. Shift features

3. Bring out class


4. Inline class
5. Hide delegate
5. Data organization: Data organization method’s main aim is to distribute

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

6. Simplifying conditional expressions: The refactoring uses the simple

conditional expressions [31]. These expressions can be carried out by


different methods given below:

52
1. Condition be for cement

2. Conditional expressions integration

3. Hypothetical explanation repetition

4. Control switch removal


5. Nestled conditions replaced

7. Simplifying method requests: We can use different methods given

below which helps to request functions to execute faster and easily: -


1. Method renaming
2. Parameters addition
3. Parameters removal
4. Explicit methods removal
5. Error codes exceptions

The proposed model of a refactoring categorization for software quality


improvement organizes refactoring techniques into several key categories, each
aimed at enhancing specific aspects of software quality. The model includes the
following components as shown in fig 1.10.

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.

In summary, the techniques of Red-Green Refactoring, Extract Method,


Simplifying Methods, Composing Method, and Abstraction each play a

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.

[Link] Refactoring Types Associated with Internal Quality


Attributes
Intrinsic quality is directly related to the system’s architecture. It is purely
just for advancement of the software [32,33,34]. If internal quality begins to
deteriorate, the system will be less adaptable in the future. As a result,
refactoring, clean coding, and constant testing are required. Table 1.7 describes
various internal quality attributes with explanation and the refactoring types that can be
applied on these attributes.

Table 1.7: Internal Quality Attributes

Attributes Explanation Refactoring


type
coupling is the degree of interdependency between
Cohesion the customize executed by a class. Coupling is a
measure of how closely two procedures or MOVE
modules are coupled and up to which level
software modules are connected with each other.
Through coupling, strength of the connections
within
modules are also evaluated the code structure is
within a class.
The amount of storage space and time needed to
Complexity execute a software programme are indicators of its MOVE
complexity. High complexity software
programme may be more likely to have errors.

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.

[Link] Refactoring Types Associated with External Quality


Attributes
Table 1.8 describes various external quality attributes with explanation and the
refactoring types that can be applied on these attributes.

Table 1.8: External Quality Attributes

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

The following table 1.9 describes various advantages and disadvantages of


refactoring.

Table 1.9: 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].

Self-contained methods prevent The cooperative work involved by


changes in bigger collaboration on
one part of the code from affecting refactoring could be surprising
other parts.
high.

As refactoring, is nothing but updating or changing the unnecessary coding.


Code refactoring includes number of methods to minimize code length and
execution time and an optimized code is received with the working of original
classes, methods and functions used in the starting of the program. This
refactoring is less costly than starting from new program coding. The major
help is in iterations and increments where the software is divided in number of
parts and there coding can be easily changed.
Refactoring cannot alter the class, functions, or classes of programme or
software system. Undisrupted code, on either side, might miss design code, as
59
well as clears and maintains code quality, resulting in a programme that is
easy to understand and comprehend, as well as error-free. As a result, it
reduces software bugs, but it's also about seeing code base as just a living
system that requires frequent maintaining of code to be strong.

60
[Link] Reasons for Refactoring
1. Makes the code simple and easy to understand

Code refactoring makes the code clear and easy to understand as it


removes all the concept of code smell. It helps to remove repetition of
code, irrelevant variables, large number of arguments, lengthy functions,
extended classes, large number of conditions or unimportant loops, etc.
It becomes easy to perform a task when code is simple, short and easy
to understand. It helps the programmers to add new features and to
remove all the errors. In other words, Code refactoring helps the user to
provide a comfortable environment with the new application. By this
process of reconstructing an application trial is done in order to realize
the functioning of each and every part and on what basis the software has
been built. It helps to know the working of the application in an
improved way.

[Link] the productivity of the application


A program will run properly and speedily if the program does not include
irrelevant classes, methods, operands or any other type of mess.
Updated program will increase the productivity of the software. Thus,
it will make the application faster and the user must not have to wait for
the required results. It will increase the user satisfaction and also increase
the goodwill of the company.

[Link] in terms of money and time


It becomes easy for the programmer to understand a new software if the
code is simpler and clear. It becomes difficult to understand a code which
is messy and the programmer will become frustrated when he tries to
understand it. If we do not carry out the process of refactoring it
becomes difficult to do any changes. The organization has to waste the
time as well as money if the software gets harmed due to some problems.

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.

1.4 Research Objectives

1. To study and analyze the existing software refactoring techniques.


2. To propose an optimization-based code smell refactoring sequencing
technique.
3. To implement the proposed approach on object-oriented software system.
4. To compare and validate the performance of proposed approach using
appropriate performance metrics.

1.5 Research Methodology

The figure 1.11 suggested step-by-step order must be followed in order to


accomplish the goals. To implement the suggested methodology, these
steps are carried out sequentially one at a time. The main objective of
previously mentioned analysis is to design and put forward a bad smell
detector that can aid software developers in producing high quality
software systems [12]. The major steps involved in the code smell
detection and prioritization are outlined as below.
 First, we studied existing machine learning, metaheuristic, and hybrid techniques
employed to design systems that aid in identifying and managing code smells and apply
refactoring sequencing techniques in order to achieve software quality and
maintainability, with the goal of supporting software developers in producing high-
quality software.

• We then proposed a novel search-based hybrid algorithm, which was used in

conjunction with HSHEP, Particle Swam Optimization, Deep Learning


And Hybrid Optimization Techniques and HTSA-SHO classifiers to detect various
types of code smells and apply refactoring sequencing using object-oriented systems.
Sample applications developed in object-oriented programming languages were used to
evaluate the proposed approach. These applications, along with associated quality
metrics and code smell specifications, were provided as input to the system.

• 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.

• An empirical study was conducted to analyze the effect of this sequencing on


refactoring decisions, demonstrating how an optimal sequence can improve
maintainability and reduce technical debt.
• Finally, a comparative analysis was carried out to assess the effectiveness of the
proposed refactoring sequencing approach in relation to existing code smell detection
and prioritization methods.

Fig 1.11: Proposed Methodology

1.6 Contribution to the Thesis

1.6.1 Hybridization

Rule-based code smell detection techniques and reafactoring sequencing


technique [37, 38, 39], despite their demonstrated performance, encounter
significant challenges. A primary issue stems from their reliance on

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

A hybrid algorithm in computer science is a powerful approach that combines two


or more distinct algorithms to solve the same problem more effectively than any
single algorithm could on its own. The goal of hybridization is to leverage the
strengths of each component algorithm while mitigating their individual weaknesses
[45,46].

[Link] Key Characteristics of Hybrid Algorithms:

1. Combination of Strengths: The core idea is to combine algorithms that


complement each other. For example, one algorithm might be excellent at global

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.

3. Improved Performance: The primary motivation for hybridization is to achieve


better overall performance in terms of:

- Accuracy/Quality of Solution: Finding more optimal or higher-quality


solutions.

- Computational Speed/Efficiency: Reaching a solution faster.

- Robustness: Being less sensitive to various types of input data or problem


instances.

- Scalability: Handling larger or more complex problems.

4. Dynamic Switching or Integration: Hybrid algorithms can operate in various


ways:

- Sequential/Cascading: One algorithm performs a task, and its output


becomes the input for the next algorithm.

- Interleaving/Alternating: Algorithms take turns, or switch between phases


of execution.

- Cooperative/Collaborative: Algorithms run in parallel, sharing information


and influencing each other's search.

- Parameter Tuning: One algorithm might optimize the parameters or


configuration of another.

[Link] Hybrid Spotted Hyena and Emperor Penguin (HSHEP)


optimization-based algorithm

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].1 HSHEP Algorithm

Refactoring sequencing, a widely used technique, is employed to address code-


smells
and improve its structure while retaining overall functionality and actions. This
process involves two primary steps: (1) Detecting portions of code that require
improvement, such as code-smells, and (2) identifying suitable refactoring
sequencing techniques to achieve the desired improvements. The initial approach
involves applying a novel optimization algorithm namely Hybrid Spotted Hyena
and Emperor Penguin optimizer (HSHEP). This hybridized algorithm
commonly aims to combine the strengths of both approaches. Once the results
from the initial spotted hyena optimizer (SHO) algorithm are obtained, we run the
hybridized algorithm to demonstrate the advantages of combining with EPO
67
algorithm. This optimization-based code smell refactoring sequencing technique
could help to ensure that code refactoring is completed efficiently and effectively,
reducing the risk of introducing new bugs or affecting the code’s functionality.
Both Emperor Penguin Optimization (EPO) and Spotted Hyena Optimization (SHO) are
metaheuristic algorithms effectively employed in hybrid techniques for refactoring sequencing.
In this context, "hybrid" means they are combined with software engineering tools like static
analysis and software metrics. Initially, static analysis identifies code smells and potential
refactoring operations, which are then encoded as "penguins" (EPO) or "hyenas" (SHO)
representing candidate refactoring sequences. The algorithms' search is driven by a
comprehensive "fitness function," which simulates applying the sequence and evaluates its
impact on software quality using metrics like coupling, cohesion, and maintainability. EPO
leverages its huddling behavior to balance exploration and exploitation of the sequence space,
moving towards optimal "warm" solutions. SHO, conversely, uses its cooperative hunting
strategy to identify and converge on the "prey" (optimal sequence) through iterative refinement
and "chaining." Ultimately, both algorithms provide intelligent search mechanisms, guided by
empirical code analysis, to automate and optimize the complex process of determining the most
beneficial refactoring order.

[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].

Fitness(r) =n−1 Σ i=0 (yi ∗ (𝛿 ∗ Severity (ci) + 𝛾 ∗ Priority (ci)


+ 𝛽 ∗ Risk (ci) + 𝛼 ∗ Importance (ci)))

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.

- Severity: In practical scenarios, the influence or significance of code smells is not


uniform across all instances. Each specific occurrence is associated with a severity
rating that enables designers to promptly identify and address the most crucial
occurrences of each
code smell. More precisely, identical types of code smells can manifest in various code
segments, each carrying distinct impact scores on the system’s architecture. These
impact
scores gauge the relative magnitude of the code smell, encompassing both its
comparative
severity and the absolute detrimental effect on the overall system quality.

- Priority: Developers commonly assign varying degrees of significance to distinct types


of code smells, which can have diverse implications for the overall quality of the
system. By prioritizing detected code smells based on their individual preferences,
developers can arrange these types in a ranked order. This prioritization approach
empowers designers to optimize time utilization and enhance the effectiveness of
resource allocation for maintenance tasks within their software projects.

- 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.

- Importance: Typically, developers require an understanding of the key code segments


(such as classes and packages) within the entire software system to effectively direct
their efforts toward enhancing their excellence. Within a standard software package
system, pivotal code segments are those that undergo frequent modifications throughout
the development and maintenance stages, facilitating the addition of new features,
adaptation to changes, and overall enhancement of the software’s structural integrity [47, 48].

[Link].4 Particle Swam Optimization, Deep Learning And Hybrid


Optimization Techniques

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.

1.6.2.1Comparison of Hybrid Spotted Hyena and Emperor Penguin


Optimizer (HSHEP) with Particle Swam Optimization, Deep Learning
And Hybrid Optimization Techniques

When comparing approaches for refactoring sequencing, a Hybrid Spotted


Hyena and Emperor Penguin Optimizer (HSHEP) offers a combined
metaheuristic solution, leveraging SHO's global exploration and EPO's balanced
search to navigate the complex combinatorial space of refactoring orders. Its
strength lies in its ability to effectively find optimal or near-optimal sequences by
iteratively evaluating solutions through a fitness function tied to software
metrics, without requiring pre-labeled training data for its core optimization.
However, it can be computationally intensive and requires careful parameter
tuning. In contrast, Deep Learning (DL) excels at learning intricate patterns
from vast code datasets, making it highly effective for tasks like accurate code
smell detection, refactoring opportunity recommendation, and impact prediction.
While powerful for understanding and predicting, DL typically doesn't directly
solve the combinatorial sequencing problem; it often needs to be hybridized with
optimization techniques. Its main drawbacks include a heavy reliance on large,
high-quality labeled training data (which is scarce for complex refactoring
scenarios), a "black box" nature, and high training costs. Finally, Particle
Swarm Optimization (PSO) stands as a simpler, standalone metaheuristic that
directly optimizes refactoring sequences by simulating swarm intelligence. It's
generally easier to implement and can be computationally efficient, but it might
be prone to premature convergence in highly complex problem landscapes and,
like HSHEP, does not inherently learn general patterns from past refactoring
outcomes. Ultimately, the choice among these depends on factors like data
72
availability, computational resources, problem complexity, and the desired
balance between automation, interpretability, and optimal solution quality. The
comparison is shown in table 1.10.
Table 1.10: Comparison of Hybrid Spotted Hyena and Emperor Penguin
Optimizer (HSHEP) with Particle Swam Optimization, Deep Learning And
Hybrid Optimization Techniques

Feature/Criterion HSHEP (Hybrid Deep Learning Particle Swarm


Metaheuristic) (ML) Optimization
(PSO)
Primary Role Optimization: Prediction/ Optimization:
Finding optimal RT Recommendation: Finding optimal
sequences. Detecting smells, RT sequences.
suggesting RTs,
predicting impact.
"Learning Iterative population- Learning complex Iterative
Mechanism" based search & patterns from large swarm-based
fitness evaluation. datasets. search & fitness
evaluation.
Computational High (due to iterative Very High for Moderate
Cost fitness evaluation for training, lower for (generally less
many solutions) inference. than HSHEP,
more than
simple
heuristics)
Development EffortModerate to High (data Moderate
High collection, model (simpler to
(implementing/tunin architecture, implement)
g two heuristics + training)
hybridization)

[Link] Performance Metrics


To calculate the gain this algorithm uses Fitness, Information Gain, and Gain Ratio
metrics.

Algorithm Flowchart Steps:


1. Start: Beginning of the entire framework.
2. Pre-processing & Data Preparation: Initial steps to get data ready.
3. Collect & Preprocess Codebase Data: Gather raw source code, extract
Abstract Syntax Trees (ASTs), control flow graphs, historical commit data,
73
and static metrics.
4. Create & Label Training Data for DL Models: This is crucial. Collect
examples of refactoring (before/after states, impact on metrics), code smells
(labeled as present/absent), etc., to train the Deep Learning models.
5. Train Deep Learning Models:
o DL Model 1: Code Smell Detector: A DL model trained to identify
code smells accurately (e.g., using GNNs on ASTs, or CNNs on code
sequences).
o DL Model 2: Refactoring Impact Predictor: A DL model trained
to predict how applying a specific refactoring (or a small pattern of
refactorings) will affect various software quality metrics (e.g.,
predicted change in CBO, LCOM, maintainability index). This is key
for speeding up fitness evaluation.
o DL Model 3 (Optional): Refactoring Suggestor: A DL model that
suggests which refactoring types are most suitable for detected
smells or code contexts.
6. Initialization Phase: Setting up the optimization.
7. Detect Initial Code Smells (using DL Model 1): Apply the trained smell
detector to the target codebase to identify existing design faults.
8. Generate Pool of Candidate Refactorings: Based on the detected smells,
create a list of potential refactoring operations that could address them. DL
Model 3 could assist in prioritizing or suggesting these.
9. Initialize PSO Swarm: Create an initial population of "particles," where
each particle is a candidate refactoring sequence (e.g., a permutation of
selected refactorings).
[Link] Initial Swarm Fitness: Calculate the fitness score for each
sequence in the initial swarm. Critically, this uses DL Model 2
(Refactoring Impact Predictor) for a fast estimation of impact,
significantly reducing computation time compared to full static analysis.
[Link] Global Best (gBest) and Personal Bests (pBest): Set the best
sequence found so far by the entire swarm (gBest) and by each individual
particle (pBest).
[Link] Optimization Loop: The iterative process where PSO searches for
the optimal sequence.
[Link] Particle Velocities (PSO Equations): Each particle's velocity is
adjusted based on its pBest, gBest, and inertia.
[Link] Particle Positions (Refactoring Sequences): Particles move to
new positions, generating new candidate refactoring sequences.
[Link] Swarm Fitness:
[Link] each Particle (Sequence): Process each newly generated sequence.
[Link] Sequence Impact (using DL Model 2 for fast estimation): The
core hybrid step where the trained DL model quickly estimates the fitness
of the sequence without full static analysis.
74
[Link] Particle's pBest: If the current sequence is better than a particle's
previous best, update its pBest.
[Link] gBest of the entire swarm: If any particle found a sequence better
than the current gBest, update gBest.
[Link] Validation: A crucial control mechanism to ensure accuracy.
[Link] it time for full validation?: A condition (e.g., every N iterations, or if
the gBest hasn't improved for a while).
[Link] Full Static Analysis & Metric Recalculation on best
sequences: If yes, take the top performing sequences (e.g., gBest and top k
pBests) and perform a rigorous, full static analysis. This is the "ground
truth" evaluation.
[Link] gBest based on full evaluation if necessary: If the full validation
reveals a different "true" best, update gBest accordingly.
24.(Loop back): Continue to the next iteration of the main loop until
termination criteria are met.
[Link] Loop: The optimization process terminates.
[Link] Global Best Refactoring Sequence (gBest): The final, most
optimal sequence found.
[Link]: Algorithm finishes.

The combination of Particle Swarm Optimization (PSO) and Deep Learning


techniques significantly enhances software maintainability. Improved precision,
recall, and overall performance suggest that these hybrid methods provide a
robust approach to code smell detection, making the refactoring process more
effective and reliable.

[Link] Hybrid TSA-SHO Model for Refactoring Sequencing (HTSA-SHO)


This hybrid model aims to leverage the exploration capabilities of TSA with the
exploitation strengths of SHO to effectively optimize the order of refactoring
operations.

Overall Hybrid Algorithm Flow (Mathematical Perspective):

For each iteration t=1 to Max_Iterations:

PTSA): For each individual X it ∈ PTSA:


2. TSA Phase (Exploration - Applied to a portion of the population, e.g.,

o Calculate avoiding collision and moving towards food components.


o Update X it+1 using TSA rules, but applying permutation operators.

▪ 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

combined updated population (after TSA phase). For each hyena X jt ∈


population, e.g., PSHO): Let PSHO be the M best individuals from the

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.

1.6.3 Problem Statement: Sequencing Refactoring Techniques for


Sustainable Software Maintenance

Developing high-quality software is paramount. When code quality is low, it


significantly escalates maintenance time, cost, and effort. After initial
development, software often transitions to a dedicated maintenance team, which
may not possess the same deep, nuanced understanding of the codebase as the
original developers. This knowledge gap can lead to new modifications, however
well-intentioned, inadvertently introducing code smells. These aren't errors, but
structural indications of deeper design issues that hinder functionality, diminish
software quality, and inflate maintenance overhead. Therefore, it's crucial to
accurately identify these smells and prioritize them based on their impact on
overall software quality.
Current code smell detection techniques—ranging from metric-based and manual
to machine learning-based and metaheuristic approaches—all have limitations.
Challenges include human error in manual detection, the subjectivity of setting
effective metric thresholds, and the complexities of dealing with false positives
76
and negatives. This highlights a critical need to evaluate the efficiency of existing
methods and, more importantly, to develop more robust and efficient approaches
for code smell detection.
Moreover, existing detection methods often produce an overwhelming list of
smells. Not all of these are equally harmful to software quality. Faced with
limited time and budget, developers are naturally reluctant to undertake extensive
refactoring without a clear understanding of each smell's actual impact. This
emphasizes the urgent need for an effective code smell refactoring sequencing
approach that can sort detected smells by their potential harm to software quality
attributes. Such prioritization would motivate developers to tackle the most
critical issues, fostering greater adoption of vital refactoring practices.
However, simply detecting and refactoring smells isn't enough. Many code
smells are interdependent, and the order in which refactoring techniques are
applied can significantly influence their effectiveness, cost, and risk. An ill-
conceived sequence can introduce new problems, negate previous improvements,
or even fail to fully eradicate the intended smells. This highlights a critical, often
overlooked challenge: the optimal sequencing of refactoring techniques.
Without an intelligent approach to determine the most effective order for
applying refactorings, even well-intentioned efforts can fall short, underscoring a
pressing need for advanced methods to guide developers in implementing
refactoring strategies efficiently and sustainably.

1.7 Organization of the Thesis


The thesis is organized as per the following chapters:

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 2: Literature Review


This chapter presents a comprehensive review of the existing literature related to code smell
detection and refactoring sequencing. It begins with an analysis of various code smell detection
77
techniques, including manual inspection, metric-based methods, machine learning approaches,
optimization algorithms, and hybrid techniques that integrate search-based methods. The review
then shifts focus to the current advancements in the area of refactoring sequencing, highlighting
strategies used to prioritize and order code smells for effective resolution. Finally, the chapter
identifies key research gaps within the existing studies, particularly the lack of integration
between accurate detection and optimal sequencing of refactoring tasks. These gaps serve as the
foundation for formulating the research problem addressed in this work.
Chapter 3: Hybrid Algorithm: HSHEP
In this chapter a unique hybrid strategy based on the HSHEP algorithm, which applies single-
objective optimization for effective refactoring of design smells unlike existing approaches. The
proposed method determines the optimal refactoring sequence by prioritizing code smells
across multiple models to enhance software quality and minimize maintainability issues.
Evaluated on a large custom dataset containing over 29,000 class records from five widely-used
open-source projects, the approach demonstrated superior performance compared to traditional
methods. HSHEP, an enhanced hybrid of the Emperor Penguin Optimizer and Spotted Hyena
Optimizer, was assessed across five performance metrics: execution time, hypervolume,
coverage, spacing, and a novel relative accuracy coverage score. It identified over 2,850
optimal refactoring sequences of length 100 after 1,000 iterations, outperforming single-
objective solutions in both efficiency and accuracy. The method not only detects and resolves
all reported pattern smells but also yields significant improvements in software reliability and
maintainability.

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.

Chapter 6: Conclusion and Future Scope


This chapter concludes the thesis by providing a brief overview of proposed approaches and
providing an insight into the future work. This chapter concludes the thesis by summarizing the
proposed approaches and outlining future research directions, with a central focus on
78
refactoring sequencing. The thesis presents key contributions in the areas of code smell
detection, and the development of optimized refactoring sequences to enhance software quality.
Special emphasis was placed on how intelligently ordered refactoring can significantly improve
maintainability and reduce technical debt in object-oriented [Link] research can
explore the application of hybrid optimization in broader software engineering tasks, such as
defect prediction, design pattern identification, and architecture recovery. There is also potential
to develop intelligent, real-time refactoring tools that dynamically adapt sequencing strategies
based on software evolution. Further refinement of algorithm integration, scalability across
larger systems, and reduction of computational overhead will enhance practical deployment.
Additionally, incorporating explainable AI techniques may improve developer trust and
transparency in automated refactoring recommendations.

79

You might also like