The Effects of Refactoring on Software Quality - SERSC

18 downloads 24 Views 525KB Size Report
Fowler provided a catalogue of refactoring and proposed when to use them to fix code smells [1]. To preserve refactoring behavior, some studies used automatic ...
International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

An Empirical Assessment of Refactoring Impact on Software Quality Using a Hierarchical Quality Model Raed Shatnawi1, Wei Li2 Software Engineering Department, Jordan University of Science & Technology, Irbid, Jordan 22110 Computer Science Department, University of Alabama in Huntsville, AL 35899, USA, [email protected], [email protected] Abstract Software refactoring is a collection of reengineering activities that aims to improve software quality. Refactorings are commonly used in agile software processes to improve software quality after a significant software development or evolution. There is belief that refactoring improves quality factors such as understandability, flexibility, and reusability. However, there is limited empirical evidence to support such assumptions. The aim of this study is to confirm such claims using a hierarchal quality model. We study the effect of software refactoring on software quality. We provide details of our findings as heuristics that can help software developers make more informed decisions about what refactorings to perform in regard to improve a particular quality factor. We validate the proposed heuristics in an empirical setting on two open-source systems. We found that the majority of refactoring heuristics do improve quality; however some heuristics do not have a positive impact on all software quality factors. In addition, we found that the impact analysis of refactorings divides software measures into two categories: high and low impacted measures. These categories help in the endeavor to know the best measures that can be used to identify refactoring candidates. We validated our findings on two open-source systems—Eclipse and Struts. For both systems, we found consistency between the heuristics and the actual refactorings. Keywords: Refactoring, design measures, quality factors, QMOOD.

1. Introduction A particular refactoring is a sequence of code changes that improves the quality of design without changing the behavior of software [1]. Software refactoring is commonly used in agile software processes to improve software quality [2]; it is used for continuous improvement of the structure and the understandability of software artifacts during development [3]. The purpose of these changes is to transform a program structure into a better quality after fixing quality defects such as bad smells, anti-patterns, flaws, pitfalls, anomalies, ill-nesses [4]. This kind of transformations reduces the cost and effort of software maintainability for the long run by keeping software complexity within acceptable levels [5]. Refactoring has been used in practice to improve software quality for commercial and opensource software systems. For example, Microsoft reserves 20% of the development effort on code rewriting [6]. Lucent had redesigned systems with design patterns and refactored the

127

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

code to match a proposed design [7]. In an open-source system example, Mozilla’s code was refactored in the beta phase [8]. The refactorings logged in ArgoUML code repository were studied by [9], and found that after refactoring only few bugs were reported and few mails have been written. Murphy et al. reported observations on interactions of 41 Eclipse developers at several iterations of open-source development, they found evidence of using 11 kinds of refactoring operations available in Eclipse IDE and they found that move method was the most used refactoring [10]. In amore recent study, Bowdidge reported experience report on adding refactoring to Apple’s Xcode IDE for programs built in Objective-C [11]. The objective was to add a refactoring tool that can refactor 200,000 line programs interactively and within acceptable timeframe. Software refactoring follows a systematic process both in agile and non-agile development processes. Mens and Tourwé described refactoring as a process that consists of many activities [12]: first, identify refactoring candidates (i.e., where the software should be refactored); second, determine which refactoring(s) to apply; third, guarantee that refactoring preserve behavior; fourth, assess the effect of the refactoring on software product quality characteristics (e.g., complexity, understandability, and maintainability) or software process (e.g., productivity, cost, and effort). Many research studies have been conducted to find the classes that are in need of refactoring. Zhao and Hayes used static measures to predict refactoring candidates [13]. Another common approach to detect where to refactor is the identification of bad smells [1] [14] [15]. Simon et al. proposed a metric-based approach [16], while Kataoka et al. used program invariants to indicate where refactorings might be applicable [17]. Fowler provided a catalogue of refactoring and proposed when to use them to fix code smells [1]. To preserve refactoring behavior, some studies used automatic code transformation [18]. In industry, there are many development tools that can be used to automate software refactoring for many OO languages and development environments, for example, Eclipse1, Together ControlCenter2 and others. Although many software development environments include refactoring tools, there are few comprehensive studies that assess the effect of a large number of refactoring mechanics on software quality. In addition, there are few previous works that provide a set of refactoring heuristics that can be used to detect refactorings and can work as guidelines for developers when refactoring. Software developers have to refactor and then validate the effect of their refactoring on software quality using other criteria such as collecting metrics data, which is a time-consuming activity. In this paper, we aim to identify refactoring heuristics that establish the relationship between software refactoring and software quality. The objectives of this work are threefold: 1. To assess the effect of refactoring activities on both the internal and external quality characteristics using a quality model. Quality models are tools that are used for the quality assessment. A quality model defines a set of quality characteristics and the relationships between them, which provide the basis for specifying quality requirements and evaluating quality [19]. In this work, wehave adapted a hierarchal Quality Model for Object-Oriented Design (QMOOD) that relates between internal and external quality characteristics [20]. 2. To establish refactoring heuristics3 that can help developers in making decisions whether refactorings improve software quality characteristics or not.

1

www.eclipse.org www.borland.com 3 Refactoring heuristics are experience-based refactorings that are used to reduce the need for calculations pertaining to software size or a tool performance. 2

128

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

3. To validate that refactoring heuristics are consistent with refactorings in real context, open-source community. The result of using a quality model is a list of refactoring heuristics that relates refactoring to software quality. These heuristics inform developers whether to carry out prescribed refactorings to improve the software quality or to search for other alternatives to improve quality. In the remainder of this paper, we provide more details on the related work in Section 2; the quality model (i.e., QMOOD) is described in Section 3; the research methodology in Section 4, which elaborates on software measures and software refactorings. In Section 5, we discuss the results and analyze the effect of refactoring heuristics on metrics and quality factors. In Section 6, we empirically validate our findings on two real case studies. Finally, we conclude our work and discuss the limitations and future work.

2. Related Work Software refactoring improves core object-oriented (OO) design internal properties such as encapsulation, abstraction, message passing, inheritance, and polymorphism [1] [2]. These properties can be quantified by software measures as Bansiya and Davis have suggested in [20]. The general belief is that improving these design properties leads to improvements on external quality factors such as understandability, reusability, efficiency, usability and functionality [21]. In addition, refactoring activities can be classified according to quality factors that can be achieved through particular refactorings [22]. Such a classification allows developers to selectively improve software quality. In most literature of software refactoring, it is assumed that refactoring improves software quality to some extent. For example, refactoring makes software design easier to modify [1], easy to extend and maintain [23], and easy to reuse [24]. However, there is limited empirical evidence of such assumptions. In this section we summarize many empirical studies that were conducted to find the impact of refactorings on the quality of software systems. Sahraoui et al. used software measures for detecting situations where a particular refactoring can be applied to improve the quality of a software system [25]. They derived empirically a set of rules on coupling and inheritance measures that can be used to select the best refactorings to improve software maintainability. In an academic study with a group of students, Stroulia and Kapoor found that refactoring decreases the size and coupling measures which they believe to increase the extendibility of the software [26]. Demeyer found, in an empirical context, that program performance improved after refactoring (e.g., replacing conditional logic by polymorphism) [27]. Kataoka et al. used coupling measures in evaluating the effect of refactoring on maintainability of a program and found that refactoring enhanced system maintainability [28]. Kataoka et al. validated these results on a C++ program for two refactoring activities: Extract Method and Extract Class. Bois and Mens have proposed a formalism framework [29], derived using Abstract Syntax Tree notations borrowed from Mens et al. [30], for analyzing the impact of software refactorings on internal measures describing the impact of refactorings on program structure. They validated the proposed framework on a small demo program; the study evaluated three refactorings only: Extract Method, Encapsulate Field, and Pull-up Method, on many software measures (Number of Methods, Number of Children, Coupling, Response for a Class, and Cohesion). The results in Bois and Mens’ work showed positive and negative impacts on the studied measures. Leitch and Stroulia studied the effect of software refactoring on software maintenance effort and costs using dependency graphs [31]. They conducted their study on two systems to discover refactoring opportunities through detecting bad smells. They provided a refactoring plan, which used two small refactorings, Extract Method and Move Method, for most of the refactorings. Their study found that refactoring

129

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

improved quality by reducing the size of code, increasing the number of procedures, reducing the density of dependencies, and reducing regression testing. Tahvildari proposed a quality framework for software re-engineering process that connects required software qualities with program transformations to improve the intended qualities [32]. The framework considers transforming programs to improve quality requirements, such as performance, and maintainability, during the re-engineering process. They assessed the re-engineering framework on two case studies (two different legacy systems written in C and migrated to C++) and the results show that the use of design patterns produced a more maintainable and higher performance system than the legacy system [33]. In another study, Tahvildari and Kontogiannis used the same framework to evaluate the impact of six transformations on many OO measures (coupling, cohesion, inheritance and complexity) [34]. The resulting impact is used to guide the reengineering process to achieve a particular quality factor (maintainability) in four open-source applications. Bois et al. proposed guidelines for enhancing cohesion and coupling measures and obtained promising results by applying them in refactoring a opensource software system—Apache Tomcat [35]. There were five refactorings under study: Extract Method, Move Method, Replace Method with Method Object, Replace Data Value with Object, and Extract Class. Bois et al. have provided a set of guidelines that serves software maintainers in their endeavor to optimize software quality and ruled out those refactorings of which the resolution will not lead to improve coupling or cohesion measures. This study has shown that the effect of refactoring on coupling and cohesion measures ranged from negative to positive. Ratzinger et al. showed that refactoring enhanced software evolvability, i.e. reduced the change coupling [36]. They used the change history from software repository to detect refactoring opportunities. After software refactoring, the evolution of the system was more facilitated and did not lead to worse change couplings or change smells. In another study, Moser used internal measures to assess the effect of refactorings on reusability and found that refactoring enhanced reusability of hard-to-reuse classes in an Agile process [37]. They conducted an empirical study on a commercial system and used internal measures, cyclomatic complexity and the CK4 measures, as surrogates for reusability. In a 2008 study, Moser and his colleagues found that refactoring not only increased aspects of software quality, but also improved productivity [3]. To validate their results, an empirical study was conducted on a commercial software system developed in Java and the collected measures were LOC, CK4 measures, Effort (hour), and Productivity (LOC); the study found that software refactoring reduces code complexity and coupling and increases cohesion. Recently, a more comprehensive study was conducted by Alshayeb [38]; he conducted his study to find the impact of eight refactorings on five quality factors: adaptability, maintainability, understandability, reusability, and testability. The results in Alsheyb’s work showed more negative relationships between the applied refactorings and the software quality factors (adaptability, maintainability, understandability, reusability and testability). Rech proposed a quality framework (defect diagnosis) that addresses the problem of diagnosing and handling quality defects [4]. The application of the framework perceived improvement of maintainability and productivity (finding defects). Most studies found a positive relationship between software refactoring and the software quality, either indirectly or directly measured. We summarize these studies in Table 1, which includes important factors such as the studied systems, internal and external measures, the quality model (quality index), and the validated refactorings. A quality index is a mathematical calculation of an external quality factor from internal measures. From Table 1, we deduce that there are many 4

There are many empirical studies put the CK metrics into relationship with software quality, in particular with maintainability, reusability, and reliability.

130

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

challenges facing the researchers: 1) most studies evaluated one or two external quality factors using internal measures without using a validated quality model; 2) most studies, that are shown in Table 1, evaluated a small number of software refactorings or transformations and that due to the massive effort needed to include more refactorings. To overcome these challenges we conduct a study on a larger number of refactorings (43 refactorings) using a quality model proposed by Bansiya and Davis [20] on four quality factors measured indirectly using nine different software measures. The study is conducted on two large software components: EclipseUI and Struts from Apache. Table 1. A Summary of Related Work Authors

Case Study

Internal Measures Inheritance and coupling measures Size and coupling

External Measures

Quality Model

Fault-proneness

No

Design extendibility

No

Refactorings Extract Superclass, Extract Subclasses, Extract Aggregate Classes Extract Superclass, Extract abstract class Replace Conditional with Polymorphism Extract Method and Extract Class Extract Method, Encapsulate Field, and Pull-up Method,

Sahraoui et al. [25]

A C++ program

Stroulia and Kapoor [26]

Academic

Demeyer [27]

A small program

-

Performance

No

Kataoka et al. [28]

A C++ program

Coupling

Maintainability

No

Bois and Mens [29]

A small demo program

#Methods, CK measures

-

No

Leitch and Stroulia [31]

Academic and commercial

Maintenance effort and costs

No

Extract Method, and Move Method

Tahvildari et al. [33]

A project in industrial environment and open library; both written in C.

Maintainability and performance

three software maintainability indexes and two performance measures

Design patterns

Tahvildari and Kontogiannis [34]

Four open-source applications

Maintainability

Metrics interpretation

Code Transformations

Code size, number of procedures Halstead's efforts, LOC, and number of Comment lines per module coupling, cohesion, inheritance and complexity

Bois et al. [25]

open source software

cohesion and coupling

-

No

Extract Method, Move Method, Replace Method w Method Object, Replace Data Value w Object, and Extract Class

Ratzinger et al. [36]

Open source system

Change coupling

Evolvability

No

Change smells

Moser [37]

A project in industrial environment

Reusability

metrics interpretation based on work of Dandashi and Rine [40]

Not available

Moser et al. [3]

A project in industrial environment

Productivity (LOC)

No

Not available

adaptability, maintainability, understandability, reusability, and testability

metrics interpretation based on work of Dandashi and Rine [40].

Extract Class, Encapsulate Field, Extract Subclass, Move Class, Extract Method, Replace Temp with Query, and Extract Subclass

Alshayeb [38]

Three small Opensource projects

McCabe’s cyclomatic complexity, and CK measures [39] LOC, CK measures, Effort (hour),

CK measures, LOC, FOUT

131

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

3. The Quality Model for Object-Oriented Design To achieve the objectives of this research, we need a quality model that can be easily used to evaluate and interpret system evolution when refactoring. To find the effect of refactoring activities on software quality, the model must also measure both the internal and external quality characteristics. Internal characteristics are used to measure software properties such as information hiding, inheritance, and polymorphism. There are many quality models that link between internal software properties and external quality factors. McCall and his colleagues [40] defined a quality model as a hierarchy of factors, criteria, and measures. ISO 91265 [41] is a standard model that defines quality as a set of product characteristics at two levels: internal and external. Squid a variant of the ISO 9126 model, but it depends on having a past-experience database to establish a relationship between internal and external quality characteristics [42]. Bansiya and Davis [20] proposed and validated a hierarchal Quality Model for Object-Oriented Design (QMOOD) that relates between internal and external quality characteristics. All these models are hierarchal and can be used to define measures and the relationships between the internal and external quality characteristics. However they differ at the low level of the hierarchy and the measure definition. QMOOD model can be used at both the system and component levels and it is easy to assess, because it provides a quantitative assessment of external quality factors from the measurements of the internal design properties. QMOOD is a hierarchal quality model that is used to assess external quality factors using design measures and can be applied to early stages (requirements and design) to ensure that the product artifacts have favorable internal properties. This model gives developers an opportunity to fix problems, remove irregularities and nonconformance to standards, and eliminate unwanted complexity early in the development cycle [20]. QMOOD assesses six external quality factors, eleven internal design properties, and OO design components such as attributes, methods, classes, composition, and inheritance hierarchies. We want to assess the effect of refactoring software components on four software quality factors only. The definitions of the four quality factors are provided as follows:  Reusability: The degree to which a software module or other work product can be used in more than one computer program or software system.  Flexibility: The ease with which a system or component can be modified for use in applications or environments other than those for which it was specifically designed.  Extendibility: The ease with which a system or component can be modified to increase its storage or functional capacity.  Effectiveness: The degree to which a design is able to achieve the desired functionality and behavior using OO design concepts and techniques. We have excluded the understandability factor because it is a subjective quality factor and using a model of merely static measures to evaluate understandability is inadequate. In addition, we have excluded the functionality factor because we assume that refactoring does not change the behavior of systems, rather it changes the internal characteristics of systems without changing functionality. The effect of refactorings on these quality factors cannot be assessed directly. QMOOD links these factors to many design properties that are quantified by software measures as shown in Table 2. Each quality factor is a function of many software 5

ISO 9126 is software product quality standard that was superseded by SQuaRE series of International Standards (ISO/IEC 25000) (ref]

132

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

properties (measures). Refactoring activities change the internal design of a software system; therefore we expect refactoring to impact external quality factors consequently. For example, the reusability is an index of four weighted properties: coupling, cohesion, messaging, and design size. Consequently, changing these properties, because of refactoring, affect reusability as well. Increasing class coupling decreases class reusability, whereas increasing class cohesion, message passing among objects, or number of classes increase the reusability of the system’s components. Table 2. Quality indices of external quality factors as adapted from [20] Quality Factors

Quality Index Calculation

Reusability

–0.25 * Coupling + 0.25 * Cohesion + 0.5 * Messaging + 0.5 * Design Size

Flexibility

0.25 * Encapsulation – 0.25 * Coupling + 0.5 * Composition + 0.5 * Polymorphism

Extendibility

0.5 * Abstraction – 0.5 * Coupling + 0.5 * Inheritance + 0.5 * Polymorphism

Effectiveness

0.2 * Abstraction + 0.2 * Encapsulation + 0.2 * Composition + 0.2 * Inheritance + 0.2 * Polymorphism

Bansiya and Davis have proposed and validated these indexes empirically. Proportional weights were assigned to indicate the influence of the properties on a quality factor [20]. Bansiya and Davis conducted an empirical study to determine the weights and the model was validated on the evolution of two real systems. The weights (+0.5, +1) were used initially if a measure positively influences a quality attribute and the weights (-0.5, - 1) were used for negative influences. These weights were changed to ensure that the sum of weighted values added to +1; for example, the sums of weighted values of the properties used to measure Reusability add to 1 [44]. An increase on a quality factor after maintenance indicates improvement of quality; otherwise a decrease indicates quality deterioration. QMOOD was selected for this work because it provides quality indexes that are easy to interpret using software measures. QMOOD provides these measures and how to assess them. The evolution of a particular quality can be measured by considering the differences between measuring the two consecutive releases. For example the effect of evolution on Flexibility is denoted ∆Flexibility. Figure 1 shows how the effect on flexibility can be evaluated. This mathematical evaluation applies to all other quality factors. From this figure we can notice that if we know the differences between measures, which result from refactorings, then we do not need to calculate the measures from source code before and after refactoring. Therefore, we can use refactoring heuristics to find the effect of refactoring on the evolution of software quality. There are many research studies that used QMOOD to assess software quality. For example, O’Keeffe and O´Cinneide used QMOOD to evaluate alternative designs that can produce a better quality [45]. In another study, Hsueh et al. used QMOOD to validate whether a design pattern is well-designed [46], i.e., it answers the question whether a proposed structural model really resolves the quality problems described in the intent of design patterns. Furthermore, using QMOOD has many advantages: it can be used to measure software artifacts at many phases; it evaluates many external quality factors such as reusability, flexibility, extendibility and effectiveness; it provides an assessment of the quality

133

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

of the software artifact after evolution, which is consistent with the measurements of the external quality factors mentioned above; it gives one measurement for each quality factor, therefore making the comparison between before and after refactoring easy to assess. Finally, QMOOD is insensitive to the design size (number of classes), because we compare normalized system measurements. The evolution of flexibility is measured as ∆Flexibility = Flexibility2 – Flexibility1 This is equivalent to ∆Flexibility = (0.25 * Encapsulation2 – 0.25 * Coupling2 + 0.5 * Composition2 + 0.5 *

Polymorphism2) – (0.25 * Encapsulation1 – 0.25 * Coupling1 + 0.5 * Composition1 + 0.5 * Polymorphism1) By using the redistributive property we get ∆Flexibility = 0.25 * (Encapsulation2 – Encapsulation1) – 0.25 * (Coupling2 – Coupling1) + 0.5 *

(Composition2 – Composition1) + 0.5 * (Polymorphism2 – Polymorphism1)

Figure 1. The evolution of software flexibility

4. Research Methodology In this section, we describe the methodology to evaluate refactorings under study. First, we introduce software measures. Next, we introduce how refactorings affect measures. 4.1

Software Measures

QMOOD uses eleven OO measures to quantify system design properties. However nine measures only are used to measure the four quality factors. In this section, we provide a description of how we evaluate the effect of refactoring activities on these measures6. Refactoring changes the structure of software such as classes, relationships among classes (inheritance, compositions, dependencies), and the constituents of classes (attributes and methods). These class changes cause changes in the system, which are indicators of quality change. We use a quality assurance tool, ckjm7, to collect the following measures: Design size (DSC): measures the number of classes in a system. This measure is simple and the effect of refactoring on this measure is easy to assess. Many refactorings affect this measure such as Extract Class, and Replace Method with Method Object. Such refactorings increase the number of classes in a design, whereas Inline Class decreases this measure. Abstraction (ANA): measures abstraction of a system. ANA is computed by determining the average of the depth of the inheritance tree (DIT). DIT is the length of the inheritance chain from the root of the inheritance tree to the measured class [39]. This measure is an indicator of the number of ancestors of a class and provides insight to the generalization in the inheritance hierarchy. A refactoring such as Extract Superclass increases abstraction. Encapsulation (DAM): measures the average of the data encapsulation in a system. Data access measure (DAM) is the ratio of the private attributes to the total number of attributes in a class. Every class encapsulates data and operations. The main criterion for a good class is to have as much data invisible to non-member methods as possible; otherwise

6

We omitted the definitions of inheritance hierarchies and design complexity measurements because they are not used to measure the four quality factors in Table 2. 7 http://www.spinellis.gr/sw/ckjm/doc/index.html/.

134

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

the encapsulation is compromised. Encapsulate Field increases the encapsulation (information hiding), because it converts a public attribute into private. Coupling (DCC): Direct class coupling (DCC) counts the number of classes that a class is directly connected to. The couplings include classes that are related by attribute declarations and message passing. This measure is an indicator of the need to other classes. Large values of DCC measure means that the system is highly coupled. Refactoring high coupled classes can improve quality. For example, Change Bidirectional Association to Unidirectional reduces the coupling among classes. Thus, this refactoring decreases coupling in the system. Cohesion (CAM): Cohesion among methods of classes (CAM) computes the relatedness (similarities) among methods of a class. The class that does one thing (i.e., cohesive) is easier to reuse and maintain than the class that does many different things (i.e., the class provides many different services). The low cohesive classes may need to be refactored. Refactoring attributes and methods in a class affects cohesion. When assessing the mechanics of refactoring, we use our subjective perception to evaluate the change on CAM. For example, Move Field is a refactoring that is considered increasing the cohesiveness of a class because the moved field does not belong to the refactored class, i.e., reduces dissimilarities among the methods. In the validation case studies, we use the cohesion measure that was defined by Henderson-Sellers [47]. Henderson-Sellers revised the LCOM measure [39] to normalize it for the number of methods and attributes in the class. Composition (MOA): Measure of aggregation (MOA) in the system is a count of the number of data declarations that are user defined classes. MOA measures the extent of the part-whole relationships (composition), realized by using attributes. Objects can encapsulate data attributes as well as other objects. The refactoring activity, Replace Array with Object, replaces data stored in an array into an object. This refactoring introduces a part-whole relationship and therefore increases the use of composition. Inheritance (MFA): Measure of functional abstraction (MFA) is the ratio of the number of inherited methods by a class to the total number of local methods in the class. MFA measures the utilization of inheritance in a design. When inheritance is used effectively the number of inherited methods increases. Many empirical and theoretical studies have shown that inheritance is not utilized well in object-oriented systems [48]. Refactoring can be used to increase the reusability via inheritance. Increasing the number of inherited methods is a sign of a functional abstraction. For example, the Form Template Method uses inheritance to pull-up the identical methods into a superclass. This refactoring increases the functional abstraction in a design. Polymorphism (NOP): Number of polymorphic methods (NOP) is a count of polymorphic methods in a class. NOP measure counts the number of polymorphic methods. We use the number of children as a surrogate of NOP. The number of children represents the number of specializations and uses of a class. Changing parent classes (superclasses) also changes the polymorphism in the inheritance hierarchy. For example, Replace Conditional with Polymorphism increases the utilization of polymorphism by creating appropriate subclasses for each conditional statement. Messaging (CIS): Class interface size (CIS) is a count of public methods in a class, which is the size of the response set for the class. A class that has large number of responsibilities tends to be large and has many interactions with other classes. Replace

135

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

Parameter with Method extracts the calculation of a parameter into a method; therefore increases the interface size of the class. 4.2

Software Refactoring

Fowler has provided a catalogue of refactorings which includes 22 code smells and 72 possible refactoring activities. Fowler categorized these refactorings into: composing methods, moving features between objects, organizing data, simplifying conditional expressions, making method calls simpler, and dealing with generalizations [1[ . Software developers use refactoring to fix code smells or other defects. We study the refactorings that Fowler proposed to use to fix 22 code smells as listed in his catalogue. We found that only 43 refactorings are suggested to fixing the 22 code smells. Therefore, we have limited our analysis to these refactoring activities. Brief descriptions of these refactoring activities are listed in Appendix I. In Fowler's catalogue, each refactoring is described in a standard format that characterizes refactoring throughout a rationale, a motivation, mechanics, and an example. The rationale describes the situations that behind refactoring, i.e., when to refactor. The motivation shows the benefits and costs of the refactoring. The mechanics illustrates the refactoring in small steps. Applying refactoring mechanics make refactoring systematic and can avoid the risk of introducing bugs into the code. In our research, we evaluate the mechanics of each refactoring to produce refactoring heuristics that can be used to make informed decisions when and how to refactor. These heuristics are intended to be conceptually simple, potentially at the cost of accuracy or precision. We documented the quantitative effect of each refactoring activity on design properties as defined in QMOOD. To get indication of the effect of each refactoring activity on the external quality factors, we need to assess the effect of refactoring mechanics on design measures. For example Extract Class is a refactoring that is used to break a large class, i.e., the class is doing a work of two or more classes and should be divided into more classes. The Extract Class is usually used to fix the God Class (very large class). To measure the effect of this refactoring on design measures, we follow the mechanics that are described in Fowler's catalogue. The mechanics of Extract Class consist of the following steps: First, decide how to split the class. Second, create the new class. Third, make a link between the two classes. Fourth, move fields to the new class. And last, move methods to the new class. This refactoring increases the number of classes. Since these two classes will be linked, coupling between objects is increased (the DCC measure). Moving methods and fields to the new class (the splitting process) increases the cohesion of both classes (CAM measure). This refactoring is not intended to be used for inheritance hierarchy; therefore it has no effect on the inheritance measures (ANA, MFA and NOP). The effects of this refactoring on software measures are shown in Table 3. The Extract Class changes four measures. According to QMOOD (Table 3), these changes improve three quality factors: Reusability, Flexibility, and Effectiveness, and deteriorate one. Therefore, we generate refactoring heuristics that inform developers about the effects of Extract Class. In summary, the process of evaluating the mechanics of a particular refactoring consists of three steps. First, we consider the mechanics of every refactoring as described in Fowler's catalogue. Second, we evaluate the effect of the refactoring mechanics on design properties and assess the changes in the relevant measures. We use + to denote an increase, - to denote a decrease, or 0 to show no changes on measures. Third, we use the measure evolution to evaluate the effect on the quality factors using QMOOD functions that are shown in Table 3.

136

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

Table 3. The heuristic resulting from the Extract Class DSC

ANA

+

0

DAM

DCC

CAM

+

+

0

MOA +

MFA

NOP

CIS

0

0

0

This evaluation results in refactoring heuristics that can be used to make informed decisions in software development process. We want to a show an evidence of the effect of refactoring on software quality. To validate the consistency of the refactoring heuristics, we want to test whether software refactorings do have a significant impact on software quality attributes (reusability, flexibility, extendibility, and effectiveness). We conduct two case studies to provide empirical evidence of the relationship between refactoring and software quality.

5. Refactoring Analysis In this section, we analyze the effect of software refactorings on measurements of the internal design properties, and then we assess the effect of refactoring on the quality factors that are defined by QMOOD. 5.1 Refactoring Impact Analysis The evaluation of refactoring mechanics is conducted for the selected refactoring activities to establish refactoring heuristics. The heuristics provide a list of refactorings that make improvement on particular software quality factors and the ones that deteriorate software quality. These heuristics are supposed to help developers in their endeavor to improve quality without the time-consuming process of collecting measures. We present a summary of refactoring effects in Table 4a through Table 4f. The refactorings that are used in composing methods, Table 4a, affect the class interface and class coupling (three changes for each). Refactorings that move features between objects, Table 4b, affect class coupling and cohesion. Refactorings that organize data, Table 4c, affect many measures, but mostly number of classes, coupling, composition, and class interface. Refactorings that simplify conditional expressions, Table 4d, affect many measures but mostly class interface and class complexity. Refactorings that make method calls simpler, Table 4e, have small effect on many measures. Refactorings that deal with generalizations, Table 4f, affect many measures, but mostly number of classes, abstraction, class interface, inheritance and polymorphism. In summary, the most refactorings that have effect on software measures are the ones that organize data (Table 4c) and deal with generalizations (Table 4f). Table 4a. The effect of composing methods on software measures Refactoring

DSC

ANA

DAM

DCC

CAM

MOA

MFA

NOP

CIS

Extract Method

0

0

0

+

-

0

0

0

+

Inline Method

0

0

0

-

0

0

0

0

-

Replace Temp with Query Replace Method with Method Object Substitute Algorithm

0

0

0

0

0

0

0

0

+

+

0

0

+

0

+

0

0

0

0

0

0

0

0

0

0

0

0

137

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

Table 4b. The effect of moving features between objects on software measures Refactoring

DSC

ANA

DAM

DCC

CAM

MOA

MFA

NOP

CIS

0 0 + 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 + +

+ + + 0 0

0 0 + 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0

0

0

0

+

0

0

0

0

+

+

+

0

0

0

0

+

+

+

Move Method Move Field Extract Class Inline Class Hide Delegate Remove Middle Man Introduce Foreign Method Introduce Local Extension

Table 4c. The effect of organizing data on software measures Refactoring Replace Data Value with Object Replace Array with Object Duplicate Observed Data Change Bidirectional Association to Unidirectional Encapsulate Field Encapsulate Collection Replace Type Code with Class Replace Type Code with Subclasses Replace Type Code with State/Strategy

DSC

ANA

DAM

DCC

CAM

MOA

MFA

NOP

CIS

+

0

0

+

0

+

0

0

+

+

0

+

+

+

+

0

0

+

+

+

0

+

0

+

+

+

+

0

0

0

-

0

0

0

0

0

0

0

+

0

0

0

0

0

+

0

0

0

+

0

0

0

0

+

+

0

0

+

0

+

0

0

+

+

+

0

0

0

0

+

+

+

+

+

0

+

0

+

+

+

+

Table 4d. The effect of simplifying conditional expressions on software measures Refactoring

DSC

ANA

DAM

DCC

CAM

MOA

MFA

NOP

CIS

Decompose Conditional Replace Conditional with Polymorphism Introduce Null Object

0

0

0

0

0

0

0

0

+

+

+

0

0

0

0

+

+

+

+

+

0

0

0

0

+

+

+

Introduce Assertion

0

0

0

0

0

0

0

0

0

138

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

Table 4e. The effect of making method calls simpler on software measures Refactoring

DSC

ANA

DAM

DCC

CAM

MOA

MFA

NOP

CIS

Rename Method

0

0

0

0

0

0

0

0

0

Remove Parameter Replace Parameter with Explicit Methods Preserve Whole Object Replace Parameter with Method Introduce Parameter Object Remove Setting Method

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

+

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

+

+

0

0

+

0

0

0

0

0

0

0

0

-1

0

0

0

0

-

Table 4f. The effect of dealing with generalizations on software measures Refactoring

DSC

ANA

DAM

DCC

CAM

MOA

MFA

NOP

CIS

Pull Up Method

0

0

0

-

0

0

-

-

-

Push Down Method

0

0

0

+

0

0

+

+

+

Push Down Field

0

0

0

0

+

0

0

0

0

Extract Subclass

+

+

0

0

0

0

+

+

+

Extract Superclass

+

+

0

0

0

0

+

+

-

Extract Interface

+

+

0

0

0

0

+

+

0

Collapse Hierarchy

-

-

0

0

0

0

-

-

0

Form Template Method

0

0

0

0

0

0

+

+

+

0

-

0

+

0

+

-

-

+

0

+

0

-

0

-

+

+

-

Replace Inheritance with Delegation Replace Delegation with Inheritance

From the results of refactorings analysis, we can notice that some measures are impacted more than others. To characterize the effect of refactoring on software measures, for each category, we count the number of times a measure is impacted by the refactorings in that category. If a measure is impacted more than 50% of the times then it is considered highly correlated with such a group, otherwise it is loosely correlated. Table 5 shows which measures that best characterize the impact of refactoring. The measures in the second and third columns are ordered by the number of times they have impact on the relevant category. We notice that messaging (CIS measure) is the most common measure among highly impacted refactorings. CIS measure is the only highly impacted measure for all categories except for moving features between objects. The coupling measure (DCC) also changes in most categories, but highly impacted when composing methods, moving features between objects and organizing data. The measures that measure inheritance hierarchies are mostly affected when dealing with generalizations. The cohesion (CAM) measure, which is considered as an important measure to predict the quality of software, is impacted for only few refactorings when features are moved between objects. CIS measure is the only measure that is highly impacted for two categories. These two categories of refactoring target the methods in classes; therefore for future work, we plan to include more measures that measure

139

International Journal of Software Engineering and Its Applications Vol. 5 No. 4, October, 2011

quality at the method level. The results in Table 5 will be used in the validation part of the study. We use the two dimensions (high and low impacts) to find matches between the proposed heuristics and refactoring in real contexts. Table 5. The effect of refactoring heuristics on measures Refactoring Category Composing methods Moving features between objects Organizing data Simplifying conditional expressions Making method calls simpler

High Impact (measures impacted >50% of times) CIS, DCC DCC, CAM CIS, DCC, DSC , MOA CIS CIS

Low Impact (measures impacted

Suggest Documents