Design Patterns with Aspectj, Generics, and Reflective Programming
Total Page:16
File Type:pdf, Size:1020Kb
DESIGN PATTERNS WITH ASPECTJ, GENERICS, AND REFLECTIVE PROGRAMMING Adam Przybylek Department of Business Informatics, University of Gdansk, Piaskowa 9, 81-824 Sopot, Poland Keywords: Design patterns, AOP, Generics. Abstract: Over the past decade, there has been a lot of interest towards aspect-oriented programming (AOP). Hannemann and Kiczales developed AspectJ implementations of the Gang-of-Four (GoF) design patterns. Their study was continued by Hachani, Bardou, Borella, and others. However, no one has tried to improve the implementations by using generics or reflective programming. This research faces up to this issue. As a result, highly reusable implementations of Decorator, Proxy, and Prototype are presented. 1 INTRODUCTION former exhibits significant improvement. In addition, a highly reusable implementation of the Capturing design knowledge in a way that makes it Prototype pattern was achieved by combining AOP possible for others to reuse it is the basic idea behind with reflective programming. design patterns (Noda & Kishi 2001). The solutions The modeling language used in this study is the proposed in the original design pattern literature extension to UML that was proposed by Przybyłek (Gamma et al. 1995) are shaped by techniques as (2008). The entire source code with examples is well as language deficiencies from the object available at the author's homepage (Przybyłek 2010). oriented (OO) paradigm. With the rise of the aspect- oriented (AO) paradigm, new programming abstractions have been occured that suggest it is time 2 MOTIVATIONS AND GOALS for these solutions to be revised. First attempts to reshape design pattern solutions For 11 out of 23 GoF patterns reusable based on aspect-oriented programming (AOP) were implementations aren’t known. Only the solutions of initiated by Hannemann & Kiczales (2002) and then these patterns are considered reusable. As a continued by Hachani & Bardou (2002), Borella consequence the programmer still has to implement (2003), Monteiro & Fernandes (2004), and Denier, the patterns for each application he is constructing Albin-Amiot & Cointe (2005). H&K developed (Borella 2003). However, to the best of the author's AspectJ implementations of the Gang-of-Four (GoF) knowledge, there is no evaluation of the impact of patterns. For 12 out of all 23 patterns, they found generics or reflection in AspectJ on the GoF reusable implementations. However, AspectJ didn’t patterns. Generics were added to AspectJ in 2005 support generics (generic types), when they were and since that time, implementations of design doing their research. With the advent of this patterns have had the potential to become more technique, a new support for more reusable reusable. Hence, the solutions that have been presented so far should be revisited and implementations have been occured. Generic types reconsidered. The aim of this paper is to present the let programmers define a type without specifying all results of exploring the existing AO the other types it uses. The unspecified types are implementations according to apply generics and supplied as parameters at the point of use. reflection. In this research the existing AO implementations were examined according to applying generics and reflective programming. It was found that generics bring advantages for the Decorator and the Proxy patterns, of which only the implementation of the 131 Przybylek A. (2010). DESIGN PATTERNS WITH ASPECTJ, GENERICS, AND REFLECTIVE PROGRAMMING. In Proceedings of the 5th International Conference on Software and Data Technologies, pages 131-136 DOI: 10.5220/0002923801310136 Copyright c SciTePress ICSOFT 2010 - 5th International Conference on Software and Data Technologies 3 THE DECORATOR PATTERN of the decorated object. Secondly, the decorator classes could directly implement the Decorator The intent of the Decorator pattern is to perform interface. Introducing the Decorator interface via the additional actions on individual objects (Borella parent declaration unnecessarily complicates the 2003; Gamma et al. 1995). The additional actions solution. Fig. 1 presents a new solution to the and the decorated objects are selected at runtime. An Decorator pattern. alternative for this pattern is inheritance. However, WrapperProtocol<E> describes the generic the Decorator pattern has several advantages over structure and behaviour that is determined by the subclassing. First, additional actions can be added pattern and it does not define any application and removed at runtime and per object. Second, specific behaviour. This solution reduces the non- combining independent extensions is easy by reusable parts of the implementation. The around composing decorator objects. With subclassing advices are responsible for intercepting objects every combination of extensions results in a new which should be decorated and passing them to the subclass and this can cause an explosion of wrap(E e) method as argument. This method iterates subclasses. through all the registered decorators and gives them There are many variations of the Decorator its argument to decorate (Listing 1). After pattern, but in this paper the one used is that defined decoration, the argument is returned. A concrete by Borella (2003). The first AO approach to this decoration process is implemented in the pattern was presented by Hannemann & Kiczales StarDecorator and DollarDecorator classes. (2002). Their solution has three limitations (Borella The joinpoints at which the object to decorate 2003). Firstly, it does not allow for dynamic should be captured are specified by the attaching and dynamic detaching of decorators. returned_object and object_passed_as_argument Secondly, it is not possible at runtime to define an pointcuts. Thus it is possible to decorate the object, order of activation among decorators. Thirdly, after inserting the decorator aspect in the system, all which is passed as an argument or returned as a instances of the intended class are decorated. result of a method call. The definitions of both Other solutions were proposed by Monteiro & pointcuts are empty, so at least one of them should Fernandes (2004) and Hachani & Bardou (2002) but be overridden in a subaspect. these do not add anything new and so need not be The concrete subaspect, which knows what type considered. A significant contribution to of object is captured and in which context, has to be implementing the Decorator pattern was made by derived from WrapperProtocol<E> by giving a Borella (2003). He uses a per-target instantiation bound type to the E parameter. One of such model to decorate only a subset of the instances of a subaspects is StringWrapper that binds the E class. His solution enables decorators to be parameter with String. StringWrapper intercepts composed dynamically. The order of activation of requests to the getNextWord() method and performs each decorator is given at runtime. a decoration on the object returned by this method. The Borella solution has two main An example of the use of StringWrapper is shown in imperfections. Firstly, the around advice and the Listing 2. wrap method are not generic, and depend on the type public E wrap(E e) { for ( Decorator<E> dec: decorators.values() ) e=dec.decorate(e); return e; } Listing 1: The wrap method. public class testDecorator { public static void main(String[] args) { WordPrinter w = new WordPrinter(); //1 StringWrapper wrapper = StringWrapper.aspectOf(w); //2 wrapper.addDecorator( new StarDecorator(), 2 ); //3 wrapper.addDecorator( new DollarDecorator(), 1 ); //4 w.setWord(0,"XXX"); //5 System.out.println( w.getNextWord() ); //6 } } Listing 2: A use of the Decorator pattern. 132 DESIGN PATTERNS WITH ASPECTJ, GENERICS, AND REFLECTIVE PROGRAMMING Figure 1: The Decorator pattern. In order to decorate a specific object, the – Create the illusion that an object on a different instance of StringWrapper that is associated with machine is an ordinary local object. this object is retrieved (line 2). Zero or more – Control access to a service-providing object decorators are then attached to this instance (lines 3 based on a security policy. and 4). Without any decorator, the getNextWord() – Create the illusion that a service object exists method would return "AA". However, the wrapper before it actually does. object has registered (lines 3 and 4) the The structure of this pattern, that uses generics, is StarDecorator and DollarDecorator instances, which shown on Fig. 2. ProxyProtocol<Subject> is a wrap the returned object with "***" and "$$$" reusable part of the implementation. Subject is a respectively. As a result, the "*** $$$ AA $$$ ***" parameter. The client binds this parameter with the string is printed on the screen (line 6). type of the object to be "proxied". The requestsToSubjectByCaller pointcut intercepts calls to the subject. If a call is proxy protected, the 4 THE PROXY PATTERN handleProxyProtection method is called instead of the original method. The isProxyProtected method The proxy pattern allows the developer to provide a checks whether the request should be handled by the surrogate object in place of the actual object in case proxy or not. By default it returns true. The access to the real object needs to be delegated or handleProxyProtection method provides an controlled. The following are some of the more alternative return value if a call is proxy protected. common uses for proxies (Grand 2002): The default implementation returns null. Concrete subaspects are forced to implement the requests – Represent an object that