Design Pattern Implementation in Java and Aspectj
Total Page:16
File Type:pdf, Size:1020Kb
Design Pattern Implementation in Java and AspectJ Jan Hannemann Gregor Kiczales University of British Columbia University of British Columbia 201-2366 Main Mall 201-2366 Main Mall Vancouver B.C. V6T 1Z4 Vancouver B.C. V6T 1Z4 jan [at] cs.ubc.ca gregor [at] cs.ubc.ca ABSTRACT successor in the chain. The event handling mechanism crosscuts the Handlers. AspectJ implementations of the GoF design patterns show modularity improvements in 17 of 23 cases. These improvements When the GoF patterns were first identified, the sample are manifested in terms of better code locality, reusability, implementations were geared to the current state of the art in composability, and (un)pluggability. object-oriented languages. Other work [19, 22] has shown that implementation language affects pattern implementation, so it seems The degree of improvement in implementation modularity varies, natural to explore the effect of aspect-oriented programming with the greatest improvement coming when the pattern solution techniques [11] on the implementation of the GoF patterns. structure involves crosscutting of some form, including one object As an initial experiment we chose to develop and compare Java playing multiple roles, many objects playing one role, or an object [27] and AspectJ [25] implementations of the 23 GoF patterns. playing roles in multiple pattern instances. AspectJ is a seamless aspect-oriented extension to Java, which means that programming in AspectJ is effectively programming in Categories and Subject Descriptors Java plus aspects. D.2.11 [Software Engineering]: Software Architectures – By focusing on the GoF patterns, we are keeping the purpose, patterns, information hiding, and languages; D.3.3 intent, and applicability of 23 well-known patterns, and only allowing [Programming Languages]: Language Constructs and Features – the solution structure and solution implementation to change. So we patterns, classes and objects are not discovering new patterns, but simply working out how implementations of the GoF patterns can be handled using a new General Terms implementation tool. Design, Languages. Our results show that using AspectJ improves the implementation of many GoF patterns. In some cases this is reflected in a new solution Keywords structure with fewer or different participants, in other cases, the Design patterns, aspect-oriented programming. structure remains the same, only the implementation changes. Patterns assign roles to their participants, for example Subject and 1. INTRODUCTION Observer for the Observer pattern. These roles define the The Gang-of-Four (GoF) design patterns [9] offer flexible solutions functionality of the participants in the pattern context. We found that to common software development problems. Each pattern is patterns with crosscutting structure between roles and participant comprised of a number of parts, including purpose/intent, classes see the most improvement. applicability, solution structure, and sample implementations. The improvement comes primarily from modularizing the A number of GoF patterns involve crosscutting structures in the implementation of the pattern. This is directly reflected in the relationship between roles in the pattern and classes in each implementation being textually localized. An integral part of instance of the pattern [6]. In the Observer pattern, an operation achieving this is to remove code-level dependencies from the that changes any Subject must trigger notifications of its Observers participant classes to the implementation of the pattern. – in other words the act of notification crosscuts one or more The implementation of 17 of the patterns is modularized in this way. operations in each Subject in the pattern. In the Chain Of For 12 of the patterns, the modularity enables a core part of the Responsibility pattern, all Handlers need to be able to accept implementation to be abstracted into reusable code. For 14, it requests or events and to either handle them or forward them to the enables transparent composition of pattern instances, so that multiple patterns can have shared participants. For the 17 Permission to make digital or hard copies of all or part of this work for modularized patterns, all pattern code from some or all participants personal or classroom use is granted without fee provided that copies are is moved into the pattern aspect, allowing those participants to be not made or distributed for profit or commercial advantage and that (un)pluggable with respect to the pattern. copies bear this notice and the full citation on the first page. To copy These results – 74% of GoF patterns implemented in a more otherwise, or republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. modular way, and 52% reusable – suggest it would be worthwhile to OOPSLA ’02, November 4-8, 2002, Seattle, Washington, USA. undertake the experiments of applying AspectJ to more patterns Copyright 2002 ACM 1-58113-471-1/02/0011…$5.00. and/or applying other aspect-oriented techniques to pattern Screen: Observer implementations. The rest of the paper is organized as follows. Section 2 surveys update() previously identified problems in design pattern implementation. display(String) Section 3 introduces the study format. In section 4, we present our AspectJ implementations and categorize the improvements we observed. Section 5 shows an analysis of our findings and 1 * observations. Related work is discussed in section 6, and Section 7 Figure FigureElement summarizes our work. addObserver(Observer) 2. ESTABLISHED CHALLENGES removeObserver(Observer) Numerous authors have identified challenges that arise when notify() patterns are concretized in a particular software system. The three most important challenges are related to implementation, documentation, and composition. Design pattern implementation usually has a number of undesirable Point: Subject Line: Subject related effects. Because patterns influence the system structure and their implementations are influenced by it [7], pattern getX():int getP1():Point getY():int getP2():Point implementations are often tailored to the instance of use. This can getColor():Color getColor():Color lead to them “disappearing into the code” [7] and losing their addObserver(Observer) addObserver(Observer) modularity [21]. This makes it hard to distinguish between the removeObserver(Observer) removeObserver(Observer) pattern, the concrete instance and the object model involved [15]. notify() notify() Adding or removing a pattern to/from a system is often an invasive, setX(int) setP1(Point) difficult to reverse change [4]. Consequently, while the design setY(int) setP2(Point) pattern is reusable, its implementations usually are not [21]. setColor(Color) setColor(Color) The invasive nature of pattern code, and its scattering and tangling with other code creates documentation problems [21]. If multiple Figure 1. A simple Graphical Figure Element System that patterns are used in a system, it can become difficult to trace uses the Observer pattern in Java. The underlined methods particular instances of a design pattern, especially if classes are contain code necessary to implement this instance of the involved in more than one pattern (i.e. if there is pattern Observer pattern. overlay/composition) [1]. usually with varying tradeoffs. Our goal was to fully investigate the Pattern composition causes more than just documentation problems. design space of clearly defined implementations of each pattern. It is inherently difficult to reason about systems with multiple We ended up creating a total of 57 different implementations, which patterns involving the same classes, because the composition ranged from 1 to 7 per pattern. Some of the tradeoffs and design creates large clusters of mutually dependent classes [21]. This is an decisions are discussed in Section 4. important topic because some design patterns explicitly use others patterns in their solution. 4. RESULTS This section presents a comparison of the AspectJ and Java 3. STUDY FORMAT implementations of concrete instances of the GoF design patterns. The findings presented in this paper are based on a comparative Section 4.1 is a detailed discussion of the Observer pattern. We use analysis of Java and AspectJ implementations of the GoF design this discussion to present properties common to most of the AspectJ patterns. solutions. The remaining patterns are presented by building on the For each of the 23 GoF patterns we created a small example that concepts developed in Section 4.1. makes use of the pattern, and implemented the example in both Java 1 4.1 Example: the Observer pattern and AspectJ. The Java implementations correspond to the sample The intent of the Observer pattern is to “define a one-to-many C++ implementations in the GoF book, with minor adjustments to dependency between objects so that when one object changes state, account for the differences between C++ and Java (lack of multiple all its dependents are notified and updated automatically”[9]. inheritance, etc.). Most patterns have a number of implementation Object-oriented implementations of the Observer pattern, such as variants and alternatives. If a pattern offered more than one the sample code in the GoF book (p. 300-303), usually add a field to possible implementation, we picked the one that appeared to be the all potential Subjects that stores a list of Observers interested in that most generally applicable. particular Subject. When a Subject wants to report a state change