6
Removing Code Duplication with Roles Fernando Sérgio Barbosa * , Ademar Aguiar ** * Escola Superior de Tecnologia do Instituto Politécnico de Castelo Branco, Castelo Branco, Portugal ** INESC TEC and Departamento de Informática da Faculdade de Engenharia da Universidade do Porto, Porto, Portugal [email protected], [email protected] Abstract— The existence of replicated code in a system makes that system harder to maintain and evolve. To remove replicated code the usual way is to use refactorings. However there are always clones that cannot be removed by refactorings alone. Some are due to lack of composition mechanisms in the underlying programming language. We propose the use of roles to remove such clones since roles provide a finer degree of composition. We sketch four role refactorings to remove code clones and apply them in a case study using the JHotDraw framework. Results show that roles have a positive impact in clone reduction as they were able to remove almost all clones traditional refactorings could not. I. INTRODUCTION Code duplication is considered a bad smell and usually means that the system needs to be refactored [1]. However code duplication is present in many systems [2][3][4][5] [6]. It has negative effects in the system maintenance and evolution [3][6][7]. It also reduces code comprehensibility [8] and hints that there are design flaws [9]. There are several techniques and tools to identify code duplication [2][7], as well as many proposals on code clone removal [10][11][12]. Nevertheless, depending on the nature of the code, these tools and techniques are not always capable of removing all the replicated code. There are many reasons for the occurrence of clones [6] [7], one of them is crosscutting concerns - concerns that a class must deal with that are not its main concern. When several classes deal with the same concern they tend to use similar code. These clones could be avoided if we had a composition mechanism where a class is composed from other software constructs. Several proposals exist: mixins [13], traits [14], features [15], aspects [16] and roles [17][18][19]. We propose the use of roles to reduce the clones that traditional clone removal techniques cannot. There are many definitions of roles [19][20][21] but we use the role definition used by Riehle [18] and supported by the JavaStage language [22]. We use roles to compose classes so an object’s behavior is defined by the composition of all roles it plays. To study how roles are able to reduce code replication we will use them in the JHotDraw framework. We identify code clones using a clone detection tool and then try to remove them using traditional approaches. The remaining clones are then removed by using roles. For those types of clones that are removable by roles we show how they are removed. The paper is organized as follows: In Section II we discuss some clone related issues. Section III is dedicated to present the role approach. The case study system and its clones are presented in section IV. We present our roles refactorings in section V and section VI shows the results of applying it to the case study. Section VII describes related work and Section VIII concludes the paper. II. CODE REPLICATION It is common for developers to copy-paste code and modify it to fit a new purpose. The result is that several code blocks will be identical or very similar. Developers often do this because it provides a faster development time but in time it will backfire. With code replication a system is more difficult to maintain and more error prone [3][6]. The importance of detecting code clones led to the development of several clone detection techniques: Line- based [7]; Token-based [4]; Abstract Syntax Tree based [6]; Metric based [2][3]. For further details on these techniques we refer to [9]. A. Code Clones Elimination We can eliminate code clones by better design [23] or refactoring [1][10][11]. There are several tools to assist in clone removal [24] and most use these refactorings: Extract Method. We put a block of code in a method and call it whenever the code is repeated. This requires the block to belong to the same class. It can be used as a pre- step for techniques that use method granularity. Pull Up Method. Move a method to a superclass if it is repeated in its subclasses. It requires classes to have a common superclass and that we are able to modify it. Extract Superclass: Create a superclass when classes have identical code but are not related. The code is then inherited by the subclasses and not repeated. It requires the classes not to have any superclass. Extract Class: If classes have repeated code but each has it own superclass then the replicated code is extracted to a new class. This class will be used by the original classes. This requires the original classes to provide delegation methods to an object of the new class. B. Origins Clones may appear in a system due to a variety of reasons [6][7], but we will only discuss those relevant to our approach. For further reading we refer to [9]. Copy-paste, with or without modifications, is the most common way of duplicating code. It provides a faster development time and the use of proven code. Language limitations, like not supporting multiple inheritance, also contribute to duplicated code. Reusable code requires an additional effort and some find it simpler to maintain a set of clones than to develop a 37 SoMeT 2013 • 12th IEEE International Conference on Intelligent Software Methodologies, Tools and Techniques • September 22-24, 2013, Budapest, Hungary 978-1-4799-0421-1/13/$31.00 ©2013 IEEE

[IEEE 2013 IEEE 12th International Conference on Intelligent Software Methodologies, Tools and Techniques (SoMeT) - Budapest, Hungary (2013.09.22-2013.09.24)] 2013 IEEE 12th International

  • Upload
    ademar

  • View
    214

  • Download
    2

Embed Size (px)

Citation preview

Page 1: [IEEE 2013 IEEE 12th International Conference on Intelligent Software Methodologies, Tools and Techniques (SoMeT) - Budapest, Hungary (2013.09.22-2013.09.24)] 2013 IEEE 12th International

Removing Code Duplication with Roles

Fernando Sérgio Barbosa*, Ademar Aguiar** * Escola Superior de Tecnologia do Instituto Politécnico de Castelo Branco, Castelo Branco, Portugal

** INESC TEC and Departamento de Informática da Faculdade de Engenharia da Universidade do Porto, Porto, Portugal

[email protected], [email protected]

Abstract— The existence of replicated code in a system

makes that system harder to maintain and evolve. To

remove replicated code the usual way is to use refactorings.

However there are always clones that cannot be removed by

refactorings alone. Some are due to lack of composition

mechanisms in the underlying programming language. We

propose the use of roles to remove such clones since roles

provide a finer degree of composition. We sketch four role

refactorings to remove code clones and apply them in a case

study using the JHotDraw framework. Results show that

roles have a positive impact in clone reduction as they were

able to remove almost all clones traditional refactorings

could not.

I. INTRODUCTION

Code duplication is considered a bad smell and usually means that the system needs to be refactored [1]. However code duplication is present in many systems [2][3][4][5] [6]. It has negative effects in the system maintenance and evolution [3][6][7]. It also reduces code comprehensibility [8] and hints that there are design flaws [9].

There are several techniques and tools to identify code duplication [2][7], as well as many proposals on code clone removal [10][11][12]. Nevertheless, depending on the nature of the code, these tools and techniques are not always capable of removing all the replicated code.

There are many reasons for the occurrence of clones [6] [7], one of them is crosscutting concerns - concerns that a class must deal with that are not its main concern. When several classes deal with the same concern they tend to use similar code. These clones could be avoided if we had a composition mechanism where a class is composed from other software constructs. Several proposals exist: mixins [13], traits [14], features [15], aspects [16] and roles [17][18][19]. We propose the use of roles to reduce the clones that traditional clone removal techniques cannot.

There are many definitions of roles [19][20][21] but we use the role definition used by Riehle [18] and supported by the JavaStage language [22]. We use roles to compose classes so an object’s behavior is defined by the composition of all roles it plays.

To study how roles are able to reduce code replication we will use them in the JHotDraw framework. We identify code clones using a clone detection tool and then try to remove them using traditional approaches. The remaining clones are then removed by using roles. For those types of clones that are removable by roles we show how they are removed.

The paper is organized as follows: In Section II we discuss some clone related issues. Section III is dedicated to present the role approach. The case study system and its

clones are presented in section IV. We present our roles refactorings in section V and section VI shows the results of applying it to the case study. Section VII describes related work and Section VIII concludes the paper.

II. CODE REPLICATION

It is common for developers to copy-paste code and modify it to fit a new purpose. The result is that several code blocks will be identical or very similar. Developers often do this because it provides a faster development time but in time it will backfire. With code replication a system is more difficult to maintain and more error prone [3][6].

The importance of detecting code clones led to the development of several clone detection techniques: Line-based [7]; Token-based [4]; Abstract Syntax Tree based [6]; Metric based [2][3]. For further details on these techniques we refer to [9].

A. Code Clones Elimination

We can eliminate code clones by better design [23] or refactoring [1][10][11]. There are several tools to assist in clone removal [24] and most use these refactorings:

Extract Method. We put a block of code in a method and call it whenever the code is repeated. This requires the block to belong to the same class. It can be used as a pre-step for techniques that use method granularity.

Pull Up Method. Move a method to a superclass if it is repeated in its subclasses. It requires classes to have a common superclass and that we are able to modify it.

Extract Superclass: Create a superclass when classes have identical code but are not related. The code is then inherited by the subclasses and not repeated. It requires the classes not to have any superclass.

Extract Class: If classes have repeated code but each has it own superclass then the replicated code is extracted to a new class. This class will be used by the original classes. This requires the original classes to provide delegation methods to an object of the new class.

B. Origins

Clones may appear in a system due to a variety of reasons [6][7], but we will only discuss those relevant to our approach. For further reading we refer to [9].

Copy-paste, with or without modifications, is the most common way of duplicating code. It provides a faster development time and the use of proven code. Language limitations, like not supporting multiple inheritance, also contribute to duplicated code.

Reusable code requires an additional effort and some find it simpler to maintain a set of clones than to develop a

37

SoMeT 2013 • 12th IEEE International Conference on Intelligent Software Methodologies, Tools and Techniques • September 22-24, 2013, Budapest, Hungary

978-1-4799-0421-1/13/$31.00 ©2013 IEEE

Page 2: [IEEE 2013 IEEE 12th International Conference on Intelligent Software Methodologies, Tools and Techniques (SoMeT) - Budapest, Hungary (2013.09.22-2013.09.24)] 2013 IEEE 12th International

fully reusable, but more complex, solution. Time limits may force the copy-paste solution. Another factor is the poor comprehension of a system by a developer. In such cases he tends to copy existing code and then modify it, often in a tentative way, to implement a similar feature.

The use of design patterns [28] also contribute to code clones as they offer a solution to similar problems and tend to be implemented in the same way by different programmers. A developer may also reuse a solution he has already used in another system without realizing it.

C. Types of Clones

Roy and Cordy [9] use 4 clone categories: Type I - Similar code fragments, except layout and comments; Type II - Structurally similar code segments with differences in identifiers, literals or types; Type III - Clones with added, removed or changed statements. They may have differences in identifiers, literals and types; Type IV - Fragments have the same functionality but the code is different.

These types are useful for clone categorization but some kinds of clones that cannot be removed by refactorings fall into the same type. When necessary, we will add other clone descriptions to better identify clones.

III. ROLES

There are several definitions of roles [19][20][21]. They have been used in dynamic situations [25][26], system modeling [17][18], and relationship modeling [27].

We use roles as a building block we can use to compose classes. Roles provide the behavior for those concerns that the classes must deal but which are not its main concern. This way those concerns are better modeled and more reusable. To support roles we developed JavaStage, a Java extension that supports static roles [22]. This paper does not intend to present JavaStage. For more information see [22]. We will refer here only those characteristics that are important for the rest of the paper.

A. JavaStage in a Nutshell

1) Declaring and playing roles A role may define methods, fields and access levels. To

play a role the class uses a plays directive and gives the role an identity, as shown in Fig. 1. To access role members the class uses this identity. A class can play any number of roles, and can even play the same role more than once. When a class plays a role the non private methods of the role are added to the class.

Fig. 1 shows a role representing a subject for the Observer pattern [28] and a AbstractFigure class playing that role. The AbstractFigure notifies its observers whenever it changes.

A role may require the player or other types to have specific methods. These methods are stated in a requirement list (see an example in the role from Fig. 2). Each list entry specifies the type that must supply the method and the method’s signature.

2) Renaming methods Role methods are tuned for a collaboration and a good

method name for one collaboration can be inadequate for a similar collaboration. To overcome this we developed a renaming mechanism. Each name may have three parts:

one configurable and two fixed. The configurable part is bounded by # as shown next.

fixed#configurable#fixed

We show this mechanism in Fig. 2. The figure shows the generalization of the subject role from Fig. 1, which we reused in JHotDraw. The name configuration is done by the class playing the role in the plays clause. To play the role the class must define all configurable methods, as shown in Fig. 2.

Using this configuration the class would have an addFigureObserver and a fireFigureChanged method. The fireFigureChanged method would call the figureChanged method. The figure also shows that roles can inherit from other roles. We developed a Container role that provides

role FigureSubject {

Vector<FigureObserver> observers =

new Vector<FigureObserver>();

void addFigureObserver( FigureObserver o){

observers.add( o );

}

void removeFigureObserver(FigureObserver o){

observers.remove( o );

}

protected void fireFigureChanged( ){

for( FigureObserver o: observers ) o.update();

}

}

class AbstractFigure implements Figure {

plays FigureSubject figureSbj;

void moveBy(int dx, int dy) {

// code for moving the figure

// firing change, using role identity

figureSbj.fireFigureChanged();

}

}

Figure 1. A role and a class playing the role.

public role Container<T> {

private List<T> content;

public Container(){content = new Vector<T>();}

public Container( List<T> store ){

content = store;

}

void add#Thing#( T t ){ content.add( t );}

public void remove#Thing#( T t ){

content.remove( t );

}

}

public role Subject<ObserverType,EventType>

extends Container<ObserverType> {

requires ObserverType implements

void #Fire.notify#( EventType event );

public Subject() { super(); }

public Subject( List<ObserverType> store ){

super( store );

}

public void fire#Fire#( EventType e ){

for( ObserverType o : observers )

o.#Fire.update#( e );

}

}

public class AbstractFigure implements Figure {

plays Subject<FigureObserver,FigureEvent>(

Fire= FigureChanged,

Fire.update= figureChanged,

Thing = FigureObserver ) figureSbj;

}

Figure 2. The generalized subject role inheriting from a container role and the AbstractFigure playing that role. Name configurations in bold.

F. Barbosa and A. Aguiar• Removing Code Duplication with Roles

38

Page 3: [IEEE 2013 IEEE 12th International Conference on Intelligent Software Methodologies, Tools and Techniques (SoMeT) - Budapest, Hungary (2013.09.22-2013.09.24)] 2013 IEEE 12th International

the behavior of a container and made our Subject role inherit from it.

3) Multiple method versions It’s possible to declare several versions of a method by

using multiple definitions of the configurable name. For example we can expand the figure observer to include several update methods, not just figureChanged. We can provide figureMoved, figureChanged, figureRemoved, etc. We would write the plays clause as plays Subject<FigureObserver,FigureEvent> (

Fire=FigureChanged, Fire.update= figureChanged,

Fire= FigureMoved, Fire.update= figureMoved,

Fire=FigureRemoved, Fire.update= figureRemoved,

Thing = FigureObserver ) figureSbj;

IV. DETECTING CLONES

To explore how roles can reduce code clones we conducted an experiment using the JHotDraw Framework.

JHotDraw is a Java GUI framework for technical and structured graphics. It defines the basic structure for a GUI-based editor with tools in a tool palette, different views and user-defined graphical figures. This framework has been used in various aspect mining works.

We used CCFinder [4], a token-based clone detection tool, to detect clones. CCFinder detects Type I and Type II clones and can be used to detect type III clones with some manual work. Type IV clones are not detected. We used the standard options of CCFinder in our study.

We accepted only clones that appeared in, at least, two files. This reduces the number of clones removable by traditional refactorings. We rejected false clones and clones that used deprecated code.

We manually inspected all detected clones to identify the concern each dealt with. We grouped clones according to its concern. This grouping helped us deciding which roles we should develop. Results are shown in table 1.

TABLE I. CLONE DETECTION RESULTS

Clones Concerns

Initial 146 Initial 41 Ignored 44 Refactored 2 Final 102 Considered 39

The next step was to remove clones using traditional refactorings. After this we identified those clones which could not be removed, or where roles would provide a better solution. We organized these clones into 4 categories: Identical clones in classes with different superclasses; Clones that have identical structures but use different, unrelated, types; Clones with the same structure and types but use different methods; Clones with the same structure that use different types and methods names. Due to space reasons, we will present these types with simplified examples and not actual code from JHotDraw.

A. Identical clones in classes with different superclasses

These clones have identical code but the classes they appear in have different superclasses. An example is shown in Fig. 3. We could have used Extract Superclass if classes didn’t have different superclasses. We could use Extract Class, but it requires classes to create forward methods to the new class. Our role solution seems to be better, as we will explain later.

B. Clones that have identical structure but use different,

unrelated, types

We’ve found clones that have the same structure, but use different types. If the types are unrelated and we cannot refactor them to make them related then we cannot refactor the clone either. An example is shown in Fig. 4.

C. Clones with the same structure and types but use

different methods

These clones cannot be easily resolved by refactoring. They have methods with the same structure and types but have different names and/or call different methods. To resolve these clones we would need to refactor methods’ names in order to uniform their names, but that is not always possible or desirable. In Fig. 5 we show an example of such a clone.

D. Clones with the same structure that use different

types and methods names

These clones have the same structure but the types, methods’ names, and called methods’ names are all different. Such clones cannot be resolved using any technique in the refactoring catalog. One example is the observer pattern where subjects must store observers and inform them of changes. The observer types are different between subjects and so are the names used for the notification of changes. Nevertheless the underlying code is basically the same.

public class ClassOne extends SuperOne {

private Button selected;

void doSomething( Button bt ){

setTool( bt.getTool(), bt.getName() );

setSelected( bt );

}

void doOtherThing( Button bt, boolean in ){

if( in ) showStatus( bt.getName() );

else showStatus( seleted.getName() );

}

void setSelected( Button bt ){ selected = bt;}

Button getSelected( ) { return selected; }

// ... rest of class code

}

public class ClassTwo extends SuperTwo {

/* same methods as the previous */

}

Figure 3. Example of a clone in classes that have different superclasses.

public class ClassOne {

void doSomething( TypeOne x ){

if( !x.isSelected() ){

x.setSeleted( true );

x.setName( getName() );

}

x.start( );

}

}

public class ClassTwo {

void doSomething( TypeTwo x ){

if( !x.isSelected() ){

x.setSeleted( true );

x.setName( getName() );

}

x.start( );

}

}

Figure 4. Example of a clone in classes that use different types.

39

SoMeT 2013 • 12th IEEE International Conference on Intelligent Software Methodologies, Tools and Techniques • September 22-24, 2013, Budapest, Hungary

Page 4: [IEEE 2013 IEEE 12th International Conference on Intelligent Software Methodologies, Tools and Techniques (SoMeT) - Budapest, Hungary (2013.09.22-2013.09.24)] 2013 IEEE 12th International

V. REMOVING CLONES WITH ROLES

To handle the unsolved clones categories we propose these refactorings: Extract Role; Extract Role Changing Types, Extract Roles with Configurable Methods; Extract Role with Types and Methods. They are similar but we use four instead of one with several options to have a one-to-one map between clone categories and refactorings. The refactorings complete description is not possible in this paper so we will present only the guidelines for each.

A. Extract Role

This refactoring can be applied to the category identical clones in classes with different superclasses. The mechanics is simple: Create a role with a name that indicates the concern it deals with; Copy the cloned code into the role (including fields). If the cloned code uses methods of the class add a requires statement for each method. Make the classes play the role.

A solution for the clone of Fig. 3 is shown in Fig. 6.

We suggest that most clones that could use Extract Class should use this solution instead. This way classes do not need to create delegation methods, just play the role.

To decide between the two consider the nature of the code. If it represents a standalone concept it should be put in a class, if it represents a partial concept it should be put in a role.

This solution could also be used instead of Extract Superclass. Again the decision is based on what the code represents. If the concept is better modeled by a class then Extract Superclass should be used. If the concept is better modeled by a role Extract Role should be used.

B. Extract Role Changing Types

We apply this to clones that have identical structure but use different, unrelated, types. We suggest the following mechanics: Create a role with a name that indicates its concern; Identify the different types used by the code that cannot be replaced by a common type; Copy the code using a generic for each different type; If the role uses methods from the types or from the classes add each method to a requires statement. Make the classes play the role configuring the role for their specific types.

Using this refactoring we can remove the clone identified in Fig. 4 as depicted in Fig 7.

C. Extract Role with Configurable Methods

This refactoring is for those clones with the same structure and types but use different methods. It uses the renaming mechanism of JavaStage. Its mechanic is: Create a role with a name that indicates its concern; Identify the methods that have different names; Copy the methods to the role marking the identified methods for configuration, taking advantage of naming patterns to reduce the amount of configurations to use; If the role uses methods of the class add a requires statement for each method. If the role uses a configurable method of another type add it to the requires list as well.

Fig. 8 shows how to remove the clone from Fig. 5 using this refactoring

D. Extract Role with Types and Methods

This refactoring uses all JavaStage features. It is used for clones that have the same structure but use different types and methods names. Its mechanics are: Create a role with a name that indicates the concern it deals with; Identify the different types used by the code that cannot be replaced by a common type; Identify the methods that

class ClassOne {

private Set<String> selectedOnes;

boolean isSelected( String name ){

return selectedOnes.contains( name );

}

boolean isSelectable(String name, String key){

if( !isSelected( name ) ) return false;

if( !isSelected( key ) ) return false;

return checkSelectable( name, key );

}

}

class ClassTwo {

private Set<String> ignoredOnes;

boolean isIgnored( String name ){

return ignoredOnes.contains( name );

}

boolean isIgnorable(String name, String key ){

if( !isIgnored( name ) ) return false;

if( !isIgnored( key ) ) return false;

return checkIgnorable( name, key );

}

}

Figure 5. Example of a clone that uses same types but different methods (in bold).

public role SelectingButton {

private Button selected;

void doSomething( Button bt ){

setTool( bt.getTool(), bt.getName() );

setSelected( bt );

}

void doOtherThing( Button bt, boolean in ){

if( in ) showStatus( bt.getName() );

else showStatus( seleted.getName() );

}

void setSelected( Button bt ){ selected = bt;}

Button getSelected( ) { return selected; }

}

public class ClassOne extends SuperOne {

plays SelectingButton selBt;

}

public class ClassTwo extends SuperTwo {

plays SelectingButton selBt;

}

Figure 6. Example of a clone in classes that have different superclasses.

public role Selecting<Type> {

requires Type implements boolean isSelected();

requires Type implements

void setSelected( boolean s );

requires Type implements

void setName( String n );

requires Type implements void start();

void doSomething( TypeOne x ){

if( !x.isSelected() ){

x.setSeleted( true );

x.setName( getName() );

}

x.start( );

}

}

public class ClassOne {

plays Selecting<TypeOne> selec;

}

public class ClassTwo {

plays Selecting<TypeTwo> selec;

}

Figure 7. Proposed solution for the example clone from Fig. 4.

F. Barbosa and A. Aguiar• Removing Code Duplication with Roles

40

Page 5: [IEEE 2013 IEEE 12th International Conference on Intelligent Software Methodologies, Tools and Techniques (SoMeT) - Budapest, Hungary (2013.09.22-2013.09.24)] 2013 IEEE 12th International

have different names. Copy the methods to the role marking the identified methods for configuration, taking advantage of naming patterns to reduce the amount of configurations, and using a generic for each different type; If the role uses methods of the class add a requires statement for each method. If the role uses methods of another type add it to the requires list as well.

The subject role presented in Fig. 2 is a good example. It shows that roles can be used to build code generic enough to be reused in many different situations.

VI. RESULTS

After analysis of the clones from JHotDraw we counted the clones that were removed with traditional refactorings and those removed using each of the proposed role refactorings. We also counted the clones still unsolved. These results are presented in table 2.

A. Discussion

The first observation we can make is that the number of concerns that could be resolved with traditional refactorings is low. The clones that used Extract Role could also use Extract Class or even Extract Superclass but roles were always a better solution (code length and modeling).

We can also observe that the number of unresolved concerns is relatively low (8 in 38 or 21%). But they can be easily explained and derives from the fact that we considered as clones some that could be considered false clones. They are clones in the structure and not on the code itself. A “creating undo activity” concern creates an undo activity object for each tool and command supported by the framework. Each has an UndoActivity inner class thus all the inner classes constructors have similar structures and were marked as clones. Each tool class also has a method that creates an undo activity. Since this method is somewhat similar, it was marked as a clone too.

We opted to maintain this code as clones because they dealt with the same concern.

Another example is persistence: figures are streamed so they all have a write and read method with similar structures, but not identical code. Our role DisplayBoxed considerably reduced this duplicated code. In another

concern the clone method overrides the superclass method for performance issues that we failed to understand.

TABLE II. CLONE REMOVAL RESULTS

Concerns Refactoring Used

Considered 38 ER 18 Solved 30 (79%) ERCT 2 Unsolved 8 (21%) ERCM 2

ERTM 9

Code Statistics

Original Clone LOC 1390 Final Clone LOC 883 Size reduction 36,5% Roles with less LOC 27 Roles with more LOC 2 Roles with same LOC 1 Concerns better with roles 90,0%

ER = Extract Role, ERCT = Extract Role Changing Types, ERCM = Extract Role with Configurable Methods, ERTM = Extract Role with Types and Methods

Three clones could use roles but their configuration would be complex and since clones had, at most, 4 simple lines of code, we did not develop a role.

From this discussion we can see that roles could remove almost all the clones and the ones it didn’t resolve were too small or could be counted as not real clones.

Using roles to remove code clones does not mean that our solution is easier to understand and develop than using clones. We do believe that all roles we developed contributed to a better system. Deciding if the system is better with or without roles is outside the scope of this paper. We intended to show that roles could remove clones and we did so. We can say that a system without clones is very likely to be a better system. Studies must be made to assess systems with roles are easier to maintain/evolve than without roles.

VII. RELATED WORK

Works on clones are abundant in the literature, from detecting clones [2][3][4][6][7] to removing clones [10] [11][12], but none is dedicated to removing clones with roles. In role related work there aren’t any studies that deal specifically with code clones.

Dynamic role approaches, like ObjectTeams [25] and CaesarJ [26], use Aspect Oriented Programming (AOP) features and could use some AOP refactorings [29] to remove clones, but no study on this has yet appeared.

Mixins [13] and traits [14] are somewhat similar. In traits, however, the order of composition is irrelevant. Traits provide a set of methods that are added to the class when it uses the trait. The class must also provide glue code in order to compose the several traits. In traits a class can be seen indifferently as a collection of methods or as composed by traits: the trait’s flattening property. In roles a class can also be seen as a whole or as composed by roles. Traits cannot inherit from other traits, like roles can inherit from other roles, but a trait can use other traits.

There is no study on code removal using traits. We can, however, think of a trait as a role without state and no configurable methods. Using this analogy we expect that traits may use Extract Role and even some of the Extract Role with Configurable Methods if the configurable methods belong to the trait. The state handling code, however, would have to be replicated so roles provide a better solution even in these cases.

public role Decider {

private Set<String> theOnes;

boolean is#Action#( String name ){

return theOnes.contains( name );

}

boolean is#Actionable#(String name,String key){

if( !is#Action# ( name ) ) return false;

if( !is#Action# ( key ) ) return false;

return check#Actionable#( name, key );

}

}

class ClassOne {

plays Decider( Action = Selected,

Actionable = Selectable

) selecter;

}

class ClassTwo {

plays Decider( Action = Ignored,

Actionable = Ignorable

) selecter;

}

Figure 8. Proposed solution for the example clone from Fig. 5.

41

SoMeT 2013 • 12th IEEE International Conference on Intelligent Software Methodologies, Tools and Techniques • September 22-24, 2013, Budapest, Hungary

Page 6: [IEEE 2013 IEEE 12th International Conference on Intelligent Software Methodologies, Tools and Techniques (SoMeT) - Budapest, Hungary (2013.09.22-2013.09.24)] 2013 IEEE 12th International

Feature Oriented Programming (FOP) decomposes systems into features [15]. The features reflect user requirements and refine each other in a step-wise manner. FOP is mainly used for SPL and program generators. Features are often implemented using Mixin layers [30]. Each mixin layer contains the code for a given feature and classes compose them. Roles can successfully replace mixins because they offer more configuration possibilities.

In [31] Schulze et al studied the impact of FOP on code duplication. The authors found that while FOP does remove some kind of clones it also introduced FOP related clones. Once again the use of roles to implement the features would be useful because many of their reported clones were of Type I and Type II with few differences and roles deal with those quite well.

VIII. CONCLUSIONS AND FUTURE WORK

Code replication is a major problem in software systems so its elimination is an important issue. We proposed roles as a way to minimize this problem.

First we analyzed the JHotDraw framework and identified the clones present. We removed the ones we could remove by using traditional refactorings and reached the conclusion that those are insufficient to tackle the problem. We catalogued the types of clones that could not be removed and presented a refactoring to remove each type using roles.

The results from using our approach show that roles with its finer degree of composition and features like method renaming and stating of requirements from players and other collaborators can reduce the duplicated code to a minimum.

In future work we intend to formalize our role refactorings following the format present in [1]. We also want to asses if removing code clones using roles have a real impact in the maintenance and evolution of a system as expected.

REFERENCES

[1] M. Fowler. Refactoring – Improving the Design of Existing Code. Addison Wesley, 2000.

[2] K Kontogiannis. Evaluation experiments on the detection of programming patterns using software metrics. In Proc. of Working Conference on Reverse Engineering, 1997.

[3] J. Mayrand, C. Leblanc, and E. Merlo. Experiment on the Automatic Detection of Function Clones in a Software System Using Metrics. In Proc. of the International Conference on Software Maintenance, IEEE Computer Society Press, 1996.

[4] T. Kamiya, S. Kusumoto, and K. Inoue. Ccfinder: A multilinguistic token-based code clone detection system for large scale source code. In Transactions on Software Engineering 8(7), pages 654–670. IEEE Computer Society Press, 2002.

[5] B. S. Baker. A Program for Identifying Duplicated Code. In Proceedings of Computing Science and Statistics: 24th Symposium on the Interface, Vol. 24:4957, March 1992.

[6] I. Baxter, A. Yahin, L. Moura, M. Sant’Anna, and L. Bier. Clone Detection Using Abstract Syntax Trees. In Proc. of the Int. Conf. on Software Maintenance. IEEE Computer Society, 1998.

[7] R. Geiger, B. Fluri, H. C. Gall and M. Pinzger. Relation of code clones and change couplings. In Proce. of the 9th International Conference of Fundamental Approaches to Software Engineering (FASE'06), pp. 411-425, Vienna, Austria, March 2006

[8] S. Giesecke. Generic modelling of code clones. In Proceedings of Duplication, Redundancy, and Similarity in Software, ISSN 16824405, Dagstuhl, Germany, July 2006.

[9] C. Roy and J. Cordy. A Survey on Software Clone Detection Research. Technical Report 2007-451, School of Computing, Queen’s University at Kingston, 2007.

[10] R. Fanta, V. Rajlich. Removing Clones from the Code. Journal of Software Maintenance: Research and Practice, Volume 11(4):223-243, August 1999.

[11] R. Komondoor and SS Horwitz. Semantics-Preserving Procedure Extraction. In Proceedings of the 27th Symposium on Principles of Programming Languages (POPL'00), Boston, MA, USA, 2000.

[12] F. Rysselberghe, S. Demeyer. Evaluating Clone Detection Techniques from a Refactoring Perspective. In Proc. of the 9th IEEE International Conference on Automated Software Engineering. (ASE'04), pp. 336-339, Linz, Austria, 2004.

[13] G. Bracha, and W. Cook. Mixin-Based Inheritance. In Proc. of the Conference on Object-Oriented Programming: Systems, Languages, and Applications / European Conference on Object-Oriented Programming, 1990. Ottawa, Canada. ACM Press.

[14] S. Ducasse, N. Schaerli, O. Nierstrasz, R. Wuyts and A. Black: Traits: A mechanism for fine-grained reuse. In Transactions on Programming Languages and Systems. 2004.

[15] S. Apel and C. Kästner. An Overview of Feature-Oriented Software Development, in Journal of Object Technology, vol. 8, no. 5, July–August 2009,pages 49–84

[16] G. Kiczales, E. Hilsdale, J. Hugunin, M. Kersten, J. Palm, W.G. Griswold. An overview of AspectJ. In proceedings of ECOOP 2001, Budapest, Hungary, (LNCS, vol. 2072), Springer; 2001

[17] B.B. Kristensen. Object-oriented modeling with roles, in Proceedings of the 2nd International Conference on Object-Oriented Information Systems, 1995, Springer-Verlag, pp. 57–71.

[18] D. Riehle Framework Design: A Role Modeling Approach, Ph. D. Thesis, Swiss Federal Institute of technology, Zurich. 2000

[19] K.B. Graversen: The nature of roles - A taxonomic analysis of roles as a language construct, Ph. D. Thesis, IT University of Copenhagen, Denmark, 2006

[20] B.B. Kristensen and K. Østerbye. Roles: Conceptual abstraction theory & practical language issues, Theory and Practice of Object Systems 2(3): 143–160. 1996

[21] F. Steimann. On the representation of roles in object-oriented and conceptual modeling. Data & Knowledge Engineering 35(1). 2000

[22] Barbosa, S. and Aguiar, A. (2012). Modeling and Programming with Roles: Introducing JavaStage, In Proc. of International Conference on Intelligent Software Methodologies tools and Techniques, (SoMeT12), Genoa, Italy, 2012.

[23] B. S. Baker. On Finding Duplication and Near-Duplication in Large Software Systems. In Proc. of the Work. Conf. on Reverse Engineering, pages 86–95. IEEE Computer Society, 1995.

[24] Y. Higo, T. Kamiya, S. Kusumoto, Katsuro Inoue. Aries: Refactoring Support Environment based on Code Clone Analysis. In Proc. of the 8th IASTED International Conference on Software Engineering and Applications, Cambridge, MA, USA, 2004.

[25] S. Herrmann. Programming with Roles in ObjectTeams/Java. AAAI Fall Symposium: "Roles, An Interdisciplinary Perspective". 2005.

[26] M. Mezini and K. Ostermann. Conquering Aspects with Caesar. In Proc. of AOSD 2003.

[27] S. Nelson, D.J. Pearce and J. Noble. Implementing First Class Relationships in Java. In Proceedings Workshop on Relationships and Associations in Object-Oriented Languages at OOPSLA 2008.

[28] E. Gamma, R. Helm, R. Johnson and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley. 1995

[29] M. Monteiro and J. Fernandes. Towards a Catalog of Aspect-Oriented Refactorings. In Proc. Int. Conf. on Aspect-Oriented Software Development, pages 111–122. ACM Press, 2005.

[30] Y. Smaragdakis and D. Batory. Mixin Layers: An Object-Oriented Implementation Technique for Refinements and Collaboration-Based Designs. ACM TOSEM, 11(2). 2002.

[31] S. Schulze, S. Apel, and C. Kästner. Code Clones in Feature-Oriented Software Product Lines. In Proc. of the 9th International Conference on Generative Programming and Component Engineering (GPCE), Eindhoven, The Netherlands, 2010.

F. Barbosa and A. Aguiar• Removing Code Duplication with Roles

42