the impact of refactoring legacy systems on code quality ...1114582/fulltext01.pdfmaintaining legacy...

47
The Impact of Refactoring Legacy Systems on Code Quality Metrics By Alan Jonsson

Upload: others

Post on 26-May-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

The Impact of Refactoring Legacy Systems on Code Quality Metrics

By Alan Jonsson

Page 2: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

Abstract Maintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

maintain the code is actually beneficial or not. This paper examines the impact of refactoring on code

quality by systematically applying proven refactoring techniques and measuring its effect on code

quality through code metrics.

As an application at Xylem was being modified the application was simultaneously refactored. Before

any refactoring was done the code quality was measured by maintainability index, cyclomatic

complexity, depth of inheritance, class coupling and lines of code. Some parts of the application were

re-written, others were refactored. By measuring the same metrics after the application was

refactored it was found that the metrics had improved, indicating that the code quality had

increased.

Keywords: Refactoring, Legacy Systems, Design science, Design and Creation, Modernizing.

Page 3: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

Table of Contents 1. Introduction ......................................................................................................................................... 1

1.1 Background .................................................................................................................................... 1

1.1.1 The application ....................................................................................................................... 2

1.2 Problem Description ...................................................................................................................... 3

1.3 Motivation / Purpose .................................................................................................................... 3

1.4 Objectives / Research questions ................................................................................................... 4

1.5 Scope / Limitations ........................................................................................................................ 4

2. Method ................................................................................................................................................ 4

2.1 System Development Design ......................................................................................................... 5

2.2 Design science ............................................................................................................................... 5

2.2.1 Problem identification and motivation .................................................................................. 5

2.2.2 Define the objectives for a solution ....................................................................................... 5

2.2.3 Design and development ........................................................................................................ 5

2.2.4 Evaluation ............................................................................................................................... 6

2.3 Code Smells ................................................................................................................................... 6

2.3.1 Duplicate Code ....................................................................................................................... 7

2.3.2 Long Method .......................................................................................................................... 7

2.3.3 Large Class .............................................................................................................................. 7

2.3.4 Long Parameter List ................................................................................................................ 7

2.4 Refactoring Methods ..................................................................................................................... 8

2.4.1 Extract Method ....................................................................................................................... 8

2.4.2 Extract Class .......................................................................................................................... 10

2.4.3 Replace Parameter with Method ......................................................................................... 11

2.4.4 Preserve Whole Object ......................................................................................................... 11

2.4.5 Introduce Parameter Object................................................................................................. 11

2.5 Quality of the code ...................................................................................................................... 12

2.6 Data analysis ................................................................................................................................ 12

2.6.1 Maintainability Index ............................................................................................................ 12

2.6.2 Cyclomatic Complexity ......................................................................................................... 13

2.6.3 Depth of inheritance ............................................................................................................ 13

2.6.4 Class Coupling ....................................................................................................................... 13

2.6.5 Lines of Code ........................................................................................................................ 13

3. Results ............................................................................................................................................... 14

Page 4: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

3.1 Project Metrics ............................................................................................................................ 15

3.2 Method Metrics ........................................................................................................................... 15

3.2.1 UpdateAllCombos ................................................................................................................. 15

3.2.2 ResetOldValuesWhenSalesCodeChanged_New ................................................................... 16

3.3.3 SetUpDynamicCharacteristics .............................................................................................. 17

4. Discussion .......................................................................................................................................... 18

4.1 Limitations ................................................................................................................................... 20

4.2 Further research .......................................................................................................................... 20

5. Conclusion ......................................................................................................................................... 21

6. References ......................................................................................................................................... 22

7. Appendices ........................................................................................................................................ 24

Appendix A ........................................................................................................................................ 24

Appendix B ........................................................................................................................................ 40

Page 5: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

1

1. Introduction

This project has been done at Xylem water solutions. Xylem water solutions is a leading global water

technology company, they design, manufacture and service engineered solutions of a wide variety of

critical applications.

The business in Sweden started as a blacksmith in 1901. Later it developed in to the company Flygt

and was acquired by the international concern ITT. In 2011 parts of ITT, which dealt with water and

pumps, was reconstituted as Xylem water solutions, henceforth Xylem. Xylems global headquarters is

located in Rye Brook, New York and the Swedish headquarters is located in Sundbyberg, Stockholm.

Xylem has approximately 16 000 employees in more than 150 countries around the world (“Xylem -

Let’s Solve Water - United States,” 2015). Xylems revenue for 2016 was $ 3,771 million (Xylem Water

Solutions, 2016).

Xylem manufactures pumps, mixers and turbines to provide clean water and dispose of wastewater.

The name Xylem is derived from the classical Greek word and it is the tissue that transports water in

plants.

Xylem has a number of web applications designed to provide customers with information about their

products. Among them is a web application called Technical Product Information (TPI). It is used by

customers to get information and technical documentation about Xylem’s pumps and products. This

is the application this paper is based around.

1.1 Background

Since the 90’s the Netscape Plugin API (NPAPI) has been used as a standard to extend browser

functionality. But since then browsers have been updated to the point where the NPAPI’s instead are

the leading cause for crashes and security incidents. This has, coupled with the fact that NPAPI isn’t

supported on mobile devices, led to Googles decision to phase out support for the NPAPI. (“Saying

Goodbye to Our Old Friend NPAPI,” 2013) As of September 1, 2015 the popular web browser Google

Chrome permanently disabled support for NPAPI plugins, rendering Chrome users unable to access

web applications made with the NPAPI plugin. With Mozilla Firefox and Microsoft’s Internet Explorer

also disabling support for NPAPI many applications will no longer function unless updated. In many

cases updating is a pretty simple procedure where for example Silverlight code is replaced with

HTML/CSS/JS.

Page 6: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

2

1.1.1 The application

The application that is being re-written is called Technical Product Information, TPI for short, it is

used by both customers and as an in-house application. It is used to access information about pumps,

mixers and other products manufactured by Xylem. There are four ways to search for the

information: search for a specific brand, search by sales code, search for documents published within

a certain time span and finally search using publication number.

Searching for a specific brand presents the user with five different drop-down menus as seen in

figure 1. The first drop-down contains all the different brands Xylem own. Based on what brand is

selected the user can now select what segment they would like to search for. Then based on the

segment, a series can be selected and based on series, a sales code is selected. For example, the user

selects the brand “Flygt”, segment “pumps & mixers”, series “3000 – wastewater pumps” and finally

sales code “3153”. There is also the option of adding a version code to your search but this is not

required.

Fig.1 Search by brand tab from the original TPI application

Searching using sales code, the user simply types in the desired sales code (and once again has the

option of typing in version code) and documents belonging to that sales code are presented to the

user.

The publication search is very similar to the brand search except for the addition of “from” and “to”

dates. They indicate that only documents created in the specified interval should be shown to the

user.

Search using publication number works similarly to sales codes search except the user does not have

the option of adding a version code to the search.

All of the above mentioned ways of searching also include a characteristics pane. This pane contains

ways of filtering search results based on for example language, document type, pressure

characteristics or hydraulic type.

The application is designed in such a way that the user should not be able to return an empty search

result. This means that when using the brand search, only current and valid options are presented

when the user selects different brands or segments. The sales code search tab has an autocomplete

Page 7: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

3

feature which will not let you search unless a valid sales code in entered into the input field. The

publication date and publication number tabs however do not meet this requirement.

1.2 Problem Description

Maintaining legacy code is an issue many companies face and in the end, programmers have to deal

with. As functionality of applications is maintained and improved, the quality of their code base

deteriorates (Mens & Tourwé, 2004). How to produce and maintain code in a way that does not

reduce or even improves code quality is beneficial to everyone involved with programming.

The standard and supported web browsers at Xylem are Internet Explorer and Chrome. This means

that all applications should be accessible through either of these browsers. The TPI application is

written in C# and the front end UI made with Microsoft Silverlight. Silverlight is a plugin that utilizes

the NPAPI and since Chrome no longer supports the NPAPI users are unable to access the application

through Chrome.

This leads to the task, which is to re-write the application without Silverlight. The task of removing

Silverlight might seem trivial at first but since the application is almost ten years old, with all the fixes

implemented along the way that entails, simply understanding the code is no trivial matter. It is not

merely a matter of translating Silverlight’s XAML to html/css/js.

1.3 Motivation / Purpose

There is a difference between re-writing and refactoring. Martin Fowler defines refactoring as a

change made to the internal structure of software to make it easier to understand and cheaper to

modify without changing its observable behavior (Fowler & Beck, 1999). A rewrite in computer

programming is the act or result of re-implementing a large portion of existing functionality without

re-use of its source code or writing inscription. Before any re-writing can be done the application has

to be understood. Not just what it does and for what purpose but understand the code and how it

does what it does. The TPI application was written almost ten years ago, primarily by people no

longer working at Xylem. The documentation could be described as scant, at best. In order to fully

understand the code, first some manner of refactoring is required. Refactoring enables re-writing by

clarifying what and how each refactored method does what it does. Konstantinos Stroggylos and

Diomidis Spinellis investigated if refactoring improves code quality in “Refactoring – Does it improve

software quality?” from 2007. After analyzing logs of open source version control systems and then

examining how some software metrics were affected, they concluded that it does not in fact improve

code quality metrics.

Page 8: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

4

This is contrary to what one would assume considering that refactoring is widely recognized as a way

to improve the internal structure of software (Bois, Demeyer, & Verelst, 2004) and how often

refactoring is mentioned in conjunction to code quality. There are also several papers written on

refactoring and code quality, a google scholar search for "refactor" "code quality" yields around 1680

results.

If done properly this will hopefully have the added benefit of facilitating future changes to the

application, where future programmers won’t have to spend a week adding a feature or making a

change that would have taken an hour if he/she had understood the code from the beginning. This

paper deals with the effectiveness of these refactorings.

1.4 Objectives / Research questions The purpose of this thesis is to:

Describe the process of changing and refactoring the system and determine in what way refactoring

impacts code quality.

1.5 Scope / Limitations

The standard for developing web applications at Xylem is using the MVC design pattern as well as

html/js/angular. The entire visual studio solution consists of nine different projects. The only project

that was changed and refactored was a project called TPI.Web. The TPI.Web project contains the

MVC framework. Models and views were not refactored but instead written from scratch using

html/js. The majority of the logic is contained within the controller written in C#. This is where the

majority of the refactoring has taken place. Hence this is where the main analysis and comparisons

are done.

In order to make database calls, the TPI application uses a service called BusinessDataService.

Everything needed to pair the right pumps with the correct documentation can be retrieved through

the service and so no refactoring or changes have to be made to the service.

The impact on performance has not been touched upon since that is outside the scope of this

project. And so while refactoring might have an impact on performance none of the metrics used

measure performance.

2. Method

The design and creation method used is described in Briony Oates's book Researching Information

Systems and Computing (2006). The process includes refactoring, how this is done is described by

Page 9: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

5

Martin Fowler and Kent Beck in their book Refactoring: Improving the Design of Existing (1999).

While simultaneously following some of the guidelines laid out by Hevner et al. as described in the

paper “A Design Science Research Methodology for Information Systems Research” (2014) by

Peffers, Tuunanen, Rothenberger and Chatterjee.

2.1 System Development Design

In short the design and creation method entails creating a tangible end product but the main focus is

on the development process (Oates, 2006). The focus is on the process but in order to understand

and illustrate it, an IT artifact is created. A common pitfall when conducting design and creation

research is that it turns into “normal” design and not research (Oates, 2006). In this case this is

avoided by systematically applying the refactoring methods described by Fowler and Beck (1999) and

in the end evaluating the positive effects this has had on the end product.

2.2 Design science

Roughly following Ken Peffers “A design science research methodology for information systems

research” (2014), the overall research process looked like this.

2.2.1 Problem identification and motivation

Since google decided to discontinue support for the NPAPI, the TPI application no longer worked on

its intended platforms. This is what led to the decision to replace Silverlight with a more modern

framework. However making the change took considerable more effort than first anticipated and so

the decision was made to refactor parts of the code to enhance understandability, code quality thus

facilitating future change.

2.2.2 Define the objectives for a solution

The solution is a rather simple one; refactor the code to make it more manageable. But the focus of

this paper is not on solely the end result, even though that is of course taken in to consideration, but

instead evaluating the benefits of the process on the end result.

2.2.3 Design and development

The overall refactoring process, detailed below, is described in “A Survey of Software Refactoring”

(2004) by Mens and Tourwé with slight modifications. The actual refactoring methods used followed

the guidelines for refactoring described by Fowler and Beck (1999). Not all refactoring methods

described by Fowler are used and some have been slightly modified to fit this project.

1. Identify what the purpose of a method is. This is not part of process described by Mens and

Tourwé. Before any change could be made the applications needed to be understood. This was

Page 10: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

6

achieved through debugging the application and following its control flow to get an understanding of

what each method does.

2. Identify what methods needed refactoring. How this is done is described later under the section

Code Smells.

3. Determine which refactoring should be applied to problematic methods or code blocks. This was

done by comparing the code in the application to Fowler and Becks (1999) description of code smells

and how to solve those problems.

4. Apply the refactoring. By following Fowlers instructions on how to perform the refactoring

techniques the appropriate refactorings were applied. Often a string of refactoring techniques were

used, such as applying extract method several times, in a row before issues were solved

satisfactorily.

5. Test that the behavior has not changed in any unintended way. After each refactoring was

applied they were tested to make sure they still functioned in the expected manner and delivered

the same results as before. In an effort to save time, no automated tests were written and all

refactored methods were instead tested by hand.

6. Assess the effect of the refactoring on the code quality metrics. This was not done intermittently

after each refactoring but instead at the end after all refactoring were done.

2.2.4 Evaluation

Evaluation has been done through generating quantifiable code metrics used to compare code

quality metrics before and after the refactoring process.

2.3 Code Smells

While the end result will be analyzed with quantifiable metrics (described later under 2.6 Data

Analysis), what was refactored was determined by what Fowler and Beck (1999) describe as bad

smells in code. This is because, according to themselves no metric rivals informed human intuition

and so they give no precise criteria for when you should refactor (Fowler & Beck, 1999). They do

however give examples.

Fowler and Beck (1999) describe a number of bad smells in code such as Speculative Generality,

Temporary field and message chains to name a few. These are indeed all code smells but because of

the author’s relative inexperience as well as the time constrains, the focus was placed on code smells

that were more obvious and easier to detect such as duplicate code, long methods, large classes and

long parameter lists. These are also, according to Fowler, the most common and stinky ones.

Page 11: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

7

All of the code smells names are pretty self-explanatory, nonetheless here is a short description of

the smell and what can be done to deal with them. The ways to deal with the code smells are first

presented in conjunction with the code smell and explained later under 2.4 Refactoring Methods.

2.3.1 Duplicate Code

Duplicate code is where you see the same code structure in more than one place. The simplest

duplicate code smell is where you have the same expression in two or more methods of the same

class. The simplest way to deal with duplicate code is to use Extract Method (Fowler & Beck, 1999).

There is also the situation where you have duplicate code in different classes. Instead of using Extract

Method you use Extract Class on one of the classes and use the new component in the other (Fowler

& Beck, 1999).

2.3.2 Long Method

The Long Method smell can be explained as: the longer a procedure is the harder and more difficult it

is to understand. The key is having short methods, not in the sense of having fewer lines of code but

the semantic distance between what the method does and how it does it. Fowler explains it as when

you feel the need to comment something, instead try and write a method. Most of the time this is

achieved by using Extract Method on the parts that seem to fit together. (Fowler & Beck, 1999)

One way of identifying code that can be extracted is to look for comments. Code that has comments

describing what it is supposed to do can often be extracted into a new method with its name based

on the comment (Fowler & Beck, 1999).

2.3.3 Large Class

A large class often has too many instance variables, and with that probably some duplicate code. You

should use Extract Class to extract variables that fit well together into a component. There is also a

possibility that you can use Extract Class or Extract Subclass several times if not all instance variables

are used all of the time. (Fowler & Beck, 1999)

2.3.4 Long Parameter List

Long parameter lists are hard to understand and because they are prone to change when you need

more data they have a tendency to become inconsistent. This is less of an issue when working with

object oriented code. When you can get all the data you need in one parameter and then use a

request to another object you can use Replace Parameter with Method. If there is a lot of data in an

object you can use Preserve Whole Object to keep the replace the parameters with the object. If you

have data with no real object you can use Introduce Parameter Object to bundle them into an object.

(Fowler & Beck, 1999)

Page 12: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

8

2.4 Refactoring Methods Here follows and explanation of the refactoring methods mentioned in the previous section. For

more thorough motivations and several more examples Fowlers book is highly recommended.

2.4.1 Extract Method

Essentially what extract method does is it takes a clump of code and creates a method from the

clump. The original clump is replaced by a method call to the new method. The new method should

have a name that describes what it does, not how it does it. Without any local variables extract

method is easy to apply. Extract method is often used on methods that are too long, therefore they

often contain variables. In that case you have to check whether any of the local variables are changed

by the extracted code. If they are affected by the change, deal with that and try to compile the code.

(Fowler & Beck, 1999)

For example: The original TPI contains a method called UpdateAllCombos, which as the name implies

updates all combo boxes in the application. This method is large; it consists of 298 IL lines of code. IL

stand for intermediate language, when .NET projects are compiled they are not directly translated to

binary code. Instead it is first translated to what is called intermediate language, it is the lowest

human-readable programming language (Boschman, 2006). As one might expect it does not simply

update all combo boxes as the name implies. It also contains all the logic needed to filter through all

the data to grab the correct information that the combo boxes should contain. Amongst other things

it contains the logic to decide whether to use current edition data or old edition data (the application

can be used to show information about old products). Extract method was used to extract that piece

of code and then again to split half of that code into two methods, one called ShowAllEditions, used

to get current and old editions and, one called DontShowAllEditions, used to show only current

editions.

The original code to filter out current or old data looks like this:

if (versionCode == null || versionCode == "")

{

if (SearchArguments.ShowOldEditions)

{

if (selectAllCategories)

{

if (selectAllLangs)

{

commonCatLangGroupIDs = (from catlang in allCatLangGroupIDs select

catlang.GroupID).Distinct();

filterCatGroupIDs = commonCatLangGroupIDs;

filterLangGroupIDs = commonCatLangGroupIDs;

}

else

{

filterLangGroupIDs = (from catlang in allCatLangGroupIDs select

catlang.GroupID).Distinct();

commonCatLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.LangID, myLang.ID) select

catlang.GroupID).Distinct();

Page 13: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

9

filterCatGroupIDs = commonCatLangGroupIDs;

}

}

else

{

if (selectAllLangs)

{

filterCatGroupIDs = (from catlang in allCatLangGroupIDs select

catlang.GroupID).Distinct();

commonCatLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.CategoryID, myCat.ID) select

catlang.GroupID).Distinct();

filterLangGroupIDs = commonCatLangGroupIDs;

}

else

{

filterCatGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.LangID, myLang.ID) select

catlang.GroupID).Distinct();

filterLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.CategoryID, myCat.ID) select

catlang.GroupID).Distinct();

commonCatLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.CategoryID, myCat.ID) &&

string.Equals(catlang.LangID, myLang.ID) select

catlang.GroupID).Distinct();

}

}

}

else

{

if (selectAllCategories)

{

if (selectAllLangs)

{

commonCatLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.EditionStatusID, idForStatusNew) select

catlang.GroupID).Distinct();

filterCatGroupIDs = commonCatLangGroupIDs;

filterLangGroupIDs = commonCatLangGroupIDs;

}

else

{

filterLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.EditionStatusID, idForStatusNew) select

catlang.GroupID).Distinct();

commonCatLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.LangID, myLang.ID) &&

string.Equals(catlang.EditionStatusID, idForStatusNew) select

catlang.GroupID).Distinct();

filterCatGroupIDs = commonCatLangGroupIDs;

}

}

else

{

if (selectAllLangs)

{

filterCatGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.EditionStatusID, idForStatusNew) select

catlang.GroupID).Distinct();

commonCatLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.CategoryID, myCat.ID) &&

string.Equals(catlang.EditionStatusID, idForStatusNew) select

catlang.GroupID).Distinct();

filterLangGroupIDs = commonCatLangGroupIDs;

}

else

{

filterCatGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.LangID, myLang.ID) &&

string.Equals(catlang.EditionStatusID, idForStatusNew) select

catlang.GroupID).Distinct();

filterLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.CategoryID, myCat.ID) &&

string.Equals(catlang.EditionStatusID, idForStatusNew) select

catlang.GroupID).Distinct();

Page 14: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

10

commonCatLangGroupIDs = (from catlang in allCatLangGroupIDs where

string.Equals(catlang.CategoryID, myCat.ID) &&

string.Equals(catlang.LangID, myLang.ID) &&

string.Equals(catlang.EditionStatusID, idForStatusNew) select

catlang.GroupID).Distinct();

}

}

}

}

}

The code above was through the use of extract method turned into these two separate methods in

the new TPI:

public static IEnumerable<string> ShowAllEditions(

this List<DTOIDsForCategoryLangGroupAndStatus> allIds,

DTOSearchArguments searchArguments,

bool selectAllLangs,

bool allCategories)

{

if (allCategories)

{

return selectAllLangs ? allIds.Select(catlang => catlang.GroupID).Distinct() :

allIds.Where(catlang => string.Equals(catlang.LangID,

searchArguments.AdvancedLanguage.ID)).Select(catlang =>

catlang.GroupID).Distinct();

}

return selectAllLangs ? allIds.Where(catlang => string.Equals(catlang.CategoryID,

searchArguments.Category.ID)).Select(catlang => catlang.GroupID).Distinct() :

allIds.Where(catlang =>

string.Equals(catlang.CategoryID, searchArguments.Category.ID) &&

string.Equals(catlang.LangID, searchArguments.AdvancedLanguage.ID))

.Select(catlang => catlang.GroupID).Distinct();

}

public static IEnumerable<string> DontShowAllEditions(

this List<DTOIDsForCategoryLangGroupAndStatus> allIds,

DTOSearchArguments searchArguments,

bool selectAllLangs,

bool allCategories)

{

var idForStatusNew = "3";

if (allCategories)

{

return selectAllLangs ? allIds.Where(catlang =>

string.Equals(catlang.EditionStatusID, idForStatusNew)).Select(catlang =>

catlang.GroupID).Distinct() :

allIds.Where(catlang =>

string.Equals(catlang.LangID, searchArguments.AdvancedLanguage.ID) &&

string.Equals(catlang.EditionStatusID, idForStatusNew))

.Select(catlang => catlang.GroupID).Distinct();

}

return selectAllLangs ? allIds.Where(catlang => string.Equals(catlang.CategoryID,

searchArguments.Category.ID) && string.Equals(catlang.EditionStatusID,

idForStatusNew)).Select(catlang => catlang.GroupID).Distinct() :

allIds.Where(catlang =>

string.Equals(catlang.CategoryID, searchArguments.Category.ID) &&

string.Equals(catlang.LangID, searchArguments.AdvancedLanguage.ID) &&

string.Equals(catlang.EditionStatusID, idForStatusNew))

.Select(catlang => catlang.GroupID).Distinct();

}

2.4.2 Extract Class

Extract class is used when one class is doing the work of two or more classes. First decide on how the

responsibilities should be divided between the old class and the new. Move fields and then methods

Page 15: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

11

from the old class to the new one, testing that everything works after each move. Start with methods

that are being called rather than calling methods. (Fowler & Beck, 1999)

Since the new TPI application followed the MVC design pattern and the old TPI had much of its logic

and UI code mixed, extract class was used to separate the logic to the controller and UI code to the

view. Much of the view code, however, was unusable since one cannot simply translate XAML code

to html/css/js, but some of the overall design was kept and helped with designing the new UI. All

http calls were also extracted to its own class.

2.4.3 Replace Parameter with Method

When and object calls a method and then passes the result of the call as a parameter for another

method you can use replace parameter with method to make the receiver call the method instead.

This is done to shorten long parameter lists because they can often be hard to understand. There are

of course limitations to when this replacement can be made, for instance if the calculation relies on a

parameter of the calling method or if the receiver does not have a reference to the sender. (Fowler &

Beck, 1999)

The mechanics of replace parameter with method works as follows. Extract any calculations of the

parameter into a method. Then replace the references to the parameter with references to the new

method. You should compile and test after each replacement. And finally remove the parameter.

(Fowler & Beck, 1999)

2.4.4 Preserve Whole Object

Preserve whole object is related to the issue of long parameter lists. When retrieving several values

from an object and passing them as parameters, you could instead use the whole object. Start by

creating a new parameter from the object, compile and test that it works. Next determine what

parameters are needed from the object. Take one parameter at a time and replace the reference in

the methods by calling an appropriate method on the object instead, now delete the parameter.

Repeat this process for each parameter that can be obtained from the object. And the final step is to

remove the code in the calling method that receives the deleted parameters. (Fowler & Beck, 1999)

In the case where you do not have an object you may have to use introduce parameter object

described below.

2.4.5 Introduce Parameter Object

Certain parameters tend to be passed around together because they naturally go together. In such

cases it can be useful to replace the parameters with an object containing all of the data. Again, this

Page 16: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

12

helps with long parameter lists, and defining accessors on the object makes the code more

consistent. (Fowler & Beck, 1999)

According to Fowler there is an added and more important benefit, because you clump parameters

together it becomes easier to see behavior that can be moved to its own class. This is however not

something that has been done to any major extent in the development of the new application since

most data handled has been bundled into DTOs (data transfer object).

2.5 Quality of the code There is internal quality and there is external quality. External quality deals with usefulness of a

system as perceived from the outside such as robustness and performance. One of the most

influential factors of software quality lays in its design (Stroggylos & Spinellis, 2007). While both of

these are important, the main focus of this paper is on the internal quality of the system.

As such, to measure the internal quality of the system a set of code metrics were used. These metrics

measure the quality of the code in terms of complexity, understandability and maintainability (Mens

& Tourwé, 2004). This results in a quantifiable way of judging the code quality of the system, before

and after the refactoring process.

Many of these methods could perhaps be refactored further however, because of time constraints

paired with the fact that refactoring of this code has been hard and so taken a lot of time, these are

the refactorings that have been done.

2.6 Data analysis

To analyze the data and compare whether the refactoring have made a significant difference to the

quality of the code, code metrics have been used. There are several popular suites used to calculate

code metrics such as, Order of Growth, Halstead’ Complexity Measure, McCabe’s Cyclomatic

Complexity and Maintainability Index (Stroggylos & Spinellis, 2007). The code metrics used to assess

the project before and after refactoring were Maintainability index, Cyclomatic Complexity, Depth of

inheritance, Class Coupling and Lines of Code.

2.6.1 Maintainability Index

Maintainability index is a metric made up out of several other source code metrics and is used to

indicate maintainability, the metrics used are: cyclomatic complexity, lines of code and Halstead

volume (Welker, 2001). A high score signifies that the code is relatively easy to maintain. An index

value between 20 and 100 indicates that the code is relatively easy to maintain. Between 10 and 19

means the code is moderately maintainable. Below 10 indicates that the code is hard to maintain.

(“Code Metrics Values,” 2007)

Page 17: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

13

2.6.2 Cyclomatic Complexity

McCabe’s cyclomatic complexity or simply cyclomatic complexity was developed by TJ McCabe in the

1970s. The cyclomatic complexity metric is created by calculating the number of different code paths

in the program. This is not the same as the physical size; instead the complexity depends on the

decision structure of the program (McCabe, 1976). This is evident in the fact that adding or

subtracting functional statements will not necessarily have a big impact on complexity but obviously

the size will change (McCabe, 1976).

A general rule is to try and keep the cyclomatic complexity score below 10. The score of cyclomatic

complexity is roughly the number of tests needed to achieve complete code coverage of that

module. (McCabe, 1996)

2.6.3 Depth of inheritance

Depth of inheritance is the height of the class in the inheritance tree (Chidamber & Kemerer, 1991).

That is, the number of class definitions extended to the root of the class hierarchy. Deeper

hierarchies might mean it is harder to understand where methods are defined. As a general rule the

depth of inheritance score is good between 1-2, 3-4 base types are ok and everything above 4 is bad.

2.6.4 Class Coupling

Class coupling means that two classes are coupled through either method calls, variables, base

classes or parameters (Harrison, Counsell, & Nithi, 1998). A general rule when designing software is

low coupling and high cohesion. High coupling means that the code will be difficult to reuse and

maintain because of the many dependencies. The general rule concerning class coupling for

members is that between 0 and 9 are good, 10 to 30 dependencies is ok but anything above that

should be refactored. For types the threshold score is increased to 80.

2.6.5 Lines of Code

Lines of code measures the approximate number of lines of code, a high number might indicate that

a method is trying to do too much. The count is based on intermediate language (IL) code and so

commented or unused code in C# is not counted. (“Code Metrics Values,” 2007) Measuring actual

lines of code would not make for a fair comparison since different programmers use different

amount of line breaks etc., and line breaks for example do not add to any kind of complexity. This

also means that the effect of “syntactic sugar” on the lines of code metric can be disregarded.

Syntactic sugar, simply put, is syntax that allows code to be expressed a more clear or concise way.

Throughout this paper, when discussing the lines of code metric it is the IL lines of code that is

referred to unless otherwise specified.

Page 18: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

14

Since the original TPI application used Silverlight the main logic of the code is located in a XAML.cs

file. Silverlight applications have a XAML file that contain markup for the UI and XAML.cs file that

contains the business logic. The XAML.cs file also contains code to modify the XAML UI markup. The

new application is designed following the MVC design pattern and so this logic is separated. The goal

of this paper is not to determine which of XAML or html/css/js measures better code quality through

metrics. Therefore only methods containing logic and or service calls are evaluated. Take for example

the “dg4_loadingRow” method of the original TPI seen in figure 2. Even though it has a relatively low

maintainability Index, high cyclomatic complexity, high class coupling and relatively high number of

lines of code it is excluded because it mainly deals with drawing UI elements for search results.

Fig 2. dg4_LoadingRow method metrics table

The original applications XAML file contains 267 methods. Not all of them have a counterpart in the

refactored application and they are therefore excluded from the analysis. All of the metrics results

can be viewed in appendices A and B.

There is a built in metric tool in visual studio which was used to get the metrics described. It ignores

code generated by tools and compilers and as such enables the metrics values to reflect code made

or changed by the developer (“Code Metrics Values,” 2007).

3. Results

The results section contains the metrics before and after refactoring. The presented results are after

all of the different refactoring methods have been used. Depth of inheritance is included in the

project comparison but excluded from the methods comparisons since it measures the number of

classes within the inheritance chain and as such does not apply to methods. The lines of code metric

is presented but no examples have been chosen based on only lines of code since this metric does

not necessarily, on its own, say much about the code quality.

A complete list of the metrics before refactoring can be viewed in appendix A. A complete list of the

metrics after refactoring can be viewed in appendix B.

Member Maintainability Index Cyclomatic Complexity Depth of Inheritance Class Coupling Lines of Code

dg4_LoadingRow

(object,

DataGridRowEve

ntArgs) : void

19 22 37 206

Page 19: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

15

3.1 Project Metrics As can be seen in figures 3 and 4 the refactored application contains two projects with the same logic

as the single project in the original application. The original application contains presentation logic

whereas this has been moved to another project, and is not being measured, in the new application.

The maintainability index has not changed much despite the fact that the original code has much

higher cyclomatic complexity and several more lines of code. The depth of inheritance as well as the

class coupling score has been brought down to an acceptable level and the lines of code have been

reduced significantly, although as explained earlier this is somewhat misleading since much of the

code has been moved to a separate project.

Fig. 3 Original TPI application project metrics

The main logic for the application was split up into 36 smaller methods in two classes. Of the 36

methods 28 had metrics that all qualified as ok or good and eight had one or more metrics that

failed. Out of the eight that failed, four only failed on the cyclomatic complexity metric. Three of the

methods failed cyclomatic complexity and the lines of code metrics while only one failed all three of

those metrics. None failed the class coupling metric although the average number of class couplings

actually went up from 7 to 8.

Fig. 4 Refactored TPI application project metrics

3.2 Method Metrics

The examples have been chosen because they either have too low maintainability index, because

they have too high cyclomatic complexity or too high class coupling. The first table presented is from

the original TPI application followed by a table of one or more methods from the refactored

application that corresponds to the original applications method.

3.2.1 UpdateAllCombos

UpdateAllCombos has an abysmal maintainability index score of 0 and a very high cyclomatic

complexity score of 152. Despite its bad score in the first two metrics the class coupling is within the

acceptable range at 25. At 298 lines the UpdateAllCombos method is a very large method.

Original TPI application

Scope Type Member Maintainability Index Cyclomatic Complexity Depth of Inheritance Class Coupling Lines of Code

Type Shell 55 1415 6 185 3576

Refactored TPI application

Scope Type Member Maintainability Index Cyclomatic Complexity Depth of Inheritance Class Coupling Lines of Code

Type HomeController 53 285 3 55 535

Type ExtensionMethod 49 42 1 13 60

Page 20: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

16

Fig. 5 UpdateAllCombos method metrics table

Extract method has been used extensively throughout the refactoring process, for example in the

UpdateAllCombos method. The methods UpdateAllCombos, seen in figure 5, has been split up into

several smaller methods, their metrics are displayed in figure 6. In all methods the Maintainability

Index has been raised. Only the GetGroupIDsForSearch method still has a maintainability index below

the acceptable 20 point score. It also has the highest cyclomatic complexity score out of all methods

measured in the new TPI application. There are still several methods that are outside the range of

acceptable levels of cyclomatic complexity. Eight out of the 13 methods still have a cyclomatic

complexity above 10. All methods have a class coupling score well within the acceptable range but

only four of the methods have a score that is considered good. Separately each methods lines of

code metric have been reduced significantly. However together they exceed the original applications

method by 77 lines, with 367 combined lines of code to the original 298 lines of code.

Fig. 6 Collection of methods extracted from UpdateAllCombos metrics table

3.2.2 ResetOldValuesWhenSalesCodeChanged_New

The ResetOldValuesWhenSalesCodeChanged_New method is called from within the huge method

UpdateAllCombos and the only reference to this method is in the UpdateAllCombos, which explains

the overlap between the refactored methods. The method ResetOldValuesWhen-

SalesCodeChange_new was refactored into three separate methods. The original maintainability

Original TPI Application

Member Maintainability Index Cyclomatic Complexity Class Coupling Lines of Code

UpdateAllCombos(string) : void 0 152 25 298

Refactored TPI Application

Type Member Maintainability Index Cyclomatic Complexity Class Coupling Lines of Code

HomeControllerGetGroupIDsforSearch(DTOSearchArguments) :

IEnumerable<string>19 74 14 120

HomeControllerUpdateCharacteristics(DTOSearchArguments,

DTOCharacteristic) : JsonResult32 32 19 64

ExtensionMethod

ShowAllEditions(this

List<DTOIDsForCategoryLangGroupAndStatus>,

DTOSearchArguments, bool, bool) :

IEnumerable<string>

43 21 10 32

ExtensionMethod

DontShowAllEditions(this

List<DTOIDsForCategoryLangGroupAndStatus>,

DTOSearchArguments, bool, bool) :

IEnumerable<string>

45 20 10 26

HomeControllerGetCategories(DTOSearchArguments) :

JsonResult48 20 12 20

HomeControllerGetLanguages(DTOSearchArguments) :

JsonResult48 20 12 20

HomeControllerGetVersionCodesX(DTOSearchArguments) :

JsonResult51 12 11 20

HomeControllerGetObsoleteProductSeries(DTOSearchArgumen

ts) : JsonResult52 12 10 16

HomeControllerGetObsoleteSalesCodesX(DTOSearchArguments

) : JsonResult56 10 9 12

HomeController GetSegments(DTOBrand) : JsonResult 58 5 11 13

HomeControllerGetProductSeries(DTOSearchArguments) :

JsonResult61 4 8 11

HomeControllerGetSalesCodesX(DTOSearchArguments) :

JsonResult61 4 8 11

HomeController

buildIntersectGroups(IEnumerable<string>,

IEnumerable<string>, IEnumerable<string>,

IEnumerable<string>, IEnumerable<string>,

bool, bool, bool, bool) : IEnumerable<string>

62 5 2 10

Page 21: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

17

index score of 17 was raised to 48, 48 and 32 respectively in the refactored methods. The initial

cyclomatic complexity score of 88 was lowered, although not enough to be considered good, to 20,

20 and 32 when refactored. The three refactored methods, GetCategory, GetLanguage and especially

UpdateCharacteristics method need further refactoring to achieve acceptable scores in the code

metrics.

At 17 its maintainability index is below what is considered acceptable. It has a very high cyclomatic

complexity score at 88, but an ok class coupling score at 13. The largest method UpdateAllCombos is

calling the 4th largest method ResetOldValuesWhenSalesCodeChanged_New (3rd largest if not

counting presentation logic); the method has 131 lines of code which is above the recommended 20.

Fig. 7 ResetOldValuesWhenSalesCodeChanged_New method metrics table

The refactored methods still have a quite low maintainability index but they are well within the range

of what is considered acceptable. Both the original method and the refactored ones have an

acceptable number of class couplings. Cyclomatic complexity is till high even after refactoring and

with 20 lines of code cyclomatic complexity scores of 20 and 32 is quite high.

Fig. 8 Collection of methods extracted from ResetOldValuesWhenSalesCodeChanged_New metrics table

3.3.3 SetUpDynamicCharacteristics

SetUpDynamicCharacteristics is run initially to set up the correct characteristics combo boxes with

regards to the users’ personal settings. The SetUpDynamicCharacteristic was broken down into four

new methods, GetAllCategories, GetAllLanguages, GetUserSettings and once again

UpdateCharacteristics. The first three methods mentioned are all simple and maintainable, all of

them have a maintainability index of 64 and their Cyclomatic complexity is low at 3, 3 and 2. And

they are short with 9, 9 and 8 IL lines of code.

It has a decent maintainability index, the cyclomatic complexity is a bit high but nothing

catastrophic. Double the recommended number of lines of codes can be explained with the fact that

it deals with some presentation. Its class couplings are within an acceptable range but close to the

Original TPI Application

Type Member Maintainability Index Cyclomatic Complexity Class Coupling Lines of Code

Shell

ResetOldValuesWhenSalesCodeChanged_new

(string, ref DTOCategory, ref DTOLanguage, ref

DTOCharacteristic, ref DTOCharacteristic, ref

DTOCharacteristic, ref DTOCharacteristic) : void

17 88 13 131

Refactored TPI Application

Type Member Maintainability Index Cyclomatic Complexity Class Coupling Lines of Code

HomeController GetCategories(DTOSearchArguments) : JsonResult 48 20 12 20

HomeController GetLanguages(DTOSearchArguments) : JsonResult 48 20 12 20

HomeControllerUpdateCharacteristics(DTOSearchArguments,

DTOCharacteristic) : JsonResult32 32 19 64

Page 22: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

18

upper bound. This is because to setup the user settings it needs access to a lot of different

information.

Fig. 9 SetUpDynamicCharacteristics method metrics table

GetAllCategories, GetAllLanguages and GetUserSettings are all well within what is considered good in

all respects. The UpdateCharacteristics method used to retrieve and update characteristics however

fails in almost all respects except class coupling.

Fig. 10 Collection of methods after refactoring of SetUpDynamicCharacteristics metrics table

4. Discussion

The results of this study suggest that refactoring has a beneficial effect on the code quality metrics

maintainability index, cyclomatic complexty, class coupling and lines of code.

Looking at the results almost all of the refactored methods have better scores on their metrics. Even

the biggest offender, the UpdateAllCombos method, with a maintainability index of 0 and cyclomatic

complexity of 152 was broken down to where all but one of the refactored methods had a

maintainability index below 19 which is what is considered ok. Although only five of the methods hit

the mark of a score below 10 on cyclomatic complexity, further refactoring would probably have

meant an even lower cyclomatic complexity score among the refactored methods. Overall the lines

of code metric was reduced. The smallest method got a score of 10 while the largest 120, which is

still smaller than the original method.

The fact that UpdateCharacteristics is present in several of the refactored method comparisons is an

indicator that it is doing too much. This is reinforced by the methods relatively bad metrics scores.

UpdateCharacteristics and GetGroupIDsForSearch are the two refactored methods that require the

greatest amount of additional work to pass the metrics evaluation.

Despite some of the refactored methods’ poor scores, the overall results point toward the fact that

you do not have to be a great programmer to write simple, understandable and high quality code.

Following a few relatively simple guidelines, breaking down large unmanageable chunks of code into

Original TPI Application

Type Member Maintainability Index Cyclomatic Complexity Class Coupling Lines of Code

Shell SetUpDynamicCharacteristics() : void 40 22 28 40

Refactored TPI Application

Type Member Maintainability Index Cyclomatic Complexity Class Coupling Lines of Code

HomeControllerUpdateCharacteristics(DTOSearchArguments,

DTOCharacteristic) : JsonResult32 32 19 64

HomeController GetAllCategories() : JsonResult 64 3 8 9

HomeController GetAllLanguages() : JsonResult 64 3 8 9

HomeController GetUserSettings() : JsonResult 64 2 9 8

Page 23: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

19

smaller more easily understood modules is relatively easy. This is not saying it does not take time or

effort, but it can be done.

Of course the metrics, maintainability index, cyclomatic complexity, depth of inheritance, class

coupling and lines of code, used in this paper to describe code quality are not the quintessential or

only way of measuring code quality. There are other metrics available, which can be used to measure

code quality, for example the MOOD metrics that are designed to measure the overall quality of an

object-oriented design. When refactoring you are in a way changing the design of the code, and it is

entirely possible that measuring code quality using other metrics, such as the MOOD metrics, is a

better way of determining code quality. However, the metrics used in this project have been around

for some time and often been used to measure code quality.

The process of removing Silverlight and implementing html/css/js instead should not require very

much time or effort. But making changes such as this, with nothing but speed in mind, will over time

deteriorate the code quality. Prioritizing code quality and maintainability will slow down the

development process but at the same time it will ensure that future changes are easier to implement

since the code quality will be higher.

This project dealt with refactoring code already written, but it is possible to apply these techniques

while writing new code as well. It does not matter if you are refactoring to maintain someone else’s

code or refactoring while producing new code. These techniques will help you and other

programmers in the future understand and maintain the code you write.

These findings are contrary to what Stroggylos and Spinellis (2007) found in their survey of

refactoring in open source software, where they concluded that the increase in quality achieved

through refactoring was not reflected in various metrics. There are probably many reasons for this,

one of them being the fact that they did not use the same metrics. There is also the fact that they

surveyed several different projects while this paper only deals with the one project. They somewhat

eliminated the factor of coder skill since their projects were open source and so many different

people could contribute, for better or worse. While this project solely relies on the authors’ skill as a

programmer, which admittedly is not world class. Different programmers will have different result

but, looking at the results of this study, systematically applying these proven refactoring techniques

will improve code quality metrics.

Because of the way the original application is built, comparing project metrics is hard. As discussed

earlier, much of the presentation logic is present within the shell project. This is not the case in the

refactored application since the presentation logic has been separated into its own view class. This

Page 24: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

20

bloats the Lines of Code metric and, by the looks of it, the Cyclomatic Complexity metrics as well.

Since the metrics lines of code and cyclomatic complexity are part of calculating the maintainability

index this is also affected. This is kind of the point of refactoring but many of these issues are better

handled by redesign rather than refactoring.

4.1 Limitations How much the redesign versus the refactoring has impacted the study has not been evaluated.

Efforts were made to avoid interpreting benefits of redesign as benefits of refactoring, by not

measuring obvious design changes and not over interpret singular metrics like lines of code. However

it cannot be disregarded as a flaw in the design and execution of this study.

In “A Survey of Software Refactoring” (2004), Mens and Tourwé suggested intermittently measuring

code metrics between smaller refactorings. This might have helped alleviate the issue with design

contra refactoring improvements in metrics.

One issue with this study is the fact that all coding has been done by a person of intermediate skill at

best. The code could have been peer reviewed but due to the fact that the coding part of the project

was completed at such a late stage meant there was no time.

The fact that no automated tests were written and instead all testing was done manually was a

mistake. Although there are no numbers to back this up, writing automated tests would probably

have saved time, since many hours were spent manually testing the system. Not only would

automated tests have sped up the testing process and the overall project. Automated tests would

also have guaranteed that behavior was preserved after refactorings had occurred in a more

consistent manner than manual testing.

4.2 Further research For future research it would be interesting to not only use code metrics as a measure of code quality.

While code metrics generate quantifiable metrics, using peer and code review to measure

understandability and maintainability from a qualitative perspective and contrasting those results to

code metrics could be interesting. This is because having code metrics describe a piece of code as

more understandable does not mean much, unless programmers agree and actually have an easier

time understanding the code.

Furthermore measuring code quality compared to the process, that is the effort and cost involved to

refactor, could provide a sort of a “tipping point” as to when it actually is beneficial to refactor and

when it simply is not worth the investment in terms of time, cost and effort.

Page 25: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

21

5. Conclusion

This paper sought to document the process of refactoring, to improve understandability of, a legacy

application at Xylem, and to understand what impact these refactorings have on the quality of the

code. Legacy code will always need to be maintained and sometimes modified. The problem lies in

trying to make sure that the maintenance does not reduce the quality of the code and

understandability of the code is maintained or improved. This is possible by using refactoring when

maintaining or otherwise modifying the software. By using metrics it is possible to measure the

quality of software. This study examines how the metrics of an application at Xylem were impacted

when the application was refactored in conjunction with a change of its front end code.

The result point toward an improvement in the metrics maintainability index, cyclomatic complexity,

class coupling and lines of code. This indicates that it is easier to maintain and improve code after

they have been refactored. I was able to improve the quality of the code but not because I am a

better programmer than anyone who previously worked on the application. However, by utilizing

techniques developed by people who are great programmers I was able to achieve small but overall

significant improvements. To quote Ken Beck:

“I’m not a great programmer; I’m just a good programmer with great habits.”

Page 26: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

22

6. References

Bois, B. D., Demeyer, S., & Verelst, J. (2004). Refactoring - improving coupling and cohesion of

existing code. In 11th Working Conference on Reverse Engineering (pp. 144–151).

https://doi.org/10.1109/WCRE.2004.33

Boschman, S. R. (2006). Performing transformations on. NET intermediate language code

(Master's thesis, University of Twente).

Chidamber, S. R., & Kemerer, C. F. (1991). Towards a metrics suite for object oriented design (Vol. 26, No.

11, pp. 197-211). ACM.

Code Metrics Values. (2007, November 22). Retrieved May 22, 2017, from

https://msdn.microsoft.com/en-us/library/bb385914.aspx

Fowler, M., & Beck, K. (1999). Refactoring: improving the design of existing code. Reading, MA: Addison-

Wesley.

Harrison, R., Counsell, S., & Nithi, R. (1998, November). Coupling metrics for object-oriented design. In

Software Metrics Symposium, 1998. Metrics 1998. Proceedings. Fifth International (pp. 150-157).

IEEE.

McCabe, A. H. W. T. J. (1996). NIST Special Publication 500-235 Structured Testing: A Testing Methodology

Using the Cyclomatic Complexity Metric.

McCabe, T. J. (1976). A complexity measure. IEEE Transactions on software Engineering, (4), 308-320.

Page 27: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

23

Mens, T., & Tourwé, T. (2004). A survey of software refactoring. IEEE Transactions on software

engineering, 30(2), 126-139.

Oates, B. J. (2006). Researching information systems and computing. London ; Thousand Oaks, Calif: SAGE

Publications.

Peffers, K., Tuunanen, T., Rothenberger, M. A., & Chatterjee, S. (2007). A Design Science Research

Methodology for Information Systems Research. Journal of Management Information Systems, 24(3),

45–77. https://doi.org/10.2753/MIS0742-1222240302

Saying Goodbye to Our Old Friend NPAPI. (2013, September 23). Retrieved May 22, 2017, from

https://blog.chromium.org/2013/09/saying-goodbye-to-our-old-friend-npapi.html

Stroggylos, K., & Spinellis, D. (2007). Refactoring–Does It Improve Software Quality? In Proceedings of the

5th International Workshop on Software Quality (p. 10–). Washington, DC, USA: IEEE Computer

Society. https://doi.org/10.1109/WOSQ.2007.11

Welker, K. D. (2001). The software maintainability index revisited. CrossTalk, 14, 18-21.

Xylem - Let’s Solve Water - United States. (2015, February 24). Retrieved May 30, 2017, from

https://www.xylem.com/en-US/

Xylem Water Solutions. (2016) annual report of Xylem Water Solutions. Retrieved from

http://investors.xyleminc.com/phoenix.zhtml?c=247373&p=irol-reportsannual

Page 28: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

24

7. Appendices

Appendix A Complete set of metrics data from the original TPI application before refactoring.

Scope Project Namespace Type Member Maintainability Index

Cyclomatic Complexity

Depth of Inheritance

Class Coupling

Lines of

Code

Type Client\ITT.TPI

(Debug)

ITT.TPI Shell 55 1415 6 185 3576

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell activateTabFromUserSettings(string) : void

52 7 6 20

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ApplicationManager.get() :

IApplicationManager

75 2 3 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell areAllInitialLoadingsDone() : bool

73 12 0 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell AutoComplete1_DropDownClosed(object,

RoutedPropertyChangedEventArgs<bool>) :

void

55 6 8 18

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell AutoComplete1_GotFocus(object,

RoutedEventArgs) : void

53 4 17 18

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell AutoComplete1_LostFocus(object,

RoutedEventArgs) : void

62 5 8 10

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell AutoComplete1_SelectionChanged(object,

SelectionChangedEventArgs) : void

57 4 9 15

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell AutoComplete2_DropDownClosed(object,

RoutedPropertyChangedEventArgs<bool>) :

void

79 1 1 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell AutoComplete2_GotFocus(object,

RoutedEventArgs) : void

95 1 4 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell AutoComplete2_LostFocus(object,

RoutedEventArgs) : void

53 7 10 19

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell AutoComplete2_SelectionChanged(object,

SelectionChangedEventArgs) : void

83 1 6 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell BorderBrandSearch_MouseLeftButtonDown(o

bject, MouseButtonEventArg

s) : void

80 2 2 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell BorderPubNrSearch_MouseLeftButtonDown(o

bject, MouseButtonEventArg

s) : void

63 2 9 10

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell BorderSalesCodeSearch_MouseLeftButtonDo

wn(object,

80 2 2 3

Page 29: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

25

MouseButtonEventArgs) : void

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Brand.get() : DTOBrand 84 1 3 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Brand.set(DTOBrand) : void

92 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell BrandCombo1_DropDownClosed(object, EventArgs) : void

100 1 1 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell BrandCombo1_GotFocus(object,

RoutedEventArgs) : void

100 1 1 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell BrandCombo1_SelectionChanged(object,

SelectionChangedEventArgs) : void

45 7 20 34

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell buildIntersectGroups(IEnumerable<string>, IEnumerable<string>, IEnumerable<string>, IEnumerable<string>, IEnumerable<string>,

bool, bool, bool, bool) : IEnumerable<string>

63 5 2 10

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CBRPSalesCode_Loaded(object,

RoutedEventArgs) : void

100 1 1 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CBRPSalesCode_SelectionChanged(object,

SelectionChangedEventArgs) : void

67 3 7 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CBxPhasedOut_Checked(object,

RoutedEventArgs) : void

61 2 6 13

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CBxPhasedOut_Unchecked(object,

RoutedEventArgs) : void

60 2 6 14

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CBxRPShow_Checked(object,

RoutedEventArgs) : void

59 6 10 12

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CBxRPShow_Unchecked(object,

RoutedEventArgs) : void

79 1 4 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Characteristics.get() : ObservableCollection<DTOCharacteristicGrou

p>

84 1 4 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Characteristics.set(ObservableCollection<DTOCharacteristicGroup>) :

void

92 1 4 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CheckAdvancedSelected() : bool

69 3 2 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CheckAllDropDownsClosed() : void

100 1 0 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell checkIfBrandShouldDisplayDenominationForP

roduct() : bool

63 4 3 8

Page 30: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

26

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell clearSearchResult() : void

84 1 3 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell complete_dg4_RowVisibilityChanged(ref

StackPanel, ref Border, ref DataGrid,

DataGridRowDetailsEventArgs) : void

66 1 11 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CopySearchArguments(DTOSearchArguments) : DTOSearchArguments

52 2 1 21

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell createCategory(DTOIDsForCategoryLangGroup

AndStatus, ref List<DTOCategory>) :

void

63 8 6 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CreateCharacteristic(DTOGroupContent, ref

List<DTOCharacteristic>, ref

List<DTOCharacteristic>, ref

List<DTOCharacteristic>, ref

List<DTOCharacteristic>) : void

52 13 7 16

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CreateDynamicCombos(List<string>) : void

53 6 21 17

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CreateEndPointName(string, string) : string

69 2 0 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CreateFeedsLink() : string

45 9 14 30

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CreateFreq(DTOGroupContent, ref

List<DTOCharacteristic>) : void

70 4 7 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CreateHydType(DTOGroupContent, ref

List<DTOCharacteristic>) : void

70 4 7 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell createHyperlinkButton(Uri, bool) :

HyperlinkButton

67 2 6 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell createHyperlinkButton(Uri, TextBlock, bool) :

HyperlinkButton

65 2 8 8

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CreateInstallation(DTOGroupContent, ref

List<DTOCharacteristic>) : void

70 4 7 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell createLanguage(DTOIDsForCategoryLangGrou

pAndStatus, ref List<DTOLanguage>) :

void

58 8 6 10

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CreateListsForCombos(IEnumerable<string>, IEnumerable<string>, IEnumerable<string>, IEnumerable<string>, IEnumerable<string>, IEnumerable<string>,

ref List<DTOCategory>, ref

List<DTOLanguage>, ref

28 73 17 52

Page 31: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

27

List<DTOCharacteristic>, ref

List<DTOCharacteristic>, ref

List<DTOCharacteristic>, ref

List<DTOCharacteristic>) : void

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell CreatePressure(DTOGroupContent, ref

List<DTOCharacteristic>) : void

70 4 7 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Debug_printGroupIDContents(DTOIDs, DTOIDs) : void

71 3 5 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell dg4_CurrentCellChanged(object, EventArgs) :

void

100 1 1 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell dg4_LayoutUpdated(object, EventArgs) : void

63 6 12 8

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell dg4_LoadingRow(object,

DataGridRowEventArgs) : void

19 22 37 206

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell dg4_MouseLeftButtonUp(object,

MouseButtonEventArgs) : void

100 1 1 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell dg4_RowDetailsVisibilityChanged(object,

DataGridRowDetailsEventArgs) : void

56 3 15 14

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell dg4_SelectionChanged(object,

SelectionChangedEventArgs) : void

68 3 3 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Document.get() : DTODocument

91 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Document.set(DTODocument) : void

92 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Documents.get() : ObservableCollection<

DTODocument>

84 1 4 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Documents.set(ObservableCollection<DTODo

cument>) : void

92 1 4 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell DynamicCombo_SelectionChanged(object,

SelectionChangedEventArgs) : void

44 13 15 31

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell enableAdvTabControls() : void

75 1 4 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ExpandInfo_Click(object, RoutedEventArgs) :

void

56 3 9 15

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell extractTabsFromMainTab() : List<TabItem>

63 4 10 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell FoundPreviousCategorySelection(string,

string) : bool

51 10 9 19

Member Client\ITT.TPI

ITT.TPI Shell GetAllCategoriesAndDocLangs() : void

73 2 2 5

Page 32: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

28

(Debug)

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetAllCategoryCharacteristics() : void

72 2 4 5

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetAllGroups() : void 76 2 2 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetAllItemCharacteristics() : void

72 2 4 5

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetAllLanguages() : void

76 2 2 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetAllowableCharacteristics(string, bool) :

List<string>

50 12 15 20

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetAllRSSDocs() : void 100 1 0 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetAllSalesCodes() : void

75 2 2 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetAllSalesCodesX() : void

75 2 2 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetAllVersionCodes() : void

72 2 4 5

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetBrands() : void 76 2 2 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetBrandsShowingDenomination() : void

80 2 2 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetCharacteristicID(string) : string

62 5 8 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetCharacteristics() : void

80 2 2 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetCharacteristicsFromListSlim(DTOGroupCon

tent, string) : DTOCharacteristic

55 4 8 16

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetComplexCharacteristics(List<DTOVersionCo

de>, string) : void

70 2 5 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetComplexDocuments(DTOSearchArgument

s) : void

58 3 13 14

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetGroupIDs(DTOCharacteristic) : void

68 3 3 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetIDsCategoriesLangsGroupIDsStatus() : void

71 3 2 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetProductSeries() : void

69 2 8 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetRelatedProducts(ObservableCollection<DTOVersionCode>) : void

79 2 4 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetRSSHelpFile() : void 95 1 1 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetSalesCodesForBrandSearch() : void

67 5 11 6

Member Client\ITT ITT.TPI Shell GetSegments() : void 76 2 2 4

Page 33: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

29

.TPI (Debug)

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetTabItem(string) : TabItem

61 4 5 11

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetUserSettings() : void

63 2 4 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetVersionCodes() : void

64 4 9 8

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GetVersionCodesForBrandSearch() : void

63 6 7 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GroupIDs.get() : DTOIDs

91 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell GroupIDs.set(DTOIDs) : void

92 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell HelpButton_Click(object, RoutedEventArgs) :

void

71 2 4 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell InfraProxy.get() : InfraStructureServiceCl

ient

60 3 8 11

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell InfraProxy_JustTestCompleted(object,

JustTestCompletedEventArgs) : void

95 1 2 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell initComboLists(ref List<DTOCategory>, ref

List<DTOLanguage>, ref

List<DTOCharacteristic>, ref

List<DTOCharacteristic>, ref

List<DTOCharacteristic>, ref

List<DTOCharacteristic>) : void

44 1 9 38

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell InitializeComponent() : void

26 2 26 150

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell isAdvancedSearch() : bool

61 7 13 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell IsPrenComboItemSelected(ComboBox) : bool

80 2 2 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell isTPIDocument(string, string) : bool

63 4 2 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell LogException(Exception, string) : void

55 2 4 16

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell LogExceptionWithNoMessageBox(Exception,

string) : void

57 2 3 15

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Minimizer3_MouseLeftButtonDown(object,

MouseButtonEventArgs) : void

76 2 3 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell NewSearchButton_Click(object,

RoutedEventArgs) : void

100 1 1 1

Member Client\ITT.TPI

ITT.TPI Shell OnGoingSearch.get() : bool

98 1 0 1

Page 34: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

30

(Debug)

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell OnGoingSearch.set(bool) : void

95 1 0 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell OnPropertyChanged(string) : void

75 3 3 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Page_Loaded(object, RoutedEventArgs) :

void

58 4 12 12

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell PageSetup() : void 35 10 24 77

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell PopulateCombos(string, List<DTOCategory>, List<DTOLanguage>,

List<DTOCharacteristic>,

List<DTOCharacteristic>,

List<DTOCharacteristic>,

List<DTOCharacteristic>) : void

31 25 30 72

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell populateUserPrenBrandCombo() : void

72 3 7 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell populateUserPrenDocCategoryCombo() : void

75 3 6 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell populateUserPrenFreqCombo() : void

51 8 17 20

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell populateUserPrenLangCombo() : void

75 3 8 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell populateUserPrenSalesCombo() : void

70 6 7 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell populateUserPrenSegmentCombo() : void

71 4 7 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell populateUserPrenSeriesCombo() : void

70 5 7 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell PrivateProxy.get() : BusinessDataServiceCli

ent

46 3 29 32

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell PrivateProxy_GetComplexCharacteristicsComp

leted(object, GetComplexCharacteristicsCompletedEventArg

s) : void

82 1 3 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ProductSeries.get() : ObservableCollection<

DTOProductSeries>

84 1 4 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ProductSeries.set(ObservableCollection<DTOP

roductSeries>) : void

92 1 4 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ProductSeriesCombo_DropDownClosed(obje

ct, EventArgs) : void

100 1 1 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ProductSeriesCombo_SelectionChanged(objec

t, SelectionChangedEvent

Args) : void

43 9 23 38

Member Client\ITT ITT.TPI Shell ProductSeriesSelect.ge 91 1 3 1

Page 35: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

31

.TPI (Debug)

t() : DTOProductSeries

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ProductSeriesSelect.set(DTOProductSeries) :

void

92 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell PropertyChanged.add(PropertyChangedEvent

Handler) : void

74 2 3 5

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell PropertyChanged.remove(PropertyChangedEv

entHandler) : void

74 2 3 5

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell radioBtnRSS_Checked(object,

RoutedEventArgs) : void

74 1 5 5

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell radioBtnUserSettings_Checked(object,

RoutedEventArgs) : void

50 6 8 28

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell RBDontShowPhasedOutProducts_Checked(object, RoutedEventArgs) :

void

47 10 16 28

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell RBShowPhasedOutProducts_Checked(object,

RoutedEventArgs) : void

47 10 16 30

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell RemoveDuplicatesFromCBXItems(ref

List<DTOCategory>, ref List<DTOLanguage>,

ref List<DTOCharacteristic

>, ref List<DTOCharacteristic

>, ref List<DTOCharacteristic

>, ref List<DTOCharacteristic

>) : void

58 1 9 12

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Reset_Clicked() : void 74 3 5 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetAdvancedTabControls() : void

52 10 14 18

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetCharacteristic(string, ref

IEnumerable<string>, ref DTOCharacteristic,

bool) : void

51 11 10 21

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetCharacteristicToDefault(ref

DTOCharacteristic, ref DTOCharacteristic, ref DTOCharacteristic, ref DTOCharacteristic) :

void

66 1 3 8

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetComboSearchSettings() : void

68 1 1 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetDynamicCombos() : void

72 3 10 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetOldCharacteristicValuesWhenSalesCode

Changed(string, ref DTOCharacteristic, ref DTOCharacteristic, ref DTOCharacteristic, ref

37 33 15 41

Page 36: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

32

DTOCharacteristic) : IEnumerable<string>

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetOldValuesWhenSalesCodeChanged_new

(string, ref DTOCategory, ref DTOLanguage, ref

DTOCharacteristic, ref DTOCharacteristic, ref DTOCharacteristic, ref DTOCharacteristic) :

void

17 88 13 131

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetSearch() : void 34 2 27 84

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetSearchArguments() : void

46 15 27 22

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetSearchInfo(bool) : void

79 2 5 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ReSetStoredCategoryOrDocLangItem(ComboB

ox, DTOCategory, DTOLanguage) : void

46 16 10 29

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResetUserPrenSelections() : void

58 1 6 15

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResultPane_SizeChanged(object,

SizeChangedEventArgs) : void

67 3 7 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResultPaneCloseDataGrid_Click(object,

RoutedEventArgs) : void

59 8 11 11

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ResultPaneOpenDataGrid_Click(object,

RoutedEventArgs) : void

62 7 10 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SalesCode.get() : DTOSalesCode

84 1 3 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SalesCode.set(DTOSalesCode) : void

92 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SalesCodeCombo_DropDownClosed(object,

EventArgs) : void

52 5 15 22

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SalesCodeCombo_SelectionChanged(object,

SelectionChangedEventArgs) : void

50 5 19 25

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SalesCodeConverter(ObservableCollection<D

TOSalesCode>) : ObservableCollection<s

tring>

63 4 4 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SalesCodesForBrandSearch.get() :

ObservableCollection<DTOSalesCode>

91 1 4 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SalesCodesForBrandSearch.set(ObservableCollection<DTOSalesCode

>) : void

92 1 4 1

Page 37: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

33

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SalesCodesX.get() : ObservableCollection<

DTOSalesCode>

60 6 11 10

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SalesCodesX.set(ObservableCollection<DTOSa

lesCode>) : void

84 1 4 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Search() : void 36 22 17 58

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SearchArguments.get() : DTOSearchArguments

84 1 3 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SearchArguments.set(DTOSearchArguments) :

void

92 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SearchButton_Click(object, RoutedEventArgs) :

void

69 2 5 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Segment.get() : DTOSegment

84 1 3 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Segment.set(DTOSegment) : void

92 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SegmentCombo_GotFocus(object,

RoutedEventArgs) : void

100 1 1 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SegmentCombo_SelectionChanged(object,

SelectionChangedEventArgs) : void

44 8 24 35

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell selectDefaultStartTab() : void

87 1 2 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell selectDTOObjectByUserSettings(object, string, ItemCollection) : object

73 3 4 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell selectDTOObjectByUserSettingsObj(object,

string, IEnumerable<object>) :

object

73 3 4 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell selectLangByUserSettings(DTOLanguage, ItemCollection) :

DTOLanguage

63 3 3 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SelectProductSeries(bool,

ObservableCollection<DTOSalesCodeX>,

ObservableCollection<DTOProductSeries>) :

ObservableCollection<DTOProductSeries>

47 20 13 21

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell selectSalesCodeFromUserSettings(DTOSalesC

ode, ObservableCollection<

DTOSalesCode>) : DTOSalesCode

65 6 7 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell selectSalesCodeFromUserSettings_(DTOSalesCode, ItemCollection) :

DTOSalesCode

65 6 7 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SelectSalesCodes(SearchType, bool,

ObservableCollection<DTOSalesCodeX>) :

ObservableCollection<

36 31 14 48

Page 38: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

34

DTOSalesCode>

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SelectSegments(ObservableCollection<DTOSeg

ment>) : ObservableCollection<

DTOSegment>

65 4 9 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell selectUserSettingsValuesForFreqCombo() :

void

48 13 19 21

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell selectUseSettingsForLangAndCategory() : void

65 2 8 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SelectVersionCodes() : ObservableCollection<

DTOVersionCode>

43 12 15 36

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetGroupIDsForSearchArguments(IEnumerabl

e<string>) : void

66 5 7 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetSearchArguments() : void

74 1 3 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetStoredCharacteristicItem(ComboBox,

DTOCharacteristic) : bool

56 6 7 15

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetTabCtrlMainAvailability() : void

79 2 3 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetUpBrandSearch() : void

57 2 14 14

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetUpDateSearch() : void

58 1 9 14

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetUpDynamicCharacteristics() : void

40 22 28 40

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetUpPubNoSearch() : void

61 1 7 12

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetUpSalesCodeSearch() : void

47 6 21 30

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell SetUpUserSettings() : void

44 5 24 37

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell setUriToShowDocument(string, string, string,

string) : string

61 2 2 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Shell() 46 1 8 35

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Shell(IUnityContainer) 43 2 15 43

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ShowHideAdvSearchButton_Click(object,

RoutedEventArgs) : void

71 3 4 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ShowHideSearchButton_Click(object,

RoutedEventArgs) : void

71 3 4 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ShowPhasedOutProducts.get() : bool

91 1 2 1

Page 39: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

35

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ShowPhasedOutProducts.set(bool) : void

92 1 2 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ShowRelatedProducts.get() : bool

91 1 2 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ShowRelatedProducts.set(bool) : void

92 1 2 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell sortCategories(List<DTOCategory>) :

List<DTOCategory>

55 5 11 16

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell sortLangs(List<DTOLanguage>) :

List<DTOLanguage>

55 5 11 16

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell Tab_GotFocus(object, RoutedEventArgs) :

void

51 13 6 22

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabAdvancedCategoryCombo_MouseEnter(o

bject, MouseEventArgs) :

void

100 1 1 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabAdvancedCategoryCombo_SelectionChan

ged(object, SelectionChangedEvent

Args) : void

63 5 8 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabAdvancedCBxOldEditions_Checked(object,

RoutedEventArgs) : void

69 3 5 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabAdvancedCBxOldEditions_Unchecked(object, RoutedEventArgs) :

void

67 3 5 7

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabAdvancedDocLangCombo_SelectionChang

ed(object, SelectionChangedEvent

Args) : void

63 5 8 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabCtrl2_SelectionChanged(object,

SelectionChangedEventArgs) : void

63 9 9 8

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserBrandCombo_SelectionChanged(obje

ct, SelectionChangedEvent

Args) : void

62 1 7 11

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserDocCategoryCombo_SelectionChang

ed(object, SelectionChangedEvent

Args) : void

100 1 1 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserFreqCombo_SelectionChanged(object, SelectionChangedEvent

Args) : void

100 1 1 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserLangCombo_SelectionChanged(objec

t, SelectionChangedEvent

Args) : void

100 1 1 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserPrenCckBoxShowPhasedOutProducts

_Checked(object, RoutedEventArgs) :

void

66 1 4 9

Page 40: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

36

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserPrenCckBoxShowPhasedOutProducts

_Unchecked(object, RoutedEventArgs) :

void

74 1 3 5

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserPrenHelp_Click(object,

RoutedEventArgs) : void

100 1 1 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserPrenInstrButton_Click(object,

RoutedEventArgs) : void

95 1 2 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserPrenReset_Click(object,

RoutedEventArgs) : void

100 1 1 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserSalesCodeCombo_SelectionChanged(

object, SelectionChangedEvent

Args) : void

100 1 1 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserSegmentCombo_SelectionChanged(o

bject, SelectionChangedEvent

Args) : void

63 1 7 10

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserSeriesCombo_SelectionChanged(obje

ct, SelectionChangedEvent

Args) : void

73 1 7 5

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell tabUserSettings_SelectTabItems() : void

58 3 14 10

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserSettings_UpdateSettings() : void

51 16 11 14

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserSettingsOK_Click(object,

RoutedEventArgs) : void

46 6 16 32

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TabUserStartCombo_SelectionChanged(objec

t, SelectionChangedEvent

Args) : void

95 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TBxPubNrSearch_GotFocus(object,

RoutedEventArgs) : void

55 2 17 17

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TBxPubNrSearch_KeyDown(object,

KeyEventArgs) : void

79 2 1 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TestServiceContact() : void

72 2 6 5

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TimeLineFrom_SelectedDateChanged(object,

SelectionChangedEventArgs) : void

54 9 16 15

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell TimeLineTo_SelectedDateChanged(object,

SelectionChangedEventArgs) : void

65 4 8 8

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell ToggleRowDetailsButton_Click(object,

RoutedEventArgs) : void

56 5 9 16

Member Client\ITT ITT.TPI Shell UpdateAllCombos(strin 0 152 25 298

Page 41: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

37

.TPI (Debug)

g) : void

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell UpdateAppearanceForDetailSearchPane(bool)

: void

76 2 4 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell updateSetupSelectionString() : void

42 21 15 31

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell UserName.get() : string 84 1 2 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetAllCategoriesCompleted(objec

t, GetAllCategoriesCompletedEventArgs) : void

65 3 5 8

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetAllCategoryCharacteristicsCo

mpleted(object, GetAllCategoryCharacteristicsCompletedEven

tArgs) : void

64 3 5 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetAllGroupsCompleted(object, GetAllGroupsComplete

dEventArgs) : void

65 3 5 8

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetAllItemCharacteristicsComplet

ed(object, GetAllItemCharacteristicsCompletedEventArgs

) : void

64 3 5 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetAllLanguagesCompleted(objec

t, GetAllLanguagesCompletedEventArgs) : void

65 3 5 8

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetAllSalesCodesCompleted(obje

ct, GetAllSalesCodesCompletedEventArgs) : void

64 3 7 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetAllSalesCodesXCompleted(obj

ect, GetAllSalesCodesXCompletedEventArgs) : void

59 9 6 11

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetAllSegmentsCompleted(objec

t, GetAllSegmentsComple

tedEventArgs) : void

58 9 8 12

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetAllVersionCodesCompleted(ob

ject, GetAllVersionCodesCompletedEventArgs) :

void

64 3 5 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetBrandsCompleted(object,

GetBrandsCompletedEventArgs) : void

57 9 9 13

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webservice_GetBrandsUsingDenominationCo

mpleted(object, GetBrandsUsingDenominationCompletedEven

tArgs) : void

66 3 5 7

Page 42: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

38

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetCharacteristicsCompleted(obj

ect, GetCharacteristicsCompletedEventArgs) : void

70 3 3 6

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetComplexDocumentsComplete

d(object, GetComplexDocumentsCompletedEventArgs)

: void

46 6 32 28

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetGroupIDsCompleted(object,

GetGroup_IDsCompletedEventArgs) : void

52 6 10 21

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetIDsForCategoryLanguageGroupIDAndStatusComplete

d(object, GetIDsForCategoryLanguageGroupIDAndStatusCompletedEventArgs) :

void

63 4 7 10

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetProductSeriesCompleted(obje

ct, GetProductSeriesCompletedEventArgs) : void

57 9 11 13

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetRelatedProductsCompleted(o

bject, GetRelatedProductsCo

mpletedEventArgs) : void

60 3 11 11

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webservice_GetRSSHelpFileDataCompleted(o

bject, GetRSSHelpFileDataCompletedEventArgs) :

void

52 4 11 19

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetSalesCodesForBrandSearchCo

mpleted(object, GetSalesCodesForBrandSearchCompletedEve

ntArgs) : void

58 4 17 13

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webservice_GetUserSettingsCompleted(objec

t, GetUserSettingsCompletedEventArgs) : void

51 11 11 20

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetVersionCodesCompleted(obje

ct, GetVersionCodesCompletedEventArgs) : void

52 7 13 20

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_GetVersionCodesForBrandSearch

Completed(object, GetVersionCodesForBrandSearchCompletedE

ventArgs) : void

59 4 11 13

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_InfraProxy_LogExceptionComplet

ed(object, LogExceptionComplete

dEventArgs) : void

100 1 1 0

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webservice_SetUserSettingsCompleted(object, SetUserSettingsComple

69 3 2 7

Page 43: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

39

tedEventArgs) : void

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell webService_TestConnectionCompleted(object

, TestConnectionComple

tedEventArgs) : void

76 2 5 3

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionCode.get() : DTOVersionCode

84 1 3 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionCode.set(DTOVersionCode) : void

92 1 3 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionCodeCombo_DropDownClosed(object,

EventArgs) : void

79 1 1 4

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionCodeCombo_SelectionChanged(object, SelectionChangedEvent

Args) : void

54 7 14 17

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionCodeConverter(ObservableCollection<

DTOVersionCode>) : ObservableCollection<s

tring>

63 4 4 9

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionCodes.get() : ObservableCollection<

DTOVersionCode>

84 1 4 2

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionCodes.set(ObservableCollection<DTOV

ersionCode>) : void

92 1 4 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionCodesForBrandSearch.get() :

ObservableCollection<DTOVersionCode>

91 1 4 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionCodesForBrandSearch.set(ObservableCollection<DTOVersion

Code>) : void

92 1 4 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionNumber.get() : string

91 1 2 1

Member Client\ITT.TPI

(Debug)

ITT.TPI Shell VersionNumber.set(string) : void

92 1 2 1

Page 44: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

40

Appendix B Complete set of metrics data from the refactored TPI application.

Scope Project Namespace Type Member Maintainability Index

Cyclomatic Complexity

Depth of Inheritance

Class Coupling

Lines of Code

Project Server\ITT.TPI.Web (Debug)

72 345 4 97 642

Namespace Server\ITT.TPI.Web (Debug)

ITT.TPI.Web 79 18 4 38 47

Type Server\ITT.TPI.Web (Debug)

ITT.TPI.Web BundleConfig

65 2 1 4 13

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web BundleConfig

BundleConfig() 100 1 0 1

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web BundleConfig

RegisterBundles(BundleCollection) : void

56 1 4 12

Type Server\ITT.TPI.Web (Debug)

ITT.TPI.Web FilterConfig

95 2 1 2 2

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web FilterConfig

FilterConfig() 100 1 0 1

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web FilterConfig

RegisterGlobalFilters(GlobalFilterCollection)

: void

94 1 2 1

Type Server\ITT.TPI.Web (Debug)

ITT.TPI.Web HandleErrorWithAjaxFilter

58 9 4 15 22

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web HandleErrorWithAjaxFilter

HandleErrorWithAjaxFilter()

100 1 1 1

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web HandleErrorWithAjaxFilter

OnException(ExceptionContext) : void

50 8 14 21

Type Server\ITT.TPI.Web (Debug)

ITT.TPI.Web MvcApplicatio

n

79 2 2 10 6

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web MvcApplicatio

n

Application_Start() : void

73 1 9 5

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web MvcApplicatio

n

MvcApplication() 100 1 1 1

Type Server\ITT.TPI.Web (Debug)

ITT.TPI.Web RouteConfig

90 2 1 4 3

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web RouteConfig

RegisterRoutes(RouteCollection) : void

82 1 4 2

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web RouteConfig

RouteConfig() 100 1 0 1

Type Server\ITT.TPI.Web (Debug)

ITT.TPI.Web WebApiConfig

89 1 1 4 1

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web WebApiConfig

Register(HttpConfiguration) : void

89 1 4 1

Namespace Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

53 285 3 55 535

Page 45: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

41

Type Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

53 285 3 55 535

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

buildIntersectGroups(IEnumerable<string>, IEnumerable<string>, IEnumerable<string>, IEnumerable<string>, IEnumerable<string>, bool, bool, bool, bool) : IEnumerable<string>

62 5 2 10

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

CreateFeedsLink(DTOSearchArguments,

DTOCharacteristic) : JsonResult

45 10 10 30

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetAllCategories() : JsonResult

64 3 8 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetAllCharacteristics() : JsonResult

61 7 12 8

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetAllLanguages() : JsonResult

64 3 8 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetAllProductSeries(DTOSearchArguments) :

JsonResult

64 3 9 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetAllSalesCodesX() : JsonResult

64 3 8 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetAllSegments() : JsonResult

64 3 8 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetAllVersionCodesX() : JsonResult

64 3 8 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetBrandFromSalesCode(DTOSalesCode) :

DTOBrand

61 4 10 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetBrands() : JsonResult

64 3 8 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetCategories(DTOSearchArguments) :

JsonResult

48 20 12 20

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetCurrentProductSeries(DTOSearchArgume

nts) : JsonResult

62 7 8 8

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetCurrentSalesCodesX(DTOSearchArgumen

ts) : JsonResult

62 8 8 8

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetDocuments(DTOSearchArguments) :

JsonResult

52 6 13 19

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetGroupIDsforSearch(DTOSearchArguments

) : IEnumerable<string>

19 74 14 120

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetLanguages(DTOSearchArguments) :

JsonResult

48 20 12 20

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetObsoleteProductSeries(DTOSearchArguments) : JsonResult

52 12 10 16

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetObsoleteSalesCodesX(DTOSearchArgume

nts) : JsonResult

56 10 9 12

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetPDFByteArray(string, string, string) :

ActionResult

61 3 6 10

Page 46: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

42

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetProductSeries(DTOSearchArguments) :

JsonResult

61 4 8 11

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetRSSHelpFile() : JsonResult

69 2 5 6

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetSalesCodesX(DTOSearchArguments) :

JsonResult

61 4 8 11

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetSegments(DTOBrand) : JsonResult

58 5 11 13

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetUserSettings() : JsonResult

64 2 9 8

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

GetVersionCodesX(DTOSearchArguments) :

JsonResult

51 12 11 20

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

HomeController() 64 1 11 7

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

HttpGet(string) : byte[]

73 2 2 5

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

Index() : ActionResult 89 1 2 2

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

IsAnyNullOrEmpty(object) : bool

62 5 2 10

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

IsTPIDocument(string, string) : bool

63 4 2 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

setUriToShowDocument(string, string, string,

string) : string

62 2 2 9

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

SetUserSettings(DTOUserSettings) : void

67 2 7 7

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.Controllers

HomeControll

er

UpdateCharacteristics(DTOSearchArguments,

DTOCharacteristic) : JsonResult

32 32 19 64

Namespace Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.ExtensionMeth

ods

49 42 1 13 60

Type Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.ExtensionMeth

ods

ExtensionMet

hod

49 42 1 13 60

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.ExtensionMeth

ods

ExtensionMet

hod

DistinctBy<TSource, TKey>(this

IEnumerable<TSource>, Func<TSource,

TKey>) : IEnumerable<TSource

>

83 1 5 2

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.ExtensionMeth

ods

ExtensionMet

hod

DontShowAllEditions(this

List<DTOIDsForCategoryLangGroupAndStatu

s>, DTOSearchArguments,

bool, bool) : IEnumerable<string>

45 20 10 26

Member Server\ITT.TPI.Web (Debug)

ITT.TPI.Web.ExtensionMeth

ods

ExtensionMet

hod

ShowAllEditions(this List<DTOIDsForCategoryLangGroupAndStatu

s>, DTOSearchArguments,

bool, bool) :

43 21 10 32

Page 47: The Impact of Refactoring Legacy Systems on Code Quality ...1114582/FULLTEXT01.pdfMaintaining legacy code can be difficult, it can also be hard to know whether what you are doing to

43

IEnumerable<string>