Refactoring Design Patterns from Object-Oriented to Aspect-Oriented in Eclipse Daniele Contarino University of Catania Viale A. Doria 6, 95125 Catania, Italy daniele.contarino@studium.unict.it Abstract—Nowadays, Aspect-Oriented programming is used benefits of the latter one, can be a very long and expensive for industrial software systems. However, many useful Object- job. It could also produce human-related mistakes. Therefore, Oriented systems have been developed and are still in use and several approaches have been proposed to assist refactoring a manual porting of big projects from Object-Oriented (OO) paradigm to Aspect-Oriented (AO) one, making the most of systems, from detecting the portions of code that need to be Design Patterns (DP), may prove a costly and time-consuming improved [8]–[11], to carry out some transformation on the process. This paper proposes a practical approach for auto- code [12], [13]. Moreover, extensive research work has been matically converting OO code to AO code, specifically for the performed for identifying design patterns [14], [15], which in implementation of DPs. The solution comprises two essential turn can help understand and improve the code. steps: recognition of the DP in OO code and conversion into AO code. Then, two examples of DP Singleton and Composite This paper proposes to assist finding the portions of code implementations on the Eclipse IDE with Eclipse Java Develop- that can be refactored and to transfom such found portions. ment Tools (JDT) are given. This allows us to save time and reduce errors, requiring human Index Terms—Design Patterns, Aspect-Oriented programming, intervention only for custom DPs. Given a software project, Recognition, Code replace, Separation of concerns our idea would be to have a tool able to: • Recognise the used DPs; I. I NTRODUCTION • Identify the classes the DP implements; Design Patterns are an essential resource for developing • Create the aspects related with the found DP; software systems of any size. The Design Patterns (DPs) are • Delete the DP features from the OO version of the code the result of several years of fieldwork by senior software and make appropriate changes to transform the code. engineers. They allow us to save time when designing an Therefore, a tool has been implemented with the said goals. application. However, many DPs have some crosscutting code The chosen development environment is Eclipse; this choice (e.g. DP Observer) or inject code in a different concern (e.g. was motivated both for its widespread use in the enterprise DP Singleton). Aspect-Oriented programming [1] solves the environments and its internal flexible support. This allows crosscutting code problem by moving such a code in separate building plugins that can easily perform parsing, checking and modules or aspects. A concern is a specific concept or goal; changing of the existing application code. the concerns can be domain or core concerns. Usually, in The use of aspects, hence the substantial replacement of OO programming the core concerns are represented by main crosscutting code, helps us to separate the domain concerns classes, then there are other non-domain or system concerns. (business logic) from non-domain concerns (DP logic). How- In OO systems the latter concerns are crosscutting, while in ever, some metadata, as Java annotations used to tag the class AO systems they are aspects, as e.g. logging systems, user with the role for a specific DP will be used, as a kind of link session checker, etc. for the two parts. Design Patterns in AO systems [2]–[5] improve code reusability, reduce the software complexity, by extracting and II. BACKGROUND CONCEPTS AND TOOLS separating the business logic code and the DP feature or non- A. Design Patterns domain concerns [6], [7]. Furthermore, the AO versions of DPs are more reusable, since a single aspect can be used for Design patterns are as the developer “utility knives”. They all the application classes needing it, and reduce the lines of represent a set of best practices conceived by experienced OO code, both for the business logic and the DP portions. This software developers; and are solutions for general problems allows the developer to focus more on models and less on the that happen during the software development. DPs describe interactions between the classes. Moreover, the same aspect a given scenario. For example, Singleton DP lets us use a can be reused without changes on other software systems. single object in all the application; the developers know this Unfortunately, carrying out a refactoring from the OO to AO technique with the name Singleton, independently from the paradigm for medium or large software systems, for having the language and platform used. Learning DPs helps the unexpe- rienced developers to solve severals problems that otherwise Copyright c 2016 held by the authors. would require the help of a senior software engineer. 11 Each DP is described by: • IMethod represents a method; 1) name; • IField represents an attribute. 2) goal; III. DP R ECOGNITION AND CONVERSION PROCESS 3) occurring problem; 4) solution offered; A. Recognition 5) effects. The recognition of design patterns implemented inside a In 1994 one of the most widespread used DP collection Java software system is carried out by observing the OO was published by four authors (also called “Gang of Four”). features of a DP, hence looking for their typical “signature” in It describes 23 patterns divided in three categories: Creational, a software system. One of the most used techniques consists Structural and Behavioral patterns [16]. of analysing the classes and finding relationships such as implements or extends [15], [18], [19]. In this way we can B. Aspect-Oriented programming determine the class hierarchy and check whether it matches The Aspect-Oriented Programming is a programming that of a DP. Every DP has a typical structure and we propose paradigm that allows crosscutting concerns to be separated into to search for three features. Our recognition algorithm can modules called aspects [1]. We use in our project the AspectJ make use of the following. technology with Java [17]. In AspectJ, an aspect consists of • Match with known specific classes or interfaces. This • Join Point: is a point inside the application execution (e.g. technique is used for DP Observer search, i.e. one of the method invocation, method return, method execution, relevant application class has to implement the Observer object creation, exception, fields access). In this point it interface and another one has to inherit from the Observ- usually interferes a cross-cutting concern or rather the able class, which is included in the JDK standard library. aspect. Such a class and an interface are well known and can be • Pointcut: is the tool that selects the Join Point based by identified from the analysis of the application code. the context and the rule specified as the definition. • Match an interface with the classes that implement it. • Advice: like a method, it executes a code when a join Starting from a given application, we get all interfaces. point is selected by a pointcut. We observe where they are implemented and the behavior AspectJ is an extension for Java SDK. AspectJ is a prepro- of the classes that implement the same interface. In case cessor that integrates the cross-cutting concerns into Java code. of DP Composite it will be useful to get the list of It converts the Pointcuts and Advices into Object-Oriented classes that implement a given interface. We will check code before that the Java code is compiled in bytecode. if a specific class contains a list of attributes having as a type the same interface (a list of leafs). Other examples C. Eclipse JDT where this feature is used include: DP Factory Method Eclipse Java Development Tools (JDT) is a tool suite for and DP Abstract Factory: we search an interface that have developing Java applications that can manipulate Java source a method whose return type is another interface. code. For this reason, JDT is a fundamental package of Eclipse • Match some attributes and/or methods. Some DPs are IDE, and is used by several Eclipse plugins. characterized by the presence of some specific attributes JDT package is made of three items: Java Models, Search or properties concerning the methods (or the construc- Engine and Abstract Syntax Tree (AST). Our developed tool tors). E.g. DP Singleton has a private constructor, a is a plug-in that uses the Eclipse JDT for recognizing and private static attribute of the same type of the class editing the Java Eclipse projects and the Eclipse UI library for and a static method that returns an object of the same integrating with the IDE (context menu, message box, etc.). type of the class. A similar recognition can be done for Eclipse UI gave us the project in a Java Model represen- Flyweight, Proxy, Object Pool (with a single Creator, like tation. We then can create the handles that can be attached Singleton). to the context menu in the Package Explorer of Eclipse. The The recognition process can be optimized if, during the handles catch the selected project (as IJavaProject) and pass process, each class will collect all the useful features for it to our (individual) DP converter. identification. Within the Eclipse JDT library the following main classes More specifically, class SearchPattern has been used to have been used. perform searches. It takes as input a IJavaElement instance, • IWorkspace represents Eclipse workspace; (which is an Eclipse supertype for IJavaProject, IMethod, • IJavaProject represents a single Java project; IPackageFragment, IPackageFragmentRoot, IType) on which • IPackageFragmentRoot represents a collection of re- a search has to be performed, and an int representing the sources (e.g. a folder or a library); matching mode (e.g. we could be searching for the ini- • IPackageFragment represents a sub-package inside a tialisation of a reference or the use of a reference, in the project; method body). Class SearchRequestor holds found items, and • ICompilationUnit represents a file with Java source code; interface IJavaSearchScope define where the search should be • IType represents a class; performed. 12 B. Conversion OO to AO version. It holds an instance of AspectPrototype To convert OO design patterns into AO versions, we proceed to generate the correspondent aspect; an instance of IMethod in two stages: represents the constructor and another instance representing the getInstance() method typical of a Singleton. An instance of • Deleting the OO features related to the design patterns IField is also representative of the static attribute implemented and/or reshaping of classes, attributes and methods; in a Singleton class. The main methods implement the code • Creating the aspects. for finding an implementation of Singleton within a class, to After having recognized all the involved different classes of identify constructor and the static method, and to search and a project in Eclipse IDE, one or more “.aj” files implementing remove the invocation of static methods in classes using the the DP are generated. They customize some different fields Singleton. by using the class names. We use the Eclipse JDT to realize Class SingletonHandler gives the possibility to con- these stages. It allows us to write aspect code as simple text. nect the Eclipse environment with the proposed toolkit. It is Moreover, if we want to change an existing code we will use an implementation of IObjectActionDelegate interface, having a more powerful tool that is the Abstract Syntax Tree (AST). method run(), which will be called upon the click on the This one parses the Java code in a XML tree and vice versa. selected project. Such a class holds an instance representing This allows us to operate directly at the rows where we need the Eclipse shell, so that messages can be shown. The main the code changes. additional method is responsible to call the methods provided IV. P ROPOSED TOOLKIT by class SingletonModifier, in order to recognise and convert portions of code. We created a toolkit that provides us with support for rec- Class SingletonSearchEngine is a subclass of class ognizing and converting DPs. The main steps are as follows: AbstractSearchEngine and is used to find the calls to • Analysis of the existing code and search classes that static methods. implements a given DP; Class CompositeModifier recognises and converts DP • Creation of the object that will perform the conversion; Composite from OO version to AO version. It mainly holds • Creation of the aspects; an instance of AspectPrototype in order to generate • Changing the analysed code. and write an appropriate aspect, realising the AO version, a The toolkit declares the previous steps (abstract methods) reference to class playing as Component, a list of references and imposes them as a guide to the various refactoring. It for the classes playing as Child (Leaf) and the Composite. The applies the appropriate changes to the code. main methods implement the logic to search for application A. Implemented Classes classes implementing Composite DP. The following describes the main classes implementing V. R ECOGNITION RULES our toolbox. Class AspectPrototype supports the gen- A. Singleton DP eration of an aspect, and holds the name of the aspects The Singleton DP is a successful DP and developers are as well as the constituting portions, such as pointcuts, ad- using it regularly. Now, our application will be concerned vices, etc., and the name of the file and package hold- with the recognition and rewriting of the code, so that the ing the code. The main methods for building such por- AO version will be produced. In the recognition process, tions of code are: addAttribute(), addPointcut(), our algorithm consider three features that distinguish the DP addAdvice(), addMethod(), and the last three take as Singleton, as follows. input some strings representing name, parameters, and body. • It exists a single private constructor; Class AspectDesignerPattern is abstract and defines • it exists a public static method that returns some object the methods that have to be implemented to recognise and convert a DP. Such a class holds the name of the classes, having the same type as the hosting class; • it exists a private static attribute of the same type of the package, project, which have to be processed; moreover, it has methods searching features on the code, deleting portions hosting class. of the found code, and creating portions of the new code. The If a class satisfies the previous conditions, this will be repre- main steps performed are described in more detail below. sented as an instance of SingletonModifier, which implements • Method createAspect() creates a custom aspect for the the functionality of the abstract class AspectDesignerPattern. found class; uses AspectPrototype class having the inter- Code in Listing 1 shows the main steps of the identification. nal elements expected for an aspect (pointcuts, advice, Then, once the class has been identified, it is constructed the attributes, etc.) and writes the code in the .aj file into the relative aspect and replaced its code. In the end, the old parts indicated package. of a Singleton class are deleted, i.e. the attributes and methods • Method replaceCode() deletes and/or modify all the por- typical of the DP, and then the aj file is written. tions of code characterizing a given DP in OO paradigm. After conversion of a Singleton class MyClass, all calls like Class SingletonModifier is a specialisation for the namesake DP and recognises and convert a Singleton DP from MyClass uniqueObject = MyClass.getInstance(); 13 will be replaced by: Component interface as an attribute, and (ii) the Leaf MyClass uniqueObject = new MyClass(); class, as a class implementing the Component interface. As for Singleton recognition, if a group of classes imple- The client will see MyClass as a usual class (not a ment a specific interface that satisfies the previous conditions, Singleton DP), however all the instantiations return the same the interface and all classes recognized will be stored in an instance of MyClass. instance of CompositeModifier. public final class SingletonModifier extends Code in Listing 2 shows the implementation of the above. AspectDesignerPattern { public final class CompositeModifier extends private static IMethod getOnlyPrivateConstructor( AspectDesignerPattern { IMethod[] methods) throws JavaModelException { public static AspectDesignerPattern[] getDesignerPattern( int numOfPrivateConstructors = 0; IJavaProject prj) { int privateConstructorsIndex = -1; ArrayList leaves = new ArrayList(); for (int i=0; i < methods.length; i++) ArrayList composites = new ArrayList(); if (methods[i].isConstructor() && Vector compositeDP = new Vector(); Flags.isPrivate(methods[i].getFlags())) { Hashtable c=new Hashtable(); numOfPrivateConstructors++; if (prj == null) return null; privateConstructorsIndex = i; ArrayList listInterface = new ArrayList(); } IPackageFragment[] pks = prj.getPackageFragments(); if (numOfPrivateConstructors != 1) return null; for (IPackageFragment pack : pks) return methods[privateConstructorsIndex]; for (ICompilationUnit jf : pack.getCompilationUnits()) } for (IType classStub : jf.getTypes()) if (Flags.isInterface(classStub.getFlags())) private static IMethod getInstanceMethod( listInterface.add(classStub); IMethod[] methods, String className) throws AspectSearchEngine se = new AspectSearchEngine(prj); JavaModelException { for (IType intf : listInterface) { se.search(intf, IJavaSearchConstants.IMPLEMENTORS, for (int i=0; i < methods.length; i++) SearchPattern.R_ERASURE_MATCH | if (methods[i].getReturnType(). SearchPattern.R_CASE_SENSITIVE); compareTo("Q"+className+";") == 0 && Reference[] matches = se.getReferences(); Flags.isPublic(methods[i].getFlags()) && if (matches.length == 0) continue; Flags.isStatic(methods[i].getFlags())) Vector listType = new return methods[i]; Vector(Arrays.asList(se.getUsingType(matches))); return null; Iterator listTypeIterator = listType.iterator(); } while (listTypeIterator.hasNext()) { IType classStub = listTypeIterator.next(); private static IField getInstanceAttribute( boolean subjFound = false; IField[] fields, String className) throws IField[] attributes = classStub.getFields(); JavaModelException { for (IField a : attributes) if (Composite.isDynamicList(a.getTypeSignature(), for (int i=0; i < fields.length; i++) intf.getElementName())) { if (fields[i].getTypeSignature(). composites.add(classStub); compareTo("Q"+className+";") == 0 && listTypeIterator.remove(); Flags.isStatic(fields[i].getFlags())) c.put(classStub, a); return fields[i]; subjFound = true; return null; break; } } } if (!subjFound) { leaves.add(classStub); Listing 1. Methods inspecting the characteristics for Singleton DP listTypeIterator.remove(); } } B. Composite DP if (leaves.size() > 0) compositeDP.add(new Composite(prj, intf, The Composite DP allows developers to use a set of items composites, leaves, c)); } as a single object through the implementation of a common AspectDesignerPattern[] adp = new interface. Every object can be a node (the element have a AspectDesignerPattern[compositeDP.size()]; compositeDP.toArray(adp); pointer to another Composite object) or a leaf (object that return adp; implements the concrete operation). For example: the I/O disk } } operation over folder or file can be processed in the same way (e.g. move, copy and rename). The folder contains one Listing 2. Methods inspecting the characteristics for Composite DP or more folders or files. The client (e.g. the explorer GUI) will After conversion, the list of Component instances hold handle the folder (Composite) and the files (Leaf) likewise (as inside the Composite class will be removed. Component). As performed for the Singleton DP, our algorithm consider VI. C ONCLUSION three feature that distinguish the Composite DP. For recogni- After years of research, AOP begins to propose itself as a tion of DP, we: valid means for developing applications outside the academic • get all interfaces of a project; context. However, for the last twenty years the development • for each interface, search all classes that implements it; of software systems has undergone exponential growth that • obtained the class list of each interface, search: (i) the does not permit an immediate exchange of technology. Our Composite class as a class that holds a list of type work provides an approach that identifies parts of the code 14 that can be refactored from OO to AO version. The already [16] E. Gamma, R. Helm, R. Johnson, and R. Vlissides, Design Patterns: well-formed and strong applications, thanks to twenty years Elements of Reusable Object-Oriented Software. Addison-Wesley, 1994. of experience on DPs, give us the opportunity to pass to the [17] R. Laddad, AspectJ in Action. Grennwich, Conn.: Manning Publications aspect version. It maintains the advantages of the latter and is Co., 2003. enriched by the AO modularity. [18] G. Pappalardo and E. Tramontana, “Automatically discovering design patterns and assessing concern separations for applications,” in Proceed- An important step during refactoring is the recognition of ings of ACM Symposium on Applied Computing (SAC), Dijon, France, the used DPs and the identification of associated classes. We April 2006, pp. 1591–1596. have identified three categories of recognition based on some [19] J. Dong, Y. Zhao, and Y. Sun, “A matrix-based approach to recovering design patterns,” IEEE Transactions on Systems, Man and Cybernetics, typical signatures of DP. Part A: Systems and Humans, vol. 39, no. 6, 2009. Our future work aims at collecting the features of all DPs at once from the application under analysis and recognise one or more DPs on the basis of the presence of all the characteristics required by the DP. Only after recognition of all the DPs the creation of the aspect code and the replacement of the OO code will be performed. R EFERENCES [1] G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda, C. Lopes, J.-M. Loingtier, and J. Irwin, “Aspect-oriented programming,” in Proceedings of ECOOP, ser. LNCS, vol. 1241. Springer, 1997, pp. 220–242. [2] J. Hannemann and G. Kiczales, “Design pattern implementation in Java and AspectJ,” in Proceedings of OOPSLA, vol. 37. ACM, 2002, pp. 161–173. [3] R. Giunta, G. Pappalardo, and E. Tramontana, “Aodp: Refactoring code to provide advanced aspect-oriented modularization of design patterns,” in Proceedings of ACM Symposium on Applied Computing (SAC), Riva del Garda, Italy, March 2012, pp. 1243–1250. [4] ——, “Aspects and annotations for controlling the roles application classes play for design patterns,” in Proceedings of IEEE Asia-Pacific Software Engineering Conference (APSEC), Ho Chi Minh, Vietnam, December 2011, pp. 306–314. [5] ——, “Superimposing roles for design patterns into application classes by means of aspects,” in Proceedings of ACM Symposium on Applied Computing (SAC), Riva del Garda, Italy, March 2012, pp. 1866–1868. [6] ——, “Using aspects and annotations to separate application code from design patterns,” in Proceedings of ACM Symposium on Applied Computing (SAC), Sierre, Switzerland, March 2010, pp. 2183–2189. [7] A. Calvagna and E. Tramontana, “Delivering dependable reusable com- ponents by expressing and enforcing design decisions,” in Proceedings of IEEE Computer Software and Applications Conference (COMPSAC) Workshop QUORS, Kyoto, Japan, July 2013, pp. 493–498. [8] F. Bannò, D. Marletta, G. Pappalardo, and E. Tramontana, “Tackling consistency issues for runtime updating distributed systems,” in Pro- ceedings of IEEE International Symposium on Parallel & Distributed Processing, Workshops and Phd Forum (IPDPSW), Atlanta, Georgia, US, 2010, pp. 1–8. [9] G. Pappalardo and E. Tramontana, “Suggesting extract class refactoring opportunities by measuring strength of method interactions,” in Proceed- ings of IEEE Asia Pacific Software Engineering Conference (APSEC), Bangkok, Thailand, December 2013, pp. 105–110. [10] E. Tramontana, “Automatically characterising components with concerns and reducing tangling,” in Proceedings of IEEE Computer Software and Applications Conference (COMPSAC) Workshop QUORS, Kyoto, Japan, July 2013, pp. 499–504. [11] M. Mongiovi, G. Giannone, A. Fornaia, G. Pappalardo, and E. Tra- montana, “Combining static and dynamic data flow analysis: a hybrid approach for detecting data leaks in Java applications,” in Proceedings of ACM Symposium on Applied Computing (SAC), Salamanca, Spain, 2015, pp. 1573–1579. [12] M. Fowler, K. Beck, J. Brant, W. Opdyke, and D. Roberts, Refactoring: Improving the Design of Existing Code. Addison-Wesley, 1999. [13] J. Kerievsky, Refactoring to patterns. Addison-Wesley, 2005. [14] N. Tsantalis, A. Chatzigeorgiou, G. Stephanides, and S. Halkidis, “Design Pattern Detection Using Similarity Scoring,” IEEE Transactions on Software Engineering, vol. 32, no. 11, pp. 896–909, 2006. [15] J. Dong, Y. Sun, and Y. Zhao, “Design pattern detection by template matching,” in Proceedings of ACM Symposium on Applied Computing (SAC), 2008, pp. 765–769. 15