DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de...

118
Universidade Federal de Pernambuco - UFPE Centro de Inform´ atica - CIn os-gradua¸ ao em Ciˆ encia da Computa¸ ao DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ Carlos Eduardo Pontual de Lemos Castro DISSERTAC ¸ ˜ AO DE MESTRADO Recife - PE 17 de Junho de 2010

Transcript of DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de...

Page 1: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

Universidade Federal de Pernambuco - UFPE

Centro de Informatica - CIn

Pos-graduacao em Ciencia da Computacao

DESIGN RULES FOR INCREASING

MODULARITY WITH CAESARJ

Carlos Eduardo Pontual de Lemos Castro

DISSERTACAO DE MESTRADO

Recife - PE

17 de Junho de 2010

Page 2: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

Universidade Federal de Pernambuco - UFPE

Centro de Informatica - CIn

Carlos Eduardo Pontual de Lemos Castro

DESIGN RULES FOR INCREASING MODULARITY WITH

CAESARJ

Trabalho apresentado ao Programa de Pos-graduacao em

Ciencia da Computacao do Centro de Informatica - CIn da

Universidade Federal de Pernambuco - UFPE como requi-

sito parcial para obtencao do grau de Mestre em Ciencia

da Computacao.

Orientador: Paulo Henrique Monteiro Borba

Recife - PE

17 de Junho de 2010

Page 3: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

Castro, Carlos Eduardo Pontual de Lemos. Design rules for increasing modularity with CaesarJ. / Carlos Eduardo Pontual de Lemos Castro. - Recife: O autor, 2010. xv, 102 folhas: il., fig., tab. Dissertação (Mestrado) - Universidade Federal de Pernambuco. CIN. Ciência da Computação, 2010. Inclui bibliografia e apêndice. 1. Engenharia de software. 2. Modularidade. 3. Programação orientada a aspectos. 4. Programação orientada a objetos. I. Título. 005.1 CDD (22.ed.) MEI-2010-163

Page 4: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

To my family, my girlfriend and everyone that believed in

me.

Page 5: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

ACKNOWLEDGEMENTS

Inicialmente, agradeco a Deus, companheiro inseparavel em todos esses 785 dias aqui “no”

Recife, a quem eu recorria quase sempre nos momentos mais difıceis, de maior angustia.

Sem Ele, nada disso seria possıvel. Agradeco tambem a muitas outras pessoas que me

ajudaram e contribuıram, de forma direta ou indireta, para a conclusao desse trabalho:

A minha famılia, por todo carinho, apoio, por acreditar muito em mim e por toda

a ajuda. Um agradecimento especial aos meus pais, que fizeram o possıvel (e o im-

possıvel) para me manter sempre motivado, sempre me dando muita atencao, e nunca

tendo deixando que eu passasse qualquer necessidade. Um abraco bem apertado no meu

irmao Bruno, de quem eu sinto muita falta. Suas visitas foram excelentes (METAL \,,/)!

A Cınthia, que me apoiou incondicionalmente durante esse perıodo, me ajudando de

todas as maneiras possıveis e impossıveis, inclusive nos momentos que nem eu conseguia

me suportar. Muito obrigado pela atencao, amor e carinho. Eu nao teria conseguido sem

o seu apoio, suas visitas, e o tempo que voce passou aqui comigo. Te amo Dra. =*

Ao orientador/amigo/lord Paulo Borba, primeiramente, no ambito profissional, pela

excelente orientacao durante esse perıodo, sempre me apontando a direcao correta, com

muita, muita paciencia, dedicacao e... ja disse paciencia? Alem disso, pelo lado amigo,

nas brincadeiras, viagens, confraternizacoes, e ate mesmo enquanto eu comemorava a

vitoria do Sao Paulo em pleno estadio dos aflitos :) Muito obrigado por tudo!

Aos meus amigos do mestrado, em especial Rodrigao, Napoleao, Moral, ModPag e

Fernanda, por toda a ajuda nos inumeros obstaculos desse perıodo: artigos, projetos,

trabalhos, discussoes... Leopoldo, Marcio e Henrique: Perdoo voces por torcerem contra

o SP :) Obrigado tambem aos membros do SPG, pelas excelentes e proveitosas discussoes.

A todos os meus amigos de Fortaleza, que me animavam toda vez que eu ia a minha

terrinha. Obrigado Brunao, Marılia, Pazzo, Sabrina, Tarcia, e a todos aqueles que me

visitaram aqui, quebrando a minha rotina e alegrando meus dias. Agradeco tambem aos

amigos da Residencia das Palmeiras, por toda forca que me deram nessa reta final.

Finalmente, agradeco ao CNPq por financiar a minha pesquisa.

Oh, and a special thanks to the #stratego community members, specially to Rob

Vermaas, for all the help with Stratego/XT. I won’t forget your beer Rob :)

iv

Page 6: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

So sei que nada sei.

—SOCRATES

Page 7: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

RESUMO

Programacao Orientada a Aspectos (POA) e um mecanismo de programacao proposto

para modularizar os requisitos transversais, visando um aumento na modularidade de

software. Entretanto, recentemente alguns autores tem alegado que o uso de POA quebra

a modularidade das classes. Isso acontece pois, sem o uso de interfaces apropriadas entre

classes e aspectos, diversas propriedades de um design modular, como compreensibilidade,

manutenabilidade e desenvolvimento em paralelo, sao comprometidas na presenca de

aspectos.

Diversas interfaces especializadas (design rules) para desacoplar classes e aspectos

foram propostas visando atenuar esse problema, como XPIs e LSD. Entretanto, tais

interfaces sao especıficas para a linguagem AspectJ, que possui problemas de reuso e

modularidade de aspectos. CaesarJ, por outro lado, e uma linguagem de programacao

orientada a aspectos com forte suporte para reuso e modularidade de aspectos. Essa

linguagem combina as construcoes OA pointcut e advice com avancados mecanismos de

modularizacao OO.

Nesse trabalho nos exploramos algumas construcoes de CaesarJ com o intuito de veri-

ficar se elas podem ser utilizadas para definir Design Rules que permitam um desenvolvi-

mento modular de codigo OO e OA. Alem disso, nos propomos CaesarJ+, uma extensao

de CaesarJ que foca no aumento de modularidade. Essa extensao introduz construcoes

que permitem impor restricoes estruturais sobre os codigos OO e OA. Um compilador

para CaesarJ+, que verifica se as restricoes especificadas nas Design Rules estao sendo

seguidas, e transforma o codigo CaesarJ+ em codigo CaesarJ tambem foi desenvolvido

nesse trabalho.

Para avaliar CaesarJ+, nos comparamos as implementacoes de tres estudos de caso

em CaesarJ+ e CaesarJ. Nossos resultados revelam que o uso de CaesarJ+ proporciona

ganho de expressividade.

Palavras-chave: Modularidade de Software, Design Rules, Programacao Orientada a

Aspectos, Programacao Orientada a Objetos, CaesarJ

vi

Page 8: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

ABSTRACT

Aspect-Oriented Programming (AOP) is a programming mechanism proposed to modu-

larize the crosscutting concerns, aiming to increase software modularity. However, more

recently, some authors have claimed that AOP, in fact, might break class modularity.

This problem arises because, without using proper interfaces, several properties of a

modular design, such as comprehensibility, changeability and parallel development, are

compromised in the presence of aspects.

In order to mitigate these problems, specialized interfaces (design rules) to decouple

classes and aspects have been proposed, such as XPIs and LSD. However, these interfaces

are specific for AspectJ, which has some issues of reusability and modularity of Aspects.

CaesarJ, for instance, is an aspect-oriented programming language with a strong support

for reusability and modularity of aspects. It combines the AO constructs, pointcuts and

advice, with advanced object-oriented modularization mechanisms.

In this work we explore some CaesarJ constructs in order to check if they can be used to

define Design Rules which enable a modular development of OO and AO code. Moreover,

we propose CaesarJ+, an extension to CaesarJ that aims to increase modularity. This

extension introduces constructs that enforce structural restrictions over both OO and AO

code. We also have developed a compiler for CaesarJ+, which checks if the restrictions

specified by the Design-Rules are being followed, and transforms CaesarJ+ into CaesarJ

valid code.

We evaluate this extension using three case studies, comparing the interfaces specified

for these examples in both CaesarJ+ and CaesarJ. Our results reveal that we have a gain

of expressiveness when using CaesarJ+.

Keywords: Software Modularity, Design Rules, Aspect-Oriented Programming, Object-

Oriented Programming, CaesarJ

vii

Page 9: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CONTENTS

Chapter 1—Introduction 1

1.1 Summary of Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.2 Organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

Chapter 2—Background 5

2.1 Software Modularity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2 Aspect Oriented Programming . . . . . . . . . . . . . . . . . . . . . . . . 6

2.3 CaesarJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.3.1 Caesar Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.3.2 Aspects Collaboration Interfaces - ACIs . . . . . . . . . . . . . . . 11

2.3.3 Mixin composition . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.3.4 Wrapper Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.4 Development of Classes and Aspects: Modularity Issues . . . . . . . . . . 15

Chapter 3—Exploring CaesarJ 18

3.1 Tetris SPL Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3.2 Template Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.2.1 Template Method without ACIs . . . . . . . . . . . . . . . . . . . 20

3.2.2 Template Method with ACIs . . . . . . . . . . . . . . . . . . . . . 23

3.3 Mixin Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

3.3.1 Mixins without ACIs . . . . . . . . . . . . . . . . . . . . . . . . . 26

3.3.2 Mixins with ACIs . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3.4 Wrappers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

3.4.1 Wrappers without ACIs . . . . . . . . . . . . . . . . . . . . . . . 32

3.4.2 Wrappers with ACIs . . . . . . . . . . . . . . . . . . . . . . . . . 34

3.5 Chapter Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

viii

Page 10: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CONTENTS ix

Chapter 4—CaesarJ+: An extension to Increase CaesarJ Modularity 37

4.1 Design Rules construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.2 Complements relationship . . . . . . . . . . . . . . . . . . . . . . . . . . 40

4.3 Design Rules implementation . . . . . . . . . . . . . . . . . . . . . . . . 41

4.4 Design Rules instantiation . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4.5 Enhancing Expressiveness . . . . . . . . . . . . . . . . . . . . . . . . . . 46

4.5.1 Wildcards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.5.2 Advice restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . 48

4.6 Chapter Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

Chapter 5—Implementation details 51

5.1 Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

5.1.1 Design Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

5.1.2 Complements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

5.1.3 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

5.1.4 Instantiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

5.2 Compiler Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 59

5.2.1 Stratego/XT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

5.2.2 CaesarJ+ Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . 61

5.2.2.1 Manipulation of Design Rules . . . . . . . . . . . . . . . 63

5.2.2.2 Compilation of DR implementations . . . . . . . . . . . 63

5.2.2.3 Manipulation of DR instances . . . . . . . . . . . . . . . 64

5.2.3 Compiler Limitations . . . . . . . . . . . . . . . . . . . . . . . . . 66

Chapter 6—Evaluation 68

6.1 Tetris SPL - Di!culty Feature . . . . . . . . . . . . . . . . . . . . . . . . 68

6.2 Observer Design Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

6.3 Health Watcher Transaction Concern . . . . . . . . . . . . . . . . . . . . 77

Chapter 7—Concluding Remarks 81

7.1 Related Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

7.1.1 Open Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

7.1.2 Aspect Aware Interfaces . . . . . . . . . . . . . . . . . . . . . . . 84

7.1.3 Crosscutting Programming Interfaces (XPIs) . . . . . . . . . . . . 84

Page 11: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CONTENTS x

7.1.4 Language for Specifying Design Rules (LSD) . . . . . . . . . . . . 85

7.1.5 CrossMDA2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

7.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

Appendix A—CaesarJ+ SDF grammar 89

A.1 General CaesarJ+ Specification . . . . . . . . . . . . . . . . . . . . . . . 89

A.2 Design Rules construct SDF . . . . . . . . . . . . . . . . . . . . . . . . . 94

Page 12: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

LIST OF FIGURES

2.1 Aspect weaving process . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.2 Mixin linearization: Generated inheritance hierarchy . . . . . . . . . . . 13

2.3 ColoredWeightedGraph (a) refined by SpecialColoredWeightedGraph (b) 14

2.4 Modularity Issues between Classes and Aspects . . . . . . . . . . . . . . 16

3.1 Tetris game: normal di!cult (left) and easy di!cult (right). . . . . . . . 19

3.2 Tetris Game - Single product diagram . . . . . . . . . . . . . . . . . . . . 19

3.3 Classes TetrisCanvas and NextPiece . . . . . . . . . . . . . . . . . . . . . 20

3.4 Template Method without ACIs: variations depend on invariant code (in-

heritance). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3.5 Diagram of Mixin implementation without use ACIs . . . . . . . . . . . . 27

3.6 Diagram of Wrapper implementation using ACIs . . . . . . . . . . . . . . 35

4.1 The order of classes in a DR instances is the same of the DR parameters 44

5.1 Overview of Design Rules compilation process . . . . . . . . . . . . . . . 52

5.2 Overview of Stratego/XT transformation process [9]. . . . . . . . . . . . 60

xi

Page 13: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

LISTINGS

2.1 Pointcut example on AspectJ . . . . . . . . . . . . . . . . . . . . . . . . 7

2.2 Advice example on AspectJ . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.3 Inter-type declaration on AspectJ . . . . . . . . . . . . . . . . . . . . . . 8

2.4 Caesar class example: classic Figure-Display problem . . . . . . . . . . . 10

2.5 Set of collaboration classes (ACI) for the graph example . . . . . . . . . 12

3.1 Template Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3.2 Interface for Template Method . . . . . . . . . . . . . . . . . . . . . . . . 22

3.3 NextPieceACI, Template Method . . . . . . . . . . . . . . . . . . . . . . 23

3.4 NextPieceACI enabling the bi-directional dependency, Template Method 24

3.5 Implementations of NextPieceACI, Template Method . . . . . . . . . . . 24

3.6 Instantiation of the variation . . . . . . . . . . . . . . . . . . . . . . . . . 25

3.7 NextPieceConcrete class: Mixin of NextPieceBase and EasyVariation . . 27

3.8 Implementation of NextPieceACI using Mixin Composition . . . . . . . . 28

3.9 NextPieceACI with the Canvas role . . . . . . . . . . . . . . . . . . . . . 29

3.10 Mixin implementation of NextPieceACI with Canvas role . . . . . . . . . 30

3.11 Invalid mixin NextPieceMixin: No error given by CaesarJ compiler. . . . 31

3.12 First implementation using wrappers . . . . . . . . . . . . . . . . . . . . 32

3.13 Wrapper class EasyVariation with inversion of control . . . . . . . . . . . 33

3.14 NextPieceACI interface for Wrapper classes implementation . . . . . . . 34

4.1 Simple CaesarJ+ Design Rule example . . . . . . . . . . . . . . . . . . . 38

4.2 Design Rule construct SDF grammar . . . . . . . . . . . . . . . . . . . . 39

4.3 Design Rule for the Di!culty feature of Tetris SPL . . . . . . . . . . . . 40

4.4 Complements construct SDF grammar . . . . . . . . . . . . . . . . . . . 41

4.5 Each class implementing a single DR role . . . . . . . . . . . . . . . . . . 42

4.6 A single class implementing more than one DR role . . . . . . . . . . . . 42

4.7 Design rule implementation SDF grammar . . . . . . . . . . . . . . . . . 43

4.8 Example of a DR instance for ExampleDR design rule . . . . . . . . . . . 44

4.9 Invalid DR instance: ExampleB implements role B, but is positioned in

the instantiation as role A implementation. Similar happens to ExampleA. 44

xii

Page 14: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

LISTINGS xiii

4.10 DR instance using a class which implements more than one role . . . . . 44

4.11 Instantiation and references of a DR role . . . . . . . . . . . . . . . . . . 45

4.12 Design rule instantiation SDF grammar . . . . . . . . . . . . . . . . . . . 46

4.13 Caesar class example: classic Figure-Display problem . . . . . . . . . . . 47

4.14 Caesar class example: classic Figure-Display problem . . . . . . . . . . . 48

5.1 Generated CaesarJ ACI for ExampleDR (Listing 4.5) . . . . . . . . . . . 52

5.2 Generic ACI after the transformation of the complements construct . . . 54

5.3 ExampleA before transformation . . . . . . . . . . . . . . . . . . . . . . 56

5.4 Generated code for ExampleA . . . . . . . . . . . . . . . . . . . . . . . . 56

5.5 CaesarJ+ DR instance and references before transformation . . . . . . . 58

5.6 Generated CaesarJ code for DR instance . . . . . . . . . . . . . . . . . . 59

5.7 Main transformation rule of CaesarJ+ compiler . . . . . . . . . . . . . . 61

5.8 Manipulation of Design Rules . . . . . . . . . . . . . . . . . . . . . . . . 63

5.9 Compilation of DR implementations . . . . . . . . . . . . . . . . . . . . . 64

5.10 Manipulation of DR instances . . . . . . . . . . . . . . . . . . . . . . . . 65

5.11 How currently CaesarJ+ compiler accepts references to DR roles . . . . . 66

6.1 CaesarJ ACI for the di!culty feature . . . . . . . . . . . . . . . . . . . . 70

6.2 CaesarJ+ Design Rule for the di!culty feature . . . . . . . . . . . . . . . 71

6.3 CaesarJ ACI for the observer design pattern . . . . . . . . . . . . . . . . 74

6.4 CaesarJ Implementation of Subject binding . . . . . . . . . . . . . . . . 75

6.5 CaesarJ+ design rule for the observer design pattern . . . . . . . . . . . 75

6.6 CaesarJ+ implementation of ObserverDR Subject binding role . . . . . . 76

6.7 LSD design rule for the HW Transaction Concern . . . . . . . . . . . . . 78

6.8 CaesarJ+ design rule for the HW Transaction Concern . . . . . . . . . . 79

6.9 CaesarJ ACI for the HW Transaction Concern . . . . . . . . . . . . . . . 79

7.1 Possible alternative DR instantiation process . . . . . . . . . . . . . . . . 87

Page 15: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

LIST OF TABLES

3.1 Problems on Template Method solution . . . . . . . . . . . . . . . . . . . 26

3.2 Problems on Mixin solutions . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.3 Problems Enumerated on this Chapter . . . . . . . . . . . . . . . . . . . 36

4.1 Use of wildcards in parameters declarations . . . . . . . . . . . . . . . . 48

5.1 Pointcuts which need to be updated . . . . . . . . . . . . . . . . . . . . . 55

6.1 Tetris SPL Di!culty Feature: Summary of the evaluation. The acronyms

mean Statically checked (SC), Partially checked (P) and No checking (N). 72

6.2 Observer Example: Summary of the evaluation. . . . . . . . . . . . . . . 76

6.3 HW Transaction Concern: Summary of the evaluation. . . . . . . . . . . 80

xiv

Page 16: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CHAPTER 1

INTRODUCTION

According to David Parnas [46], modularization is a mechanism for improving the flexibil-

ity and comprehensibility of a system, enabling the reduction of its development time. A

modular design depends on developer decisions and on the programming paradigm used

for the software development, as each paradigm has its own modularization strategies.

Object-Oriented Programming (OOP), a widely adopted paradigm in software indus-

try, has the class artifact as the main unit for modularizing concerns. However, when

using OOP, some concerns cannot be well modularized, their implementation is scattered

throughout several system modules, tangled with code responsible for the implementation

of other concerns. Those are called crosscutting concerns. Aspect-Oriented Programming

(AOP) [5] is a programming mechanism proposed to modularize crosscutting concerns,

aiming to increase software modularity. AOP languages modularize these concerns by

means of a new modular unit, named aspect. Distribution, tracing, persistence and

transactional management are examples of crosscutting concerns well addressed by AOP.

Nevertheless, the use of AOP might compromise several properties of a modular de-

sign. For instance, the parallel development of classes and aspects is limited, as program-

mers are not able to write aspects until the related classes have been implemented [24].

Otherwise, aspects and class developers must be in constant communication to establish

the minimum requirements they need to provide. Moreover, evolving a class might break

the intents of an aspect. As a consequence, developers might not be able to change a

class (or even an aspect) without considering the join points advised by the aspects. In

this way, classes lose their flexibility. This problem is known as fragile pointcut [36]. The

comprehensibility is also compromised, as programmers are not allowed to reason about

a class without considering all aspects that might advise it [12]. Therefore, constructs

introduced to support crosscutting modularity might actually break class modularity [51],

creating dependencies between classes and aspects.

Aiming to mitigate these issues, some works discuss the use of Design Rules (DRs)

for specifying interfaces between classes and aspects [38, 57, 43]. They claim that these

design rules, which generalize the notion of information hiding interfaces and must be

rigorously obeyed, reduce the dependencies in Aspect-Oriented (AO) systems, decoupling

1

Page 17: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

INTRODUCTION 2

classes and aspects and enabling their independent development. Moreover, DRs work

as a guideline for developers of Object-Oriented (OO) and AO code.

Sullivan et al. [57], for instance, compares the use of design rules since the beginning

of the development process with the obliviousness approach, where no rules for classes

and aspects are defined before the implementation. They show that the code generated

using DRs is less complex and presents less dependencies between classes and aspects.

However, their DRs are specified using natural language, which might lead to verbose,

imprecise and ambiguous specifications. Later, Griswold et al. [24] introduce Crosscutting

Programming Interfaces (XPI), which uses AspectJ to express Design Rules. A clear

limitation of XPIs is that they do not represent in an explicit way the responsibilities

of class developers. Besides that, the use of AspectJ leads to complex specifications

(pointcuts), as this language was not designed to this purpose. Furthermore, many of the

restrictions have to be defined with natural language, which cannot be statically checked.

Costa Neto [43] presents a Language for Specifying Design Rules (LSD), which has the

specific purpose of specifying DRs in AO systems. However, the interfaces generated by

LSD are specific for AspectJ, which has some aspect reusability and modularity issues,

such as lacking of aspectual polymorphism and lacking support for multi-abstraction

aspects [42].

CaesarJ [10], on the other hand, is an aspect-oriented programming language with a

strong support for reusability and modularity of aspects. It combines the AO constructs,

pointcuts and advice, with advanced OO modularization mechanisms. Also, on CaesarJ

there is no explicit di"erentiation of classes and aspects, an aspect is a CaesarJ class

(cclass) with pointcuts or advice. This language introduces the Aspect Collaboration

Interface (ACI) concept [42], which enables us to specify nested interfaces of CaesarJ

classes.

In this work, we explore CaesarJ constructs in order to check if they can express

Design Rules that enable modular development between OO and AO code. After an initial

analysis, we conclude that the concept of ACI, along with its modularization mechanisms,

is not enough for expressing clear design rules. The interfaces defined using ACIs are not

clear enough to allow parallel development of the modules, and its rules might not be

automatically checked by the language compiler, as we discussed in a previous work [49].

Thus, we propose CaesarJ+, an extension to CaesarJ that aims to increase mod-

ularity. Our extension introduces the design rules construct into CaesarJ, enabling the

specification of rules for OO and AO code. We also introduce the use of wildcards on rules

related to methods and advice, which was not available in CaesarJ ACIs. A CaesarJ+

Page 18: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

1.1 SUMMARY OF GOALS 3

compiler, which is responsible for verifying the rules established on the Design Rules, is

also presented. This compiler is implemented using Stratego/XT [55], a language and

toolkit for program transformations. In this way, a compiler error is raised if any of the

restrictions defined within the DRs is not respected.

We evaluate CaesarJ+ using three examples, a feature from a Tetris game SPL, the

Observer design pattern [21], and one concern from the Health Watcher system [53].

We compare the interfaces defined using our Design Rules approach with the interfaces

specified using CaesarJ ACIs. Our results reveal that we have a gain of expressiveness

when using CaesarJ+, as with its DRs we are able to express and check restrictions

that could not be expressed with CaesarJ ACIs. Moreover, we still can use all CaesarJ

functionalities.

As previous work illustrate [38, 57, 43], we also believe that the use of specific De-

sign Rules decouple classes and aspects, enabling their independent development. The

hypothesis of our work is that by allowing the specification of proper design rules in

CaesarJ we can have a modular (independent) development of OO and AO code.

1.1 SUMMARY OF GOALS

Our work has the following goals:

• Analyze the concept of Aspect Collaboration Interfaces (ACI) present on CaesarJ,

verifying how we can use it to define interfaces between OO and AO code;

• Enable the definition of design rules on CaesarJ to promote the modular (indepen-

dent) development of Object-Oriented and Aspect-Oriented code;

• Provide tool support for automatically verifying restrictions established by these

Design Rules.

1.2 ORGANIZATION

This dissertation is organized as follows:

• Chapter 2 reviews essential concepts used throughout this work: Software Modu-

larity and Aspect-Oriented Programming. It also overviews CaesarJ, describing its

main constructs addressed in this work, and discusses modularity issues related to

the development of classes and aspects.

Page 19: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

1.2 ORGANIZATION 4

• Chapter 3 explores the use of some CaesarJ constructs. It introduces implementa-

tions of a Tetris game SPL feature, using several CaesarJ modularization mecha-

nisms. We have a discussion about the modularity problems of each implementa-

tion.

• Chapter 4 presents CaesarJ+, an extension to increase CaesarJ modularity, moti-

vating and discussing all of its proposed constructs.

• Chapter 5 presents CaesarJ+ compiler, which verifies and checks the restrictions

specified on the DRs. It explains how this compiler works and discuss implementa-

tion details, which uses the Stratego/XT language and toolkit for program trans-

formations.

• Chapter 6 describes the evaluation of CaesarJ+, which consists of a comparison be-

tween the implementations of 3 case studies using both CaesarJ+ DRs and CaesarJ

ACIs to define necessary interfaces.

• Chapter 7 describes the concluding remarks of our work, discussing our contribu-

tions, the related work, limitations of our approach and the future work.

• Appendix A depicts the CaesarJ+ SDF grammar.

Page 20: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CHAPTER 2

BACKGROUND

In this chapter we introduce the main concepts used as base for this work. First we discuss

about Software Modularity and the concept of modularity on which this work is based

(Section 2.1). In Section 2.2 we make a brief introduction of Aspect Oriented Program-

ming, while Section 2.3 introduces CaesarJ, the programming language used on this work,

depicting its main constructs mentioned throughout this dissertation. Finally, we discuss

about modularity issues between development of classes and aspects on Section 2.4.

2.1 SOFTWARE MODULARITY

Parnas [46] concept of modularity for software development is close related to design

decisions that decompose and organize the system into a set of modules. Although

proposed more than thirty years ago, Parnas criteria of modularity are still being used

in many works on Software Engineering and several other areas. According to him, the

following attributes are expected in a modular design:

• Comprehensibility: a modular design allows developers to understand a module

looking only at: (1) the implementation of the module itself; and (2) the interfaces

of the other modules referenced by it;

• Changeability: a modular design enables local changes. If changes are necessary

in the internal implementation of a module A, the other modules that depend

exclusively on A interface will not need to change, since there is no modification in

the module interface;

• Parallel Development: the specification of module interfaces enables the parallel

development of modules. Di"erent teams might only focus in their own modules,

reducing the time-to-market and the need of communication.

Parnas proposed the information hiding principle as the criteria to be used in de-

composition of systems into modules. According to him, the parts of a system that are

more likely to change must be hidden into modules with stable interfaces. These criteria

5

Page 21: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.2 ASPECT ORIENTED PROGRAMMING 6

are enforced on the Object-Oriented (OO) paradigm in which classes implementations

details are hidden and only their interfaces are exposed. However, the interaction of

Aspect-Oriented (AO) and OO languages does not follow this principle, as mentioned on

Section 2.4.

More recently, Baldwin and Clark [6] proposed a theory which considers modularity

as a key factor to innovation and market growth, independent of the industry area. Their

theory uses Design Structure Matrices (DSMs) to reason about dependencies among

artifacts and claims that the task structure organization is closely related to that de-

pendencies. In this way, if two modules are coupled, their parallel and independent

development is impossible, requiring communication between the di"erent teams, or the

implementation of both modules by a single team.

We can improve modularity by removing dependencies between design decisions, but it

is necessary to elaborate several assumptions before that. Baldwin and Clark [6] represent

these assumptions as a special kind of parameter, named as Design Rules (DRs). DRs

are less likely to change and are used as interfaces between modules [38]. In this way,

they are used to decouple design parameters, like typical programming interfaces remove

the coupling between software components. Such design rules establish strict partitions

of knowledge and e"ort at the outset of a design process. We can say that programming

interfaces are specific representations of Design Rules. The most important is that DRs

are not just guidelines or recommendations, they must be rigorously obeyed in all phases

of design and production.

Ribeiro et al. [51] made a study in which DSMs were utilized to analyze three versions

of a real software application (OO, AO, and AO using Design Rules). The version of

the system that uses Design Rules su"ered a reduction on the coupling between classes

and aspects, generating a more modular design, specially when considering semantic

dependencies [13] between them.

2.2 ASPECT ORIENTED PROGRAMMING

Aspect-Oriented Programming (AOP) [34] is a programming mechanism proposed to

modularize crosscutting concerns. These concerns often cannot be cleanly decomposed

from the rest of the system, which results in either scattering or tangling, making the

code di!cult to understand and hard to maintain. Distribution, tracing, transaction

management, persistence, among others are well-accepted examples of crosscutting con-

cerns. AOP separates these kind of concerns, avoiding scattering and tangling of code,

Page 22: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.2 ASPECT ORIENTED PROGRAMMING 7

promoting a more modular system. There are several Aspect-Oriented (AO) languages,

and AspectJ [5, 32], an AO extension to Java, is the well-known AOP language.

AOP encapsulates the crosscutting concerns inside units called aspects. AOP is based

on Join Point Interception model (JPI), which defines (1) the points in the program where

the aspects should be applied, called join points, (2) a way to specify or quantify these

join points, called pointcuts, and (3) a construct to specify code to run at a join point,

usually called advice. Next we describe the main AOP constructs that can be declared

inside an aspect [33]:

• Pointcut: It defines which points in the code are related to a given crosscutting

concern, the points where the concern should be applied. Pointcuts are used to

specify a set of join points, enabling the quantification in AOP. In AspectJ we have

some primitive pointcut designators (PCDs), like call, execution, this, target,

among others, which allow us to define the desired pointcuts. Listing 2.1 presents

three AspectJ pointcuts. Pointcut coordChange defines that calls to methods setX

or setY, of the Paint class, which have just one integer parameter might be in-

tercepted by aspects. Regarding pointCreation, it specifies that the execution of

Point constructor might be intercepted as well. We can combine pointcuts using

logical operators in most AOP languages, as we can see on Line 5.

Listing 2.1 Pointcut example on AspectJ

1 pointcut coordChange ( ) : ca l l (void Point . setX ( int ) )

2 | | ca l l (void Point . setY ( int ) )

3 pointcut po intCreat i on ( ) : execution ( Point .new ( ) ) ;

4

5 pointcut po intModi f i ed ( ) : coordChange ( ) | | po intCreat i on ( ) ;

• Advice: An advice is the construct used to specify the behavior that should be

applied to a given join point. Usually it uses a pointcut which specifies the points

where the advice should be applied. On AspectJ we have three types of advice,

which are applied before, after, or around a given join point. Listing 2.2 shows

an example of an advice that use the previously declared pointModified pointcut

to update the Display class.

Listing 2.2 Advice example on AspectJ

1 after ( ) : po intModi f i ed ( ) {

2 Display . update ( ) ;

3 }

Page 23: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.3 CAESARJ 8

• Inter-type declaration: It enables programmers to declare in one place members

or parents of another class. Inter-type declarations (ITDs) provide a way to express

crosscutting concerns a"ecting the structure of modules, in order to enable that all

code related to a specific concern can be concentrated into aspects. In AspectJ

we have ITDs that declare new attributes, methods, change the parent of a given

class, among others. Listing 2.3 shows examples of AspectJ ITDs. On Line 1 class

Point is being declared to inherit from FigureElement. Line 3 declares the color

attribute inside class Point, whereas we have the declaration of method setColor

to modify this attribute in Lines 5-7.

Listing 2.3 Inter-type declaration on AspectJ

1 declare parents : Point extends FigureElement ;

2

3 private Color Point . c o l o r ;

4

5 public void Point . s e tCo lor ( Color co l o r ) {

6 this . c o l o r = co l o r ;

7 }

Classes and aspects are composed by aspect compilers (weavers, such as AJDT [2]

or abc [1] for AspectJ) in a process called weaving, illustrated in Figure 2.11. AOP was

initially defined as Quantification, due to pointcuts quantification, and Obliviousness, as

class developers were initially supposed to design and codify its classes without care about

aspects that would latter be applied [20]. However, more recently some authors [57, 54]

started to claim that the obliviousness approach is not well-suited for AOP, as classes

that where not developed with aspects in mind can lead to very complex pointcuts or join

points which are not able to be captured by aspects. In this work we consider that, in

order to achieve a better modularity between OO and AO code, class developers should

be aware of aspects and its behavior.

2.3 CAESARJ

CaesarJ [10] is a Java [28] based aspect-oriented programming language with a strong

support for reusability and modularity of components. It combines the AO constructs,

pointcuts and advice, with advanced object-oriented modularization mechanisms. From

an aspect-oriented point of view, this combination of features is particularly well-suited

to make large-scale aspects reusable - one can say, it enables aspect components. From a

1Figure adapted from http://commons.wikimedia.org/wiki/File:AspectJ_Weaving.svg.

Page 24: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.3 CAESARJ 9

Figure 2.1 Aspect weaving process

component-oriented view, on the other hand, CaesarJ is addressing the problem of inte-

grating independent components into an application without modifying the component

to be integrated or the application [4].

First proposed as Caesar, CaesarJ has a higher-level module concept on top of Join

point interception (JPI), an important cornerstone of AO languages, providing a better

support for expressing an aspect as a set of collaborating abstractions, and for structuring

the interaction between two parts of an aspect, aspect implementation and aspect binding

(integration with a base code) [42].

CaesarJ is not completely independent from Java, its classes interact with Java classes

and interfaces, and the program main class must be a Java class. Moreover, CaesarJ

compiler generates Java bytecode, using the AspectJ weaver to insert the advice calls into

the generated bytecode.

On the next sections a few concepts and constructs of CaesarJ used in this work are

described. More details about the language can be found on [10, 4].

2.3.1 Caesar Classes

The principal module on CaesarJ is a caesar class, represented by the keyword cclass.

Di"erent from a Java class, a caesar class can have both roles of classes (OO) and aspects

(AO) at the same time. An aspect on CaesarJ is a cclass with AspectJ based pointcuts

and/or advice. They can be instantiated and referenced as any other object, its references

Page 25: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.3 CAESARJ 10

can be polymorphic, enabling aspectual polymorphism, and multiple instances of an

aspect can be created and used simultaneously.

Di"erent from AspectJ, aspects on CaesarJ are not enabled by default, they must be

explicitly activated (deployed), otherwise its pointcuts will not match any join point and

its advice will not be executed. Caesar classes can be statically or dynamic deployed, as

we can see on Listing 2.4.

Listing 2.4 Caesar class example: classic Figure-Display problem

1 public deployed cclass DisplayUpdate {

2 pointcut moveFigure ( FigureElement f e ) : ( ca l l (void FigureElement+. s e t ! ( . . ) )

3 | | ca l l (void FigureElement+.moveBy ( . . ) ) && ta r g e t ( f e ) ;

4

5 after ( FigureElement f e ) : moveFigure ( f e ) {

6 Display . update ( f e ) ;

7 }

8 }

9

10 public abstract cclass LogAspect {

11 pointcut pointChange ( Point p ) : t a r g e t (p ) && ( ca l l (void Point . s e t ! ( . . ) )

12 | | ca l l (void Point .moveBy ( . . ) ) ) ;

13 }

14

15 public cclass SimpleLog extends LogAspect {

16 after ( Point p ) : pointChange (p) {

17 System . out . p r i n t l n ( ”Point ” + p + ” changed . ” ) ;

18 }

19 }

20

21 public cclass Detai l edLog extends LogAspect {

22 void around( Point p ) : pointChange (p) {

23 System . out . p r i n t l n ( ”Point ” + p + ” actua l coords : ” p . getCoords ( ) ) ;

24 proceed ( ) ;

25 System . out . p r i n t l n ( ‘New coords o f ’ + p + ‘ : ’ p . getCoords ( ) ) ;

26 }

27 }

28

29 public class Main {

30 public stat ic void main ( Str ing [ ] a rgs ) {

31 Point p1 , p2 ;

32 LogAspect l a ;

33 . . .

34 i f ( deta i l edLog ) l a = new Detai l edLog ( ) ;

35 else l a = new SimpleLog ( ) ;

36 . .

37 deploy ( l a ) {

38 p1 .moveBy ( 5 ) ;

39 }

40 p2 .moveBy ( 3 ) ;

41 }

42 }

Page 26: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.3 CAESARJ 11

The code depicted above is an extension of the classic Figure-Display example, which

has Point and Line as subclasses of FigureElement. The deployed keyword in Line 1

specifies that DisplayUpdate is statically activated, working like an aspectj aspect. Lines

34-35 show the dynamic selection and instantiation of LogAspect, while Line 37 shows its

dynamic deploy (deploy keyword). Moreover, Lines 37-39 specifies LogAspect scope of

actuation, this aspect can intercept everything can be reached by commands within this

block. It means that the join point of Line 40 (calls to Point.moveBy method, defined

on pointChange pointcut, Lines 11-12) is only matched by DisplayUpdate aspect. As

we can see on Lines 16 and 22, pointcut inheritance is allowed on CaesarJ.

Caesar classes can only inherit from other caesar classes, its not possible for them

to inherit from a Java class. However, they can implement Java interfaces. In order to

facilitate comprehension and maintain consistency with other languages, we use the term

CaesarJ class throughout this work to reference a caesar class.

2.3.2 Aspects Collaboration Interfaces - ACIs

Collaboration Interfaces (CI) were proposed by Mezini and Osterman to cope with some

limitations existent on standards interfaces [41]. On CaesarJ the CI concept was extended

to support the use of AO constructs, originating the Aspect Collaboration Interfaces

(ACIs). An ACI is a cclass which groups a set of collaboration CaesarJ classes (inner

classes).

Di"erent from Java, on CaesarJ all inner classes of a given cclass are considered

virtual classes [39], as they are handled in the same way as virtual methods. They can

be redefined in subclasses of the enclosing class, allowing us to incrementally refine a set

of collaborating classes, as we can see on Listing 2.52.

Graph is a collaboration that groups classes Edge, DirectedEdge and Node. The col-

laboration WeightedGraph inherits from Graph, redefining Edge and Node, adding the cost

attribute. As references to virtual classes are always bound to the most specific redefini-

tion known in the context of the enclosing object, the superclass of WeightedGraph.

DirectedEdge is bound to WeightedGraph.Edge. Moreover, accessing the variables

start and end in the context of WeightedGraph allows us to use the newly introduced

properties of WeightedGraph.Node, although the declaration was made in Graph.Edge

itself.

That way, it is possible to refine classes of a collaboration, introducing new methods,

2Example adapted from http://caesarj.org/index.php/ProgrammingGuide/BasicConcepts

Page 27: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.3 CAESARJ 12

fields and class relationships. Thus, it is not necessary to repeat previously defined inher-

itance relationships, methods and attributes. For example, if we redefine DirectedEdge

on WeightedGraph, its not necessary to declare it as a subclass of Edge, this relationship

is automatically inherited, as WeightedGraph.DirectedEdge is identified as a refinement

of Graph.DirectedEdge.

Listing 2.5 Set of collaboration classes (ACI) for the graph example

1 public cclass Graph {

2 public cclass Edge {

3 Node s tar t , end ;

4 }

5 public cclass DirectedEdge extends Edge {

6 int d i r e c t i o n ;

7 }

8 public cclass Node {

9 public abstract void getState ( ) ;

10 }

11 }

12

13 public cclass WeightedGraph extends Graph {

14 public cclass Edge {

15 f loat cos t ;

16 }

17 public cclass Node {

18 f loat cos t ;

19 }

20 }

We can define ACIs that specify only abstract inner classes, which contain only ab-

stract operations. These kinds of ACIs can be seen as interfaces, as they have only design

purpose, without any implementation.

2.3.3 Mixin composition

On CaesarJ it is possible to compose two or more CaesarJ classes using the & operator

on the extends clause of a given cclass. This process is a type of multiple inheritance,

allowing a class to have more than one super class. As CaesarJ classes are translated

to conventional Java classes, which do not support multiple inheritance, CaesarJ uses a

mixin-based algorithm [17] to linearize all the composed classes, generating a hierarchi-

cally organized order of the superclasses.

Listing 2.6 shows an example of composition using mixins. On the depicted code,

ColoredWeightedGraph is a composition of both ColoredGraph and previously defined

WeightedGraph (Line 28). On that way, ColoredWeightedGraph contain both vir-

Page 28: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.3 CAESARJ 13

tual classes originated from ColoredGraph and WeightedGraph. Moreover, virtual class

Node of composition ColoredWeightedGraph contains attributes from ColorGraph.Node,

WeightedGraph.Node and Graph.Node. Figure 2.2 shows the superclass hierarchy gener-

ated after the execution of the mixin linearization process.

Listing 2.6 Mixin composition example

22 public cclass ColoredGraph extends Graph {

23 public cclass Node {

24 Color co l o r ;

25 }

26 }

27

28 public cclass ColoredWeightedGraph extends ColoredGraph & WeightedGraph { }

!"#"$%&'%()*%&+$,-* !"#"$%&+$,-* '%()*%&+$,-* +$,-*

Figure 2.2 Mixin linearization: Generated inheritance hierarchy

An interesting point about mixin composition is the way how it manages inheritance

links between virtual classes. A collaboration can refine its super collaboration with

new virtual classes and new inheritance links. The inheritance hierarchies of such refine-

ments can be merged using mixin composition. For example, suppose that we have a

new kind of graph, SpecialColoredWeightGraph, which refines ColoredWeightedGraph

(Listing 2.7).

Listing 2.7 SpecialColoredWeightedGraph collaboration

30 public cclass SpecialColoredWeightedGraph extends ColoredWeightedGraph {

31 public cclass Specia lEdge extends Edge {

32 . . .

33 }

34 public cclass DirectedEdge extends Specia lEdge {

35 }

36 }

This new collaboration defines a new edge, SpecialEdge (lines 31-33), which inher-

its from the previously defined Edge class. Besides that, this new collaboration refines

DirectEdge (Line 34), declaring that it now inherits from SpecialEdge (initially it was

subclass of Edge, as we can see on Line 5 of Listing 2.5).

Figure 2.3(a) shows the contents of ColoredWeightedGraph. The gray boxes rep-

resent virtual classes and relationships which were inherited, not declared inside the

Page 29: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.3 CAESARJ 14

!"#"$%&'%()*%&+$,-*

(a)

!"#$%&'()')*#+,#%-.#+/*&".

(b)

Figure 2.3 ColoredWeightedGraph (a) refined by SpecialColoredWeightedGraph (b)

ColoredWeightedGraph cclass itself. Figure 2.3(b) depicts SpecialColoredWeightGraph.

The black boxes represent virtual classes declared or refined inside this new collaboration,

while the gray boxes are virtual classes inherited from ColoredWeightedGraph. As we

can see, the inheritance of DirectedEdge is modified, now it inherits from the new de-

clared cclass SpecialEdge. Although DirectedEdge is an empty cclass on Listing 2.7,

due to the refinement properties of CaesarJ virtual classes we can access all operation

and attributes of Graph.DirectedEdge (like direction, see Line 6 of Listing 2.5) when

using objects of SpecialColoredWeightedGraph.DirectedEdge.

2.3.4 Wrapper Classes

Wrapper is a mechanism introduced in CaesarJ to adapt (bind) an existing class to a role

defined in a collaboration. Wrapper classes, which are identified by the wraps clause (like

extends), are virtual classes which depend on an application object. They can access the

state of the enclosed object using the wrappee keyword, and can potentially introduce

additional state and operations to the wrapped object.

Listing 2.8 shows an example of wrapper classes, adapting existing classes Point and

Shape to the Node role defined on the Graph collaboration (see Listing 2.5). As wrapper

classes were proposed to increase reuse, it is possible to reuse the implementation of Edge,

DirectEdge and part of Node implementation (Graph Impl, Lines 38-42) and adapt the

Node role to its specific usage. When a Point is a node, the state of this node is given by

the coordinates of the Point, whereas the state of a node is the state of a Shape object

when we have a Node being a Shape.

As we can see on Listing 2.8, first Graph Impl is composed with PointWrappers to

Page 30: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.4 DEVELOPMENT OF CLASSES AND ASPECTS: MODULARITY ISSUES 15

generate PointGraph (Line 57) and then the same implementation is reused and com-

posed with ShapeWrapper to generate ShapeGraph (Line 58). Although on this example

we are not showing any reuse of wrapper classes, it is also possible. If we have an-

other implementation of Graph, like ColoredGraph , we can reuse the existing bindings

PointWrapper and ShapeWrapper to generate new combinations of graph on which points

and shapes represent the nodes.

Listing 2.8 Wrapper classes

38 public cclass Graph Impl extends Graph {

39 public cclass Edge { . . . }

40 public cclass DirectedEdge { . . . }

41 public cclass Node { . . . }

42 }

43 public cclass PointWrapper extends Graph {

44 public cclass PointNode extends Node wraps Point {

45 public void getState ( ) {

46 System . out . p r i n t l n ( ” ( ” wrappee . getX ( ) , + ” , ” + wrappee . getY ( ) +” ) ” ) ;

47 }

48 }

49 }

50 public cclass ShapeWrapper extends Graph {

51 public cclass ShapeNode extends Node wraps Shape {

52 public void getState ( ) {

53 System . out . p r i n t l n (wrappee . ge tState ( ) ) ;

54 }

55 }

56 }

57 public cclass PointGraph extends Graph Impl & PointWrapper { }

58 public cclass ShapeGraph extends Graph Impl & ShapeWrapper { }

2.4 DEVELOPMENT OF CLASSES AND ASPECTS: MODULARITY ISSUES

As previously introduced in Section 2.2, Aspect-Oriented Programming (AOP) has been

proposed as a technique for modularizing crosscutting concerns. However, the use of AOP

can bring modularity problems, as developers must consider all aspect implementations

in order to reason about a specific class [57, 54, 12].

By referring to class implementation details in aspects, one can compromise modular

reasoning and changeability, requiring class modifications to be fully aware of which as-

pects a"ect a given class. Therefore, constructs aimed to support crosscutting modularity

might actually break class modularity [51]. As there is no interface between classes and

aspects, the parallel development of them is also compromised.

In order to avoid this conflict, some authors discuss how to expose aspect-oriented

interfaces and how to compute module interfaces in AOP systems. Sullivan initially

Page 31: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.4 DEVELOPMENT OF CLASSES AND ASPECTS: MODULARITY ISSUES 16

!"#$%&'&$())!"#$%&!'!!!!$%&!()!*+''''!"#$%&'*+%,!,-&./$%&!(0!'!&1$,2(!3!(!4''''!"#$%&'*+%,!,-&5/$%&!*0!'!&1$,2*!3!*!4!!!!!!!!2224

!"#$%&'()!-&.!6789&-:$,7;9*!'''''!+%/.&".'7#$%&6789&-/"#$%&!70<!.(01-./70!=''''''''')-./>!"#$%&2>0!??!&($$/>!"#$%&2,-&>/2200+''''(2.-0/"#$%&!70<!7#$%&6789&-/70!'!!!!!!!!!:$,7;9*2@789&-/70+!!!!!44

!"#$$%&'('")*'+

,-.%&/$*"#0%/$%1)2%3'/14%5*6#2'6%%%%%%7-'1%#%8)/12%9-#14':%;%1''6%2)%6)%/22

<$*'92%&'('")*'+

='0>%?*6#2'&/$*"#0%#$*'92%#"+'#60%%%%%%5*6#2'$%&/$*"#0@%&)1A2%0)5%$''%/2:

Figure 2.4 Modularity Issues between Classes and Aspects

presented a comparative analysis between an AO system developed using an oblivious

approach and the same system developed using design rules which document interfaces

between classes and aspects [57]. The approach using design rules promises benefits when

relevant crosscutting behavior is anticipated. However, this solution uses natural language

to express the design rules, which may lead to verbose and ambiguous interpretation, not

mentioning the fact that it cannot be statically checked.

In later works [24, 56], they propose to express and check the design rules using

AspectJ, calling the approach Crosscutting Programming Interfaces (XPI). They claim

that one of the main benefits of its approach is that it does not require any new construct

in the language. However, as AspectJ was not designed for this purpose, its not possible to

express and check most constraints required for defining the responsibilities of classes and

aspects using the proposed XPI language, and the written specification can become very

complex. Natural language is used along with AspectJ code to specify some restrictions.

Costa Neto proposed a Language for Specifying Design Rules (LSD) [44] in order to

enable the definition of more precise design rules between OO and AO code. LSD Design

Rules impose both structural and behavioral restrictions over Java and AspectJ code, and

its compiler is able to statically check most of these restrictions. Beside having a Java

and AspectJ-like syntax, LSD introduces many new constructs, which require developers

to learn a new language.

Compared to other AO languages, CaesarJ introduces many new features and benefits.

Our objective in this work is to enable the specification of design rules in CaesarJ, without

modifying the existing compiler. For this we propose CaesarJ+, an extension to CaesarJ

where code is pre-compiled and transformed into valid CaesarJ code. This extension is

Page 32: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

2.4 DEVELOPMENT OF CLASSES AND ASPECTS: MODULARITY ISSUES 17

presented on Chapter 4.

On the next chapter we discuss some issues found when using CaesarJ to specify

Design Rules to enable a more modular design.

Page 33: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CHAPTER 3

EXPLORING CAESARJ

In this chapter we explore the CaesarJ constructs Wrappers, Aspect Collaboration In-

terfaces and Mixin Composition introduced on Section 2.3, using them to implement

multiples versions of a Tetris Software Product Line (SPL) [47] example. A brief analysis

focusing on support for modular development of Aspect-Oriented and Object-Oriented

code is made for each implementation. This chapter is organized as follows: Section 3.1

describes the Tetris SPL example used in this chapter, whereas Sections 3.2, 3.3 and

3.4 describe implementations using Template Method, Mixin Composition and Wrapper

classes, respectively.

3.1 TETRIS SPL EXAMPLE

In order to explore the mentioned CaesarJ constructs, we use a simple Software Prod-

uct Line of Tetris games for mobile phones1. A SPL is an approach that enables the

generation of related software products from reusable assets, such as classes, aspects and

requirements, bringing an increase in productivity [47, 58]. This Tetris SPL generates,

among others, products (i) with normal di!culty, which shows only the next piece (tetris

block) that will appear, and (ii) with easy di!culty, showing the next two pieces, as

illustrated in Figure 3.1. It is important to note that some devices are not able to display

two next pieces, due to their limited screen-size.

As illustrated in the diagram of a single product of this SPL (Figure 3.2), TetrisCanvas

is the class responsible for organizing all components on the screen (board, pieces and

the information boxes), whereas the NextPiece class is responsible for showing the next

Tetris block (piece) that will appear on the game.

Starting from a single product, in order to implement the di!culty feature we need dif-

ferent versions (variations) of the following methods of NextPiece: (a) paintBox, which

is called by other methods of NextPiece (paint, for example) to repaint the box that

shows the next piece, and (b) updatePiece, which is called by the TetrisCanvas class to

update the next piece that will be displayed, as we can see in Figure 3.3. Also, there are

1The code of the single application used to extract this SPL can be downloaded at [31].

18

Page 34: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.1 TETRIS SPL EXAMPLE 19

Figure 3.1 Tetris game: normal di!cult (left) and easy di!cult (right).

+paint( g : Graphics ) : void+drawPiece( type : int ) : void+updatePiece() : void+paintBox( g : Graphics ) : void

...

NextPiece

-np : NextPiece...

+init() : void+sideBoxes() : void

...

TetrisCanvas

TetrisConstants

DropThread

TetrisBoard

TetrisMidlet

DisplayBox

TetrisPiece TitleBox InfoBox

Figure 3.2 Tetris Game - Single product diagram

Page 35: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.2 TEMPLATE METHOD 20

multiple scattered calls to NextPiece methods (updatePiece) on TetrisCanvas, which

is a class that does not need to vary to enable the di"erent variations of the di!culty fea-

ture. It is important to note that, when painting the box contents, the paintBox method

has to access non-variant members of NextPiece (like drawPiece, see Figure 3.3), which

characterizes a mutual (bi-directional) dependency: non-variant methods call variant

methods, while variant methods also call invariant operations.

Figure 3.3 Classes TetrisCanvas and NextPiece

There are multiple ways to implement these variations, including OO [40] techniques

(using design patterns) and AO techniques [34]. In order to analyze the support for mod-

ularity provided by CaesarJ we use in the following sections three di"erent approaches

(OO template method design pattern, Mixin Composition and Wrapper classes) to im-

plement the di!culty feature of this SPL using CaesarJ. For each approach we present

two di"erent implementations, one without using ACIs, and a second one using ACIs

to establish an interface that tries to guide the development of both common code and

variation code.

3.2 TEMPLATE METHOD

In this section we introduce CaesarJ implementations of the di!culty feature using the

Template Method design-pattern. Note that on Section 3.2.1 no CaesarJ specific con-

struct besides cclass is used in our implementations, while on section 3.2.2 the ACI

construct is introduced.

3.2.1 Template Method without ACIs

Listing 3.1 presents a possible implementation for the di!culty feature in CaesarJ using

the Template Method design pattern [21]. In this implementation we aim to achieve reuse

of the invariant (common) part of the feature implementation, while the variation part

Page 36: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.2 TEMPLATE METHOD 21

is implemented in separated modules.

Listing 3.1 Template Method

abstract cclass NextPiece {

. . .

void paint ( ) { . . . paintBox () ; . . . }

void drawPiece ( int type ) { . . . }

abstract void updatePiece ( ) ;

abstract void paintBox ( ) ;

. . .

}

cclass NormalVariation extends NextPiece {

void updatePiece ( ) { . . . }

void paintBox ( ) { . . . drawPiece ( type ) . . . }

}

cclass EasyVar iat ion extends NextPiece {

void updatePiece ( ) { . . . }

void paintBox ( ) { . . . drawPiece ( type ) . . . }

}

In this solution, NextPiece is an abstract cclass that contains the implementation

of the common code (methods that will not vary, as drawPiece) and the signature of

the variant methods, updatePiece and paintBox. As detached on the code, invariant

method paint calls paintBox, which characterizes the template method. Each variation

is implemented in a single cclass (NormalVariation and EasyVariation), which inher-

its from the invariant class (NextPiece), providing the code for the abstract methods. A

factory can be used to instantiate and return the proper variation for each product.

A problem with this implementation is that we have design and implementation

tangling (problem labeled P1). The specification of the variations (abstract signatures)

is tangled with the implementation of other NextPiece methods, which implies that the

variations can only be implemented after the invariant class is defined. It is not possible

to split the development between two teams, one responsible for the common part and

the other responsible for the variation part.

An enhancement to this solution would be the specification of an interface on top of

the NextPiece cclass (Listing 3.2), specifying the signatures of all methods (including

the variable ones). In this solution, NextPiece now only has the implementation of

the common methods, but remains abstract, because it only implements the invariant

methods of INextPiece. Variations continue to be implemented on NormalVariation

and EasyVarition cclasses, which were omitted because they are exactly the same as

described on Listing 3.1.

Page 37: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.2 TEMPLATE METHOD 22

Listing 3.2 Interface for Template Method

interface INextPiece {

. . .

void paint ( ) ;

void drawPiece ( int type ) ;

void updatePiece ( ) ;

void paintBox ( ) ;

}

abstract cclass NextPiece implements INextPiece {

. . .

void paint ( ) { . . . paintBox ( ) ; . . . }

void drawPiece ( int type ) { . . . }

. . .

}

Although it separates the design from implementation (solving P1), this enhancement

brings two problems: (P2) it is not possible to explicitly specify in the interface

which methods are related to common part and which are related to the varia-

tion part; and (P3) the variation code cannot be compiled independently of the

common code, because variations extend the class used for the implementation of the

invariant code (see Figure 3.4), which implies that a part of variation code development

can only be done after the implementation of the common code. Considering P2, one

can say that the use of comments on the interface is enough to specify the common and

the variation roles. In this way, developers may decide to follow or not the specification

of the comments. Thus, it is not possible to ensure (static check) that the specification

made by these comments is being obeyed, as comments are ignored by compilers.

INextPiece

NextPiece

EasyVariation NormalVariation

Figure 3.4 Template Method without ACIs: variations depend on invariant code (inheritance).

Page 38: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.2 TEMPLATE METHOD 23

3.2.2 Template Method with ACIs

Aiming to solve problems P2 and P3 (Section 3.2.1) we use ACIs to specify interfaces that

provide a more modular design, trying to enable the parallel development of common and

variate code. Our first thought was to generate a kind of Design Rule which specifies that

two roles are needed for this implementation, base and variation. As an ACI can contain

more than one cclass, we tried to use it as a container to specify the classes that must

be implemented in our code, in order to split the development of base and variations so

it can be done in parallel.

Listing 3.3 presents NextPieceACI, our first idea of design rule in CaesarJ for this

variant. In Line 1 we have the declaration of the interface, which is an ACI containing

another CaesarJ class. Lines 2 and 9 present the declaration of cclasses that must

be implemented. Lines 3-6 and 10-11 specify the methods that must be present on the

implementation of the virtual classes, similar to a Java interface. However, as specified

on Section 3.1, the di!culty feature demands a mutual dependency between base and

variation (paintBox is called by other methods of NextPiece - e.g. paint, and paintBox

uses another methods of NextPieceBase - e.g. drawPiece), which is not possible to

specify using the design rule of Listing 3.3, as methods of NextPieceBase can not see

methods of NextPieceVariation.

Listing 3.3 NextPieceACI, Template Method

1 abstract cclass NextPieceACI {

2 abstract cclass NextPieceBase {

3 . . .

4 abstract void paint ( ) ;

5 abstract void drawPiece ( int type ) ;

6 . . .

7 }

8

9 abstract cclass NextPieceVar iat ion extends NextPieceBase {

10 abstract void updatePiece ( ) ;

11 abstract void paintBox ( ) ;

12 }

13 }

Listing 3.4 shows a CaesarJ interface that enables this mutual dependency. Lines 7 and

8 are the only di"erence between this interface and the one in Listing 3.3. At a first glance,

these lines look unnecessary because they are re-declared at NextPieceVariation, which

is a sub-class of NextPieceBase. However, they enable the use of both updatePiece

and paintBox by members of NextPiece, enabling the bi-directional dependency. This

mutual dependency could be easily achieved with the use of AspectJ like intertype dec-

Page 39: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.2 TEMPLATE METHOD 24

larations, which are not supported by CaesarJ.

Listing 3.4 NextPieceACI enabling the bi-directional dependency, Template Method

1 abstract cclass NextPieceACI {

2 abstract cclass NextPieceBase {

3 . . .

4 abstract void paint ( ) ;

5 abstract void drawPiece ( int type ) ;

6

7 abstract void updatePiece ( ) ;

8 abstract void paintBox ( ) ;

9 . . .

10 }

11

12 abstract cclass NextPieceVar iat ion extends NextPieceBase {

13 abstract void updatePiece ( ) ;

14 abstract void paintBox ( ) ;

15 }

16 }

Listing 3.5 shows the implementation of the NextPieceACI interface. As our interface

is a Collaboration Interface, its roles (inner cclasses) must be implemented by virtual

classes, inside collaborations that inherit from our design rule. On Line 1 we have the

declaration of NextPiece Impl, a collaboration that inherits from NextPieceACI. This

collaboration is abstract because it only implements the invariant role of the interface.

Lines 2-7 show the refinement of the virtual class NextPieceBase, which was previ-

ously defined on the ACI. This refinement implements the methods of NextPieceBase

role. However, this refined class cannot be instantiated (abstract), because methods

updatePiece and paintBox present on NextPieceBase are only implemented by the

variations.

Listing 3.5 Implementations of NextPieceACI, Template Method

1 abstract cclass NextPiece Impl extends NextPieceACI {

2 abstract cclass NextPieceBase {

3 . . .

4 void paint ( ) { . . paintBox ( ) . . . }

5 void drawPiece ( int type ) { . . . }

6 . . .

7 }

8 }

9

10 cclass EasyVar iat ion Impl extends NextPiece Impl {

11 cclass EasyVar iat ion extends NextPieceVar iat ion {

12 void updatePiece ( ) { . . . }

13 void paintBox ( ) { . . . drawPiece ( type ) . . . }

14 }

15 }

Page 40: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.2 TEMPLATE METHOD 25

EasyVariation Impl (10-15) is the collaboration which contains EasyVariation (Lines

11-14), a virtual class responsible for the implementation of NextPieceVariation (vari-

ation role of our interface). Other variants (such as normal) would have similar code

structure, di"ering only on the implementation of the methods that vary (updatePiece

and paintBox). In that way, now developers must instantiate first the cclass that con-

tain the implementation of the virtual class, and then they can instantiate the virtual

class itself, as we can see on Listing 3.6

Listing 3.6 Instantiation of the variation

public class Main {

public stat ic void main ( Str ing [ ] a rgs ) {

. . .

EasyVar iat ion Impl easyImpl = new EasyVar iat ion Impl ( ) ;

NextPieceACI . NextPieceVar iat ion easyVar = easyImpl .new EasyVar iat ion ( ) ;

. . .

}

}

Analyzing the interface NextPieceACI (Listing 3.4), we see that it completely solves

P1, this interface is only concerned with design. Although the interface contains two

abstract inner-classes that must be implemented, it is explicitly stated if updatePiece

and paintBox should be implemented only by the variations (NextPieceVariation sub-

classes) or if it should be implemented by the base part (subclasses of NextPieceBase)

and redefined by the variations. It may mislead the developers when looking only at the

ACI, leaving problem P2 only partially solved. Besides that, as we can see on the im-

plementation of the interface (Listing 3.5), due to the use of the template method design

pattern, the implementation of the variations are still coupled with the implementation

of the base code. As the implementation of the variations inherits from the common code

implementation (for example, EasyVariation Impl extends NextPiece Impl), it is not

possible to have a separated compilation of the variations (P3), as on Section 3.2.1.

Moreover, the code of Listing 3.5 is a little confusing. The use of virtual classes

makes the code harder to understand (confuse) (P4). It is necessary to write both

collaborations, NextPiece Impl and EasyVariation Impl, only to contain the virtual

classes implementing NextPieceACI roles. The result code would be simpler and cleaner

if we had a solution in which NextPieceBase and EasyVariation could be directly

written in top-level classes (without using virtual classes), respecting the specifications

of our interface.

Table 3.1 summarizes the problems faced on this section. A “-” in a cell represents

that a problem does not occur on a given approach, while “X” indicates that a problem

Page 41: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.3 MIXIN COMPOSITION 26

occurs and “O” means that a problem partially occurs using a approach.

Table 3.1 Problems on Template Method solution

Template Method

Problems No ACI ACI

P1 - Design and implementation tangling O -

P2 - Roles not well defined on the interface X O

P3 - No separate compilation X X

P4 - Confusing code due to use of virtual classes - X

P1 occurs only on the first solution of Section 3.2.1, while the second solution using a

Java interface and the solutions using ACI avoid this problem. P2 can only be partially

avoided on the solutions with ACI, the ACI is confusing due to the repetition of methods

on both common and variation roles (see Listing 3.4). P3 occurs on both solutions (with

and without ACI), due to the use of template method on the implementation, while P4

arises from the use of virtual classes, which brings overhead to the code.

3.3 MIXIN COMPOSITION

One of CaesarJ constructs is the mixin-based composition mechanism [17], which enables

a class to have multiple super classes (multiple inheritance). With the use of mixins we

can partially implement a CaesarJ class (or a collaboration) in multiple modules and

then join these implementations in a single module. In this section we explore the use of

CaesarJ mixins to implement our SPL example, trying to achieve a more modular design,

which enables the parallel development of common and variation code. Throughout this

section we show two types of implementations, with and without using ACIs.

3.3.1 Mixins without ACIs

Our first use of mixins to implement the di!culty feature is very similar to the INextPiece

of Listing 3.2. The only di"erence is that we use an abstract CaesarJ class as our inter-

face (instead of a traditional one) and implement it in separate modules, NextPieceBase,

EasyVariation and NormalVariation, as we can see on Figure 3.5.

Analyzing the figure, NextPieceConcrete is the class that joins the partial implemen-

tations of base and variations, defining which variation would be used. On Listing 3.7

Page 42: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.3 MIXIN COMPOSITION 27

Figure 3.5 Diagram of Mixin implementation without use ACIs

we can see a possible implementation of NextPieceConcrete, which specifies the use of

EasyVariation on the mixin list (extends clause). To enable other variations we can

have multiple versions of NextPieceConcrete, each one with a di"erent variation on

the extends clause, and then use a build mechanism along with a Configuration Knowl-

edge [16, 7] to put the specific NextPieceConcrete for each product of the SPL.

This solution enables the independent compilation of common and variation code, now

they depend only on NextPiece interface. However, NextPiece has the aforementioned

problem P2 (Section 3.2.1), it is not clear that two di"erent roles are specified on this

interface, which should be used as a guide for the development of common and variantion

roles. Besides that, on this implementation developers handle instances of the mixin

class, instead of instantiating classes that they implemented (NextPieceBase or

EasyVariation). We label this problem as P5. On this example, NextPieceConcrete

is the mixin class, it joins the classes that implement the ACI. In this way, developers

need to create objects of NextPieceConcrete type, but there is no specification of this

class-name on the interface, and developers cannot change this name without defining a

new cclass.

Listing 3.7 NextPieceConcrete class: Mixin of NextPieceBase and EasyVariation

cclass NextPieceConcrete extends NextPieceBase & EasyVar iat ion {

}

Next we show our implementation of the di!culty feature using ACIs, trying to solve

the open problems.

Page 43: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.3 MIXIN COMPOSITION 28

3.3.2 Mixins with ACIs

Looking back to the interface (ACI) of Listing 3.4 and its implementation (Listing 3.5,

section 3.2.2), we can see that variations depend on the invariant code due to the inheri-

tance relationship, which is necessary because this implementation follows the template

method design pattern. Using mixin composition we can partially implement our inter-

face, eliminating this dependency, as we can see on Listing 3.8, keeping the same ACI of

Listing 3.4.

Lines 1-8 depict the implementation of the common part, NextPiece. Here, di"erent

from Listing 3.5, as variation code does not depend on common code implementation, the

virtual class that implements the invariant code can refine or extend the NextPieceBase

role (we can see in in Line 2 that inheritance is being used).

In Lines 10-15 of Listing 3.8 we have the definition of EasyVariation Impl, collabo-

ration responsible for the implementation of the variation code. Di"erent from the tem-

plate method version, the variations now depend only on the interface (NextPieceACI),

enabling the independent compilation of common and variation code (solving P3). Be-

sides that, this collaboration can not be instantiated, because it implements only part

of the interface. Instead, developers now have to instantiate the composition of both

invariant and variant code (P5), which is represented by NextPieceConcrete, defined

inside of mixin NextPieceMixin (18-21). This is a drawback of this solution, because, as

aforementioned, there is no specification of NextPieceConcrete nor NextPieceMixin on

NextPieceACI (our interface) and it is not possible to specify it dynamically. Moreover,

as we are using the same ACI of Listing 3.4, problem P2 remains open.

Listing 3.8 Implementation of NextPieceACI using Mixin Composition

1 abstract cclass NextPiece Impl extends NextPieceACI {

2 abstract cclass NextPiece extends NextPieceBase {

3 . . .

4 void paint ( ) { . . paintBox ( ) . . . }

5 void drawPiece ( int type ) { . . . }

6 . . .

7 }

8 }

9 abstract cclass EasyVar iat ion Impl extends NextPieceACI {

10 abstract cclass EasyVar iat ion extends NextPieceVar iat ion {

11 void updatePiece ( ) { . . . }

12 void paintBox ( ) { . . . drawPiece ( type ) . . . }

13 }

14 }

15 cclass NextPieceMixin extends NextPiece Impl & EasyVar iat ion Impl {

16 cclass NextPieceConcrete extends NextPiece & EasyVar iat ion { }

17 }

Page 44: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.3 MIXIN COMPOSITION 29

Also, the use of mixin composition to implement collaborations allows us to define

roles on the interface (ACI) that are not on the same hierarchy, which was not possible

using template method. Our interface of Listing 3.4 (NextPieceACI, template method)

only defines two virtual classes because they are on the same hierarchy (one extends

the other). That way, we can now specify another role on NextPieceACI, for example,

Canvas. The definition of this role on the ACI is useful to avoid the scattered calls of

the updatePiece method, which occurs on the TetrisCanvas class, as introduced on

Section 3.1. As an aspect on CaesarJ is a simple cclass with pointcuts or advice, we can

extend NextPieceBase with a pointcut that captures the execution of Canvas methods

that call updatePiece (see Figure 3.3), as we can see on Listing 3.9. We could also have

defined pointcuts and advice on the solution of Section 3.2.2. However, due to the use of

the Template Method design-pattern on the implementation, it is not possible to specify

the Canvas role on the ACI, which is essential to guarantee that the desired join points

could be match.

The enhanced version of NextPieceACI now has three roles. NextPieceVariation is

exactly the same of Listing 3.4. Canvas (Lines 19-22), the new virtual class, defines that

methods init and sideBoxes must exist. In this way, we can write a pointcut on the

base role that matches executions of these methods, as we can see on NextPieceBase’s

matchCanvas (9-10).

Listing 3.9 NextPieceACI with the Canvas role

1 abstract cclass NextPieceACI {

2 abstract cclass NextPieceBase {

3 . . .

4 abstract void paint ( ) ;

5 abstract void drawPiece ( int type ) ;

6

7 abstract void updatePiece ( ) ;

8 abstract void paintBox ( ) ;

9 pointcut matchCanvas ( ) : execut i on (! Canvas . i n i t ( ) )

10 | | execut i on (! Canvas . s ideBoxes ( ) ) ;

11 . . .

12 }

13

14 abstract cclass NextPieceVar iat ion extends NextPiece {

15 abstract void updatePiece ( ) ;

16 abstract void paintBox ( ) ;

17 }

18 abstract cclass Canvas {

19 abstract void i n i t ( ) ;

20 abstract void s ideBoxes ( ) ;

21 }

22 }

Page 45: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.3 MIXIN COMPOSITION 30

Listing 3.10 Mixin implementation of NextPieceACI with Canvas role

1 abstract cclass NextPiece Impl extends NextPieceACI {

2 abstract cclass NextPiece extends NextPieceBase {

3 . . .

4 void paint ( ) { . . paintBox ( ) . . . }

5 void drawPiece ( int type ) { . . . }

6

7 after ( ) : matchCanvas ( ) { . . . updatePiece ( ) ; . . . }

8 . . .

9 }

10 }

11

12 cclass Tetr i sCanvas Impl extends NextPieceACI {

13 cclass Tetr i sCanvas extends Canvas {

14 void i n i t ( ) { . . . }

15 void s ideBoxes ( ) { . . . }

16 }

17 }

18

19 cclass NextPieceMixin extends NextPiece Impl & EasyVar iat ion Impl & Tetr i sCanvas Impl {

20 cclass NextPieceConcrete extends NextPiece & EasyVar iat ion {

21 }

22 }

Listing 3.10 shows the implementation of this enhanced NextPieceACI. Lines 1-10

depict the collaboration that defines the implementation of the base part. The main

di"erence here is that we have an after advice which uses the matchCanvas pointcut

defined on the NextPieceBase role of NextPieceACI. This advice is responsible for

calling updatePiece, which is a variation method defined on both base and variation

roles, enabling invariant methods to call it, every time matchCanvas matches a join point

on the execution of our system. We omit the implementation of the variation role because

it is the same of Listing 3.8 (EasyVariation Impl). TetrisCanvas Impl (12-17) is the

collaboration that defines TetrisCanvas, the implementation of Canvas role.

The composition mixin NextPieceMixin (19-22) joins the implementation of the three

roles specified in the interface. It defines NextPieceConcrete class, which joins the im-

plementation of both NextPieceBase and NextPieceVariation roles, creating a concrete

class. NextPieceConcrete is necessary due to the bi-directional dependency of the roles

NextPieceBase and NextPieceVariation, which can be developed in parallel. In order

to support this dependency, the signature of some variation methods are redefined inside

the base definition. This way, implementation of both invariant and variation roles must

be abstract (because they only implement part of the role). This inner-mixin is necessary

to enable the instantiation of one of these classes.

As the Canvas role does not depend on any other role, its implementation can

Page 46: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.3 MIXIN COMPOSITION 31

be concrete and no other inner-mixin related to Canvas needs to be specified inside

NextPieceMixin. It is important to note that on scenarios without this mutual depen-

dency the partial implementations do not need to be abstract (like Canvas for example,

which does not vary), and it is not necessary to define a virtual mixin (NextPieceConcrete)

composing the partial implementations inside the mixin class.

Our extended interface of Listing 3.9 has the same drawbacks P2 and P4 of the solu-

tion introduced on Listing 3.5. Moreover, the use of CaesarJ mixin composition brings

us another problem: CaesarJ compiler only obligates the implementation of vir-

tual classes of concrete collaborations [4]. We label this problem P6. As we are

using NextPieceACI as a kind of design rule, our objective is to obligate the implemen-

tation of all the roles specified inside it, which is not enforced by the CaesarJ compiler.

Therefore, if our composition mixin NextPieceMixin lacks the implementation for the

Canvas role (as we can see on Listing 3.11), or the implementation of both dependent roles

NextPieceBase and NextPieceVariation, no error message is given by the compiler.

As the NextPieceBase role of NextPieceACI specifies a pointcut that references the

Canvas role, if Canvas is not implemented as specified on the interface the pointcuts may

not match any join point, disabling advice that use these pointcuts.

Listing 3.11 Invalid mixin NextPieceMixin: No error given by CaesarJ compiler.

cclass NextPieceMixin extends NextPiece Impl & EasyVar iat ion Impl {

cclass NextPieceConcrete extends NextPiece & EasyVar iat ion {

}

}

Table 3.2 Problems on Mixin solutions

Mixin Implementations

Problems No ACI ACI

P2 - Roles not well defined on the interface X O

P4 - Confusing code due to use of virtual classes - X

P5 - Instantiate only mixin classes X X

P6 - Compiler does not check all ACI roles - X

Table 3.2 summarizes the problems faced on this section. As aforementioned, P2

remains partially opened, while P4 occurs on solutions with ACI, which use virtual classes.

P5 obligates developers to instantiate only objects of the mixin type, instead of objects

of the type of classes used to implement the roles. It is important to note that P6 only

Page 47: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.4 WRAPPERS 32

occurs because the solution with ACI enables the specification of multiple roles in a single

interface, which is very useful for writing design rules.

3.4 WRAPPERS

Wrapper classes are used on CaesarJ as a mechanism to adapt external classes, intro-

ducing new state and operations on it dynamically [4]. On this section we explore this

feature of CaesarJ, trying to implement the variations as Wrapper classes that adapt

classes containing the invariant behavior, aiming to achieve a more modular design which

enables the reuse of the common code.

3.4.1 Wrappers without ACIs

In order to instantiate a wrapper class we need to specify an instance of the class that

is wrapped. As Wrapper classes were proposed to adapt an existing class to a specific

context of a collaboration, we use in our example NextPiece as the class to be wrapped

(containing the invariant code) and we define a collaboration for each variation, in order

to enable the adaptation of the common code to the specific context of each variation.

Thus, in order to instantiate a variation we use a invariant-type object as a parameter

(i.e. developers have to handle at least instances of two di"erent types). Our first

implementation using wrappers is shown on Listing 3.12.

Listing 3.12 First implementation using wrappers

1 cclass NextPiece {

2 void paint ( ) { . . paintBox ( ) . . . }

3 void drawPiece ( int type ) { . . . }

4 }

5

6 cclass EasyVar iat ion Impl {

7 cclass EasyVar iat ion wraps NextPiece {

8 void updatePiece ( ) { . . . }

9 void paintBox ( ) { . . . wrappee . drawPiece ( type ) . . . }

10 }

11 }

Lines 6-11 depicts the EasyVariation Impl, collaboration responsible for the defini-

tion of the wrapper cclass EasyVariation (7-10). On CaesarJ all wrapper classes must

be virtual classes, it is not possible to declare top-level (not virtual) wrapper classes,

that is the only reason we declare EasyVariation Impl in this solution, as the wrapper

class EasyVariation must be a virtual class. As we can see on Line 7 (keyword wraps),

EasyVariation is responsible for wrapping objects of NextPiece (1-4) type. However,

Page 48: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.4 WRAPPERS 33

this implementation does not compile. As we can see on Line 2, due to the bi-directional

dependency of invariant and variation code, the paint method calls paintBox, which

is defined only on the variation. Methods of the invariant class NextPiece cannot see

variation methods, invariant code cannot depend on variant code (P7). On the

other hand, the variation, implemented on the wrapper class EasyVariation, can easily

access all methods and attributes of the common class (wrapped class) using the wrappee

keyword, as depicted in Line 9.

One way to implement the di!culty feature using wrapper classes is to remove the

common-variation dependency using inversion of control (pointcuts and advices). In this

way, methods of NextPiece would no longer call the variant methods (updatePiece or

paintBox), while methods that vary are free to access invariant methods by using the

wrappee keyword, as we can see on Listing 3.13.

The common code now does not depend on the variation code directly. Instead, the

variation has an advice that acts after the execution of NextPiece paint method (6-8).

Although it may work on this small example, on more complicated cases it is not that

simple to invert that dependency using pointcuts and advice only. Sometimes it is not

possible to write a pointcut that matches the exact join point desired, being necessary to

re-write the code adding a hook method to enable the match of a given pointcut.

Listing 3.13 Wrapper class EasyVariation with inversion of control

1 cclass EasyVar iat ion Impl {

2 cclass EasyVar iat ion wraps NextPiece {

3 void updatePiece ( ) { . . . }

4 void paintBox ( ) { . . . wrappee . drawPiece ( type ) . . . }

5

6 after ( ) : execution (! NextPiece . paint ( ) ) {

7 updatePiece ( ) ;

8 }

9 }

10 }

Although there is no interface on the code snippets of this section, we can easily

define an interface (or an abstract cclass) on top of NextPiece (e.g. INextPiece) and

an abstract cclass on top of the variations. However, as wrapper classes must be virtual,

the design rule (abstract cclass) of the variations must be a collaboration containing a

virtual class specifying the methods that must be present on the variation. Besides that,

as the wrapper relationship is not inheritable nor can be redefined, it is not possible

to specify on this interface that a class must wrap another one (problem P8).

Without this information, developers, which are being guided by the interface, might not

know that variations must wrap a specific class.

Page 49: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.4 WRAPPERS 34

On the next section we describe the use of Wrapper classes with Aspect Collaboration

Interfaces to implement the di!culty feature.

3.4.2 Wrappers with ACIs

Using ACIs we can specify an interface that groups the specification of the invariant class,

which will be wrapped, and the variation class, the wrapper one, along with other classes

that may be used by our feature. This interface can be partially implemented on multiple

modules, which are then composed with mixins, as described on Section 3.3.2.

Listing 3.14 shows a possible ACI designed for the solution using wrapper classes.

This design rule is very similar to the solution presented on Listing 3.4 of Section 3.3.2,

the only di"erences are that invariant class (NextPiece) does not have the signatures

of updatePiece and paintBox and that variant class NextPieceVariation does not

inherits from the invariant class. In this interface we should be supposed to declare

that NextPieceVariation wraps from NextPiece. However, as wrapper inheritance nor

redefinition is allowed on CaesarJ, its not possible to specify on the ACI that one virtual

class wraps from another one (P8), that is why we put the wraps clause inside comments

on Line 9, meaning that this restriction cannot be enforced by the compiler.

Listing 3.14 NextPieceACI interface for Wrapper classes implementation

1 abstract cclass NextPieceACI {

2 abstract cclass NextPiece {

3 . . .

4 abstract void paint ( ) ;

5 abstract void drawPiece ( int type ) ;

6 . . .

7 }

8

9 abstract cclass NextPieceVar iat ion /!wraps NextPiece!/ {

10 abstract void updatePiece ( ) ;

11 abstract void paintBox ( ) ;

12 }

13 }

The solution using Wrapper classes with ACIs has all the advantages presented on

the solution of Section 3.3.2 (Mixins with ACIs). Considering the disadvantages, this

solution also has all the drawbacks listed on the aforementioned section plus problems

P7, wrappers can not express bi-directional dependency between two roles, and P8, which

may mislead developers that are being guided by the ACI.

Figure 3.6 depicts how the implementation of this ACI looks like. It is very similar

to the one listed on Section 3.8, however, besides inherit from the invariant class, the

Page 50: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.5 CHAPTER SUMMARY 35

!"#$%&"'"()*'+"$"

!"#$%&"'"!"#$%&"'"()*

!"#$%&"'"+,-&,$&./

Figure 3.6 Diagram of Wrapper implementation using ACIs

variations now wrap it. Moreover, the implementation of the invariant class can be done

using refinement of inheritance, although only refinement is presented in Figure 3.6.

On the next section we summarize all the problems enumerated on this chapter.

3.5 CHAPTER SUMMARY

Table 3.3 summarizes the problems described on this chapter. Lines represent the prob-

lems observed (P1, P2, ..., P8) while columns represent the approaches used on the

implementations (Template Methods without ACIs, Mixin using ACIs, etc.).

We can group the problems described in this chapter on two groups, major problems

(gray lines) and minor problems (white lines). By major problems we mean problems

that harm the modular development of OO and AO code. They are P1, P2, P3 and

P7. As in this work we want to enable this modular development on CaesarJ, it should

be possible to develop classes and aspects in parallel, depending only on a common

interface, and allowing a separated compilation (P3). In order to enable it, we need

an interface which clear states the multiple roles that should be developed separated

(P2). Moreover, in a SPL we have situations where a product di"er from another only

on specific implementations of certain operations of a given class. These operations may

Page 51: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

3.5 CHAPTER SUMMARY 36

Table 3.3 Problems Enumerated on this Chapter

Template Method Mixin Composition Wrapper Classes

Problems No ACI ACI No ACI ACI No ACI ACI

P1 O - - - - -

P2 X O X O X O

P3 X X - - - -

P4 - X - X - X

P5 - - X X - O

P6 - - - X - X

P7 - - - - X X

P8 - - - - X X

use or are used by other software operations, which may cause a mutual dependency

situation, like we have on the Tetris SPL example. In this way, this mutual dependency

should be supported (P7).

The minor problems, on the other hand, are P4, P5, P6 and P8. The ACIs demand

the use of virtual classes, which makes the code confuse to understand (P4). Moreover,

when using ACIs, CaesarJ compiler does not verifies if all ACI roles are implemented

(P6). Besides that, the use of mixins to compose partial implementations of an interface,

which enables the separate compilation of this modules, obligates developers to use the

composition mixin instead of instantiating the classes that they implemented (P5).

The template method implementations do not allow separate compilation of roles of a

given interface. Mixin composition, on the other hand, enables this separate compilation,

whereas the use of wrappers introduce problems P7 and P8. Moreover, solution using

wrapper classes with ACI also demands the use mixin composition and does not bring

any benefit not present when using only mixin composition.

Thus, among the discussed approaches, the solution with mixin composition using

ACIs is the one that provides a better modularity support. However, this approach

still has modularity issues, as discussed in Section 3.3.2 and summarized in this section.

On the next chapter we introduce CaesarJ+, an extension to CaesarJ that enables the

specification of design rules which aim to facilitate a more modular development of OO

and AO code, solving the problems mentioned on this chapter.

Page 52: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CHAPTER 4

CAESARJ+: AN EXTENSION TO INCREASE

CAESARJ MODULARITY

Chapter 3 explored multiple ways to implement the di!culty feature of a Tetris game SPL

using CaesarJ. In order to achieve a better modularity support, we have pushed CaesarJ as

far as we could, being necessary even to do an inversion of control in the implementations

using wrappers to enable the mutual dependency of common and variation code (see

Section 3.4).

As mentioned in Section 3.5, the solution using mixin compositions with ACI is the one

that provides better modularity support, allowing the specification of design rules that

have multiple roles and allowing the separate development and compilation of these roles

inside di"erent modules. Thus, these ACIs work as interfaces that specify the minimum

restrictions between these modules. However, this solution has many drawbacks, as

summarized in Section 3.5.

In order to minimize these drawbacks we propose in this work CaesarJ+, an extension

of CaesarJ that aims to increase modularity. This extension defines a set of constructs

on top of CaesarJ, which enable the specification of design rules for OO and AO code,

allowing independent development. Furthermore, the restrictions defined by CaesarJ+

DRs are automatically verified (statically checked). CaesarJ+ constructs syntax is similar

to LSD [43] constructs.

In the following sections we present the new constructs introduced by CaesarJ+.

4.1 DESIGN RULES CONSTRUCT

The design rules expressed using CaesarJ in the last chapter are CaesarJ classes that

contain one or more abstract cclasses (ACIs). As previously mentioned in Section 3.3, it

is possible to partially implement these interfaces in multiple modules and them compose

the implementations using mixin compositions. However, the CaesarJ compiler does

not enforce that all abstract CaesarJ classes of a given collaboration are implemented

(problem P6, see Sections 3.3.2 and 3.5), which can lead to situations where some roles

declared on the ACI are not present in the composed mixin.

37

Page 53: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.1 DESIGN RULES CONSTRUCT 38

To avoid this problem we need a way to specify roles and restrictions that must be

present on the implementations of the interface. CaesarJ+ introduces the Design Rule

construct, represented by the dr keyword. CaesarJ+ design rules group one or more roles

(cclasses), similar to CaesarJ collaborations. They establish a contract, the roles and

restrictions specified on the DRs are enforced by CaesarJ+, which means that these roles

must have a proper implementation satisfying all the defined restrictions.

Listing 4.1 Simple CaesarJ+ Design Rule example

1 dr SimpleDR [ NextPiece , Canvas ]

2 public abstract cclass NextPiece {

3 int width , he i ght ;

4

5 public abstract void paint ( ) ;

6 public abstract void drawPiece ( ) ;

7 . . .

8 }

9 public abstract cclass Canvas {

10 abstract void s ideBoxes ( ) ;

11 . . .

12 }

13 }

Listing 4.1 shows a simple CaesarJ+ design rule based on the Tetris SPL exam-

ple (Section 3.1). The DR SimpleDR declares two roles, NextPiece and Canvas, each

one defining abstract methods, paint and drawPiece of NextPiece, and sideBoxes of

Canvas. The DR construct is mainly for design purposes, that is the reason that all the

methods on the depicted code are abstract. Nevertheless, as we use CaesarJ classes to

define our DR roles, it is also possible to have attributes and concrete methods declared

inside a DR role. For example, width and height (Line 3) are attributes that can be

used by all operations of NextPiece role. Although not described on the example, a DR

can also have declarations of constants which are global to all roles declared within the

DR, like Java constants.

A role declared inside a DR can reference all the other roles of the same DR. For

example, as described in Section 3.1, the Canvas role methods are responsible for paint-

ing the screen objects. Thus, its implementation needs to call the NextPiece paint

method. This role could also have another method which returns or receives a parameter

of NextPiece type.

As we can see in Line 1 of Listing 4.1, SimpleDR has two parameters, NextPiece

and Canvas. These parameters represent the roles declared within the DR, allowing the

abstraction of real role name by classes responsible for the DR implementation, increasing

the reuse of design rules. Thus, only name of types defined within the DRs can be declared

Page 54: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.1 DESIGN RULES CONSTRUCT 39

as DR parameters. It is also possible to have roles declared inside a DR which are not

represented in the parameter list. Classes responsible for the implementation of these

kinds of roles need to have the same name as declared on the DR role. More details

about DR implementation are described in Section 4.3.

Listing 4.2 presents the grammar of CaesarJ+ DR construct using the Syntax Defini-

tion Formalism (SDF) [59], which is a meta-syntax to define context-free grammars. The

SDF meta-syntax is adopted in this work because it is used by Stratego/XT, which is the

language used to implement CaesarJ+ compiler. More details about Stratego/XT and

CaesarJ+ compiler are introduced in Chapter 5. Line 6 exports the design rule construct

(DRConstruct, LHS), specifying that it defines a language type (TypeDec, RHS). As de-

fined in Line 7, a design rule is composed by a declaration head (DrDeclarationHead),

which is the keyword dr plus the Id of a given design rule and the list of parameters

(Line 9), and a body (DrBody). A body of a DR (Line 10) is a block that contains mul-

tiple members, which can be constants or classes (Lines 15-16). Classes and constants

declarations are imported from Java grammar (Line 2). Java class declarations are later

modified, inside another SDF module, to include cclass declarations. A SDF parser

generates a tree with the parsed terms (parse tree). It is possible to define a specific rep-

resentation for each term of this parse tree. For example, , DrDec (cons("DRDec"), RHS

of Line 7) is the representation on the tree for a DrConstruct, containing a DrDecHead

(RHS of Line 9) and a DrBody (RHS of Line 10). A complete CaesarJ+ SDF grammar

is depicted in Appendix A.

Listing 4.2 Design Rule construct SDF grammar

1 imports

2 languages / java /JavaMix

3 exports

4 context!free syntax

5 DrConstruct !> TypeDec

6 DrDeclarationHead DrBody !> DrConstruct { cons ( ”DrDec” ) }

7

8 ”dr” Id DrParams !> DrDeclarationHead { cons ( ”DrDecHead” ) }

9 ”{” DrMembersDeclaration ! ”}” !> DrBody { cons ( ”DrBody” )}

10 ” [ ” { Id ” , ”}+ ” ] ” !> DrParams { cons ( ”DrParam” )}

11

12 context!free syntax

13 ConstantDec !> DrMembersDeclaration

14 ClassDec !> DrMembersDeclaration

15

16 l ex ica l syntax

17 ”dr” !> Keyword

Page 55: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.2 COMPLEMENTS RELATIONSHIP 40

4.2 COMPLEMENTS RELATIONSHIP

In the last chapter we present an example of two mutually dependent roles, next piece

commonalities and variations, that should be separately developed in order to produce a

more modular design. As presented in Listings 3.4 and 3.9, design rules elaborated with

ACI enable this mutual dependency, allowing the separate development of these roles.

However, to enable that both roles access each other methods, it is necessary to duplicate

the abstract signatures of methods that vary inside the class that have the common

methods. This duplication generates a complex specification (P2, Section 3.5) that can

mislead developers that are being guided by these DRs. In other words, these design

rules cannot clearly guide the independent development of the aforementioned roles.

Aiming to have a more accurate DR, we introduce in CaesarJ+ the complements

cclass relationship. The idea of this relationship is to enable the modularization of part

of a role (a specific concern, for example) inside another module, allowing the remaining

operations of this role and the modularized methods to have full visibility of each other.

With the complements, it is now possible to express in a clear way the contents of the

mutually dependent roles, enabling their independent development.

Listing 4.3 Design Rule for the Di!culty feature of Tetris SPL

1 dr NextPieceDR [Common, Var i at i on ] {

2 abstract cclass Common {

3 abstract void paint ( ) ;

4 abstract void drawPiece ( int type ) ;

5 }

6

7 abstract cclass Var iat i on complements Common {

8 abstract void updatePiece ( ) ;

9 abstract void paintBox ( ) ;

10 }

11 }

Listing 4.3 shows a DR in CaesarJ+ similar to the ACI of Listing 3.4. NextPieceDR

uses the complements relationship (see Line 7, complements keyword), Variation is the

complementary role whereas Common is the complemented one. The contents of comple-

mentary roles are only part of the complemented role, which means that classes imple-

menting only complementary roles cannot be instantiated.

The complements construct should be used when we want to modularize parts of a

class. In this way, it is possible to develop on parallel two (or more) parts of the same

class. Then, when we join the implementations of all these parts (the complemented

and the complementary roles) we can instantiate a single module, the one responsible

Page 56: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.3 DESIGN RULES IMPLEMENTATION 41

for the complemented role. In summary, we have a single module to be used that was

implemented (modularized) on more than one class.

Di"erent from the inheritance relationship, which is unidirectional, complements al-

lows that both complemented and complementary classes completely share its methods

and attributes. In this way, the Variation role (complementary) can access all methods

and attributes of the Common (complemented) role that were defined on the DR, and

vice-versa.

A cclass (role) of a design rule can only complement cclasses declared within the

same DR, otherwise it would not be possible to fully understand a DR looking only at

its code, compromising the comprehensibility (modularity). Moreover, a DR role can

complement one or more roles within the same DR.

The complements relationship is introduced as one more construct for CaesarJ classes.

Similar to a design rule (see Listing 4.2), a cclass is a composition of a head and a body.

Thus, it is necessary to modify only the head of a cclass (ClassDeclarationHead) to

enable the use of the complements construct. As we can see in Lines 3-5 of Listing 4.4, the

complements construct must appear after the declaration of superclasses and before the

implementation of interfaces. The {ClassType "&"}+ expression on the LHS of Line 8

means that we can use the & operator to specify that a given cclass of a DR complements

one or more cclasses.

Listing 4.4 Complements construct SDF grammar

1 context!free syntax

2

3 ( Annotations | Cla s sMod i f i e r s )! ” c c l a s s ”

4 Id TypeParams? SuperClass ? Complements?

5 I n t e r f a c e s ? Wraps? !> ClassDeclarat ionHead { cons ( ”CClassDecHead ” ) }

6

7

8 ”complements ” {ClassType ”&”}+ !> Complements { cons ( ”Complements” ) }

9

10 l ex ica l syntax

11 ”complements ” !> Keyword

4.3 DESIGN RULES IMPLEMENTATION

Sections 4.1 and 4.2 introduce and detail the CaesarJ+ design rules notion and its com-

plements notion. As the DRs are contracts that must be obeyed by modules of a system,

it is necessary to associate this contract with the classes responsible for their roles. In this

way, classes need to specify the design rules that they are implementing. As a CaesarJ+

Page 57: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.3 DESIGN RULES IMPLEMENTATION 42

DR can have several roles, classes implementing a DR need to define which role they are

providing, in order to establish which are the class responsibilities.

To implement a DR, a cclass uses the implements keyword followed by the name

of the design rule that it is implementing and the name of role that it is responsible for.

For instance, Listing 4.5 shows a toy DR (ExampleDR) with roles A and B, which are im-

plemented by classes ExampleA and ExampleB, respectively. As we can see, ExampleA in-

forms that it implements ExampleDR role A (..implements ExampleDR [A] .., Line 10),

whereas ExampleB specifies that it is responsible for role B (..implements ExampleDR [B]

.., Line 13). In this way, ExampleA must provide the implementation of method x,

whereas ExampleB must provide implementation of y, as we can see in Lines 11 and 14,

respectively.

Listing 4.5 Each class implementing a single DR role

1 dr ExampleDR [A, B] {

2 public abstract cclass A {

3 public abstract void x ( ) ;

4 }

5 public abstract cclass B {

6 public abstract void y ( ) ;

7 }

8 }

9

10 cclass ExampleA implements ExampleDR [A] {

11 public void x ( ) { . . . }

12 }

13 cclass ExampleB implements ExampleDR [B] {

14 public void y ( ) { . . . }

15 }

Due to the use of DR parameters, we have multiple ways to implement a DR and its

roles. For example, a developer responsible for roles A and B can opt to implement them

using a single class. In this way, he has to specify that this class is responsible for these

two roles, as we can see in Listing 4.6 (ExampleAB). Thus, this class has to provide the

restrictions of both roles A and B. This is represented in Lines 2 and 3.

Listing 4.6 A single class implementing more than one DR role

1 cclass ExampleAB implements ExampleDR [A, B] {

2 public void x ( ) { . . . }

3 public void y ( ) { . . . }

4 }

Although not described in the code snippets, the implementation of a complementary

role is similar to the implementation of any other role. The only di"erence is that no

Page 58: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.4 DESIGN RULES INSTANTIATION 43

objects of this class can be created, only classes implementing complemented or normal

roles can be instantiated, as described in Section 4.2.

The CaesarJ ACIs introduced in Chapter 3 obligate developers to create collaborations

in order to implement these ACI roles, as the roles represented in the ACIs must be

implemented inside virtual classes. As introduced in this section, the CaesarJ+ DRs are

implemented by means of top-level classes. With the use of top-level classes the code

written is more concise, easier to understand. It is not necessary to define a collaboration

and then define a virtual class for each role, as we have in Chapter 3.

The syntax of a design rule implementation is introduced as a modification into the

Java implements construct grammar. As presented in Line 5 of Listing 4.4, cclasses can

implement interfaces (Interfaces?). Thus, it is necessary to specify that a cclass now

can implement both interfaces and design rules, which is depicted in Listing 4.7. As we can

see in Lines 3-4, the implements keyword can be followed by multiple implementations of

interfaces or design rules. Line 6 depicts the implementation of DRs, which is composed

by the design rule name (ClassType) followed by a list of roles which it implements

(DrParams, see Listing 4.2), whereas Line 8 depicts the implementation of a Java interface.

In this way, all the classes responsible for implementing a DR role must use the implements

construct, di"erent from what we have in LSD [43], for example.

Listing 4.7 Design rule implementation SDF grammar

1 context!free syntax

2

3 ” implements ” {( In t e r f a c e s Imp l | DRImpl) ” , ”}+

4 !> I n t e r f a c e s { cons ( ” Implements” ) }

5

6 ClassType DrParams !> DRImpl { cons ( ”ImplDrDec” ) , p r e f e r }

7

8 ClassType !> In t e r f a c e s Imp l { cons ( ” ImplementsDec ” ) }

4.4 DESIGN RULES INSTANTIATION

CaesarJ+ DR constructs introduced in Section 4.1 specify a protocol of interaction be-

tween OO and AO code (CaesarJ classes). These protocols can be exercised by di"erent

classes, on di"erent contexts. Each set of classes implementing a DR in a specific con-

text is independent of the others. On CaesarJ+ we specify this set of classes during

the design rule instantiation. A CaesarJ+ DR designed by the developer works like a

model, as a specific DR is generated for each design rule instance. In summary, a DR

instantiation binds the classes responsible for implementing the design rule roles in a

Page 59: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.4 DESIGN RULES INSTANTIATION 44

given context, generating a specific DR (interface) for each instantiation. An example of

DR instantiation is shown in Listing 4.8.

Listing 4.8 Example of a DR instance for ExampleDR design rule

dr InstaceExampleAB = ExampleDR [ ExampleA , ExampleB ]

The design rule ExampleDR (Listing 4.5) has two parameters, A and B, so its instance

requires two classes responsible for these parameters (ExampleA and ExampleB, as we

can see in Listing 4.8). In a DR instantiation, classes that implement DR roles must be

informed in the same sequence of the DR parameter list (see Figure 4.1). For example,

as cclass ExampleA is responsible for role A and ExampleB for role B, the instantiation

ExampleDR shown in Listing 4.9 results in an error, as ExampleB does not provide method

x and ExampleA does not provide y.

!"#!"#$%&"$'&"((("$)*"+

####$$%&''"$%"+"(((",####$$%&''"$'"+"(((",""""(((####$$%&''"$)"+"(((",,

!"#!-./01.23"4"!#5%&"5'&"((("5)*

$$%&''#5%"##()*%+)+,-'"!"#$%*"+""""(((,

$$%&''#5'"##()*%+)+,-'"!"#$'*"+""""(((,

$$%&''#5)"##()*%+)+,-'"!"#$)*"+""""(((,

Figure 4.1 The order of classes in a DR instances is the same of the DR parameters

Listing 4.9 Invalid DR instance: ExampleB implements role B, but is positioned in the in-

stantiation as role A implementation. Similar happens to ExampleA.

dr InstaceExampleBA = ExampleDR [ ExampleB , ExampleA ]

Listing 4.10 DR instance using a class which implements more than one role

dr InstaceExampleABAB = ExampleDR [ ExampleAB , ExampleAB ]

DR instantiations in CaesarJ+ are global, like public classes or interfaces declara-

tions. They must specify one class for each parameter of the instantiated DR, even if

Page 60: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.4 DESIGN RULES INSTANTIATION 45

a given class is responsible for the implementation of more than one role. For exam-

ple, the design rule instance for ExampleDR using cclass ExampleAB (Listing 4.6) which

implements both roles A and B is depicted in Listing 4.10.

Each DR instance is independent of the others. A given DR instance can only han-

dle objects of classes specified within its instance. For example, suppose that method

x from ExampleDR role A receives a parameter of B role type. In that way, if we are

handling instance InstaceExampleAB, the x method can only receive an instance of

ExampleB cclass, because this is the class responsible for this role in this DR instance.

Even if we have another class implementing ExampleDR role B (ExampleB2, for example),

InstanceExampleAB would not be able to handle objects from ExampleB2, because this

class is not a member of this DR instance.

In order to create objects of a class that implements a DR role we first need a design

rule instance. After instantiating a DR we use its instance name followed by the new

keyword and the name of the class specified within the DR instance which we want to

instantiate. References to objects attributes of DR role type also need to be preceded by

the DR instance name. Listing 4.11 shows examples of both references and instantiations

of ExampleDR roles.

Listing 4.11 Instantiation and references of a DR role

1 dr InstaceExampleAB = ExampleDR [ ExampleA , ExampleB ]

2

3 public class Main {

4 private InstaceExampleAB .A aObject ;

5

6 private InstaceExampleAB .B bObject ;

7

8 public stat ic void main ( int [ ] a r gs ) {

9 aObject = InstanceExampleAB .new ExampleA ( ) ;

10

11 bObject = InstanceExampleAB .new ExampleB ( ) ;

12 }

13 }

In Line 1 we have the already mentioned InstaceExampleAB instance of ExampleDR.

Lines 4 and 6 show examples of how to declare variables of ExampleDR role type. Note that

it is necessary to specify the name of DR and the classes which implement the roles before

referencing the role itself (A or B). In Lines 9 and 11 we have the instantiation of classes

ExampleA and ExampleB, which are responsible for the implementation of ExampleDR

roles A and B, respectively.

CaesarJ also has a mechanism for specifying classes used in a collaboration. Regarding

the example of Section 3.3.2, mixin composition is the mechanism that specifies the classes

Page 61: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.5 ENHANCING EXPRESSIVENESS 46

that implement the ACI roles. For this, it is necessary to define a collaboration mixin

and, for roles that are mutually dependent, it is also needed to define an inner-mixin.

This force developers to instantiate objects of this inner-mixin type, which is not defined

in the ACI (problem P5). In order to replace the implementation of a certain role we need

to create a new collaboration mixin indicating the class which contains the new code.

Considering mutually dependent roles, the instantiation of CaesarJ+ DRs avoids the

specification of the inner-mixin which was necessary in implementations of ACI using

mixin composition. Now, after instantiating a given design rule, we can then instantiate

classes which are responsible for the complemented roles, whereas classes implementing

complementary roles cannot be instantiated.

Listing 4.12 shows the SDF grammar that introduces the design rule instantiation.

First we declare the design rules instantiation (DrInstance) as a type declaration (Line

3). DrInstance is the composition of the dr keyword followed by the name of the instance

(Id), the equals signal, the name of the DR that is being instantiated (DrReference) and

the list of classes which implements the DR roles (DrParams), as depicted in Line 5. Line

7 depicts the DrReference construct, which is a simple Id.

Listing 4.12 Design rule instantiation SDF grammar

1 context!free syntax

2

3 DrInstance !> TypeDec

4

5 ”dr” Id ”=” DrReference DrParams !> DrInstance { cons ( ”DrInstance ” ) }

6

7 Id !> DrReference { cons ( ”DrReference ” ) }

4.5 ENHANCING EXPRESSIVENESS

The CaesarJ interfaces expressed in Chapter 3 using ACIs are useful to specify that rules

must exist and their implementations must provide methods with the same signature as

declared on each DR role. These restrictions are similar to Java interface restrictions.

Thus, the expressiveness of each restriction is low, as each signature restriction is a exact

requisite. For example, we cannot write general rules that are applied for more than one

method pattern, it is necessary to write one restriction for each specific method. So far,

the CaesarJ+ DR constructs introduced also follow the exact requisites principle.

In this way, in order to increase the expressiveness of our DRs, we propose the use of

AspectJ-like wildcards in the definition of DR roles’ method signatures. As DRs are used

to specify restrictions between AO and OO code, method signatures using wildcards can

Page 62: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.5 ENHANCING EXPRESSIVENESS 47

be restrict enough to guarantee that a given pointcut is going to match. The restrictions

defined using wildcards are evaluated following the minium requisites principle. The use

of wildcards on CaesarJ+ is discussed in 4.5.1.

Moreover, CaesarJ ACIs already define some restrictions over pointcuts, as pointcuts

defined inside ACI inner-classes are inherited by cclasses which implement these roles.

However, it is not possible to define any restriction over advice. Thus, we also introduce

in CaesarJ+ a way to define restrictions over DR roles’ advice. These restrictions are

introduced in Section 4.5.2.

4.5.1 Wildcards

Listing 4.13 shows part of the DisplayExampleDR design rule for the Figure-Display

example, which depicts the use of wildcards in CaesarJ+ role method signatures (Line 4).

As DR are used to specify the minimum requirements between modules in order to enable

their modular development, the evaluation logic of method signatures that use wildcards

searches for at least one method that matches the signature. For example, the cclass

implementing PointRole must have at least one public method whose name starts with

set, returns void and has just one int parameter, such as public void setX(int x).

Listing 4.13 Caesar class example: classic Figure-Display problem

1 dr DisplayExampleDR [ . . . PointRole , LogRole , . . . ] {

2 . . .

3 public abstract cclass PointRole extends FigureElement {

4 public void s e t !( int ) ;

5 }

6

7 public abstract cclass LogRole {

8 pointcut pointChange ( Point p ) : t a r g e t (p) && ( ca l l (void Point . s e t ! ( . . ) ) ;

9 }

10 . . .

11 }

Method signatures of CaesarJ+ roles can have wildcards in cclass modifiers, return

type, method name and parameters type, with the latter option having an usage di"erent

from the other options. Besides the "*" (any) wildcard, parameters can be defined using

AspectJ wildcard "..", which represents any parameters of any type. Table 4.1 depicts

the possible combinations of wildcards when used to represent method parameters.

Also, only the "*" (any) wildcard can also be used to represent a method visibility

modifier or the return type of a method. Moreover, on CaesarJ+ DRs the use of wildcards

on the list of exceptions thrown by a method is not allowed, as we believe that it can

Page 63: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.5 ENHANCING EXPRESSIVENESS 48

Table 4.1 Use of wildcards in parameters declarations

Parameter declaration Behavior

method(*) One parameter of any type

method(..) Any parameters of any type

method(T,*) Two parameters, one of type T and other of any type

method(T, ..) A parameter of type T plus zero or more of any type

method(T, *, ..) A parameter of T type plus one or more of any type

mislead the developers guided by the DR, which would not be able to identify what

exceptions he must be able to handle or throw when implementing a DR method.

4.5.2 Advice restrictions

When using CaesarJ ACIs, we are able to to specify that an implementation of a virtual

class (ACI role) must have some specific methods and pointcuts (if we declare abstract

pointcuts, for example). However, it is not possible to impose any restrictions over advice.

What we are to do is write an advice directly into a DR role, with the execution code

(behavior) inside it, but it is not possible to specify that classes implementing this role

should also provide a certain advice that uses (or not) a certain pointcut.

In this way, we introduce in CaesarJ+ the possibility to impose restrictions over advice

on DR roles. Listing 4.14 shows an extension of LogRole (Listing 4.13) which specifies

that an after advice, using at least pointChange pointcut, must be present on LogRole

implementation, as we can see in Line 4.

Listing 4.14 Caesar class example: classic Figure-Display problem

1 public abstract cclass LogRole {

2 pointcut pointChange ( Point p ) : t a r g e t (p ) && ( ca l l (void Point . s e t ! ( . . ) ) ;

3

4 after ( Point p , . . ) : pointChange (p) . . ;

5 }

Looking carefully to the declared advice, we can see three di"erences comparing to a

normal AspectJ/CaesarJ pointcut : (1) it uses a wildcard (“..”) at the variable bindings,

(2) it has a wildcard after the specification of the pointcut (“..”), and (3) it does not

have a body, as this rule is only for design purpose. Regarding (1), it is possible to use

the parameter wildcards detailed in Table 4.1 within the advice parameter bindings. For

Page 64: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.6 CHAPTER SUMMARY 49

example, if we use the "*" wildcard instead of ".." (resulting in after(Point p, *))

we need an advice which binds exactly two parameters, with the first one of Point type,

in order to match the advice restriction. Considering (2), the ".." wildcard indicates

that the pointcut which is being used by the advice can be complemented. The eval-

uation logic for advice restriction also follows the minimum requisites principle, which

means that any after advice that exposes at least a parameter of Point type and uses at

least the pointChange pointcut (receiving the exposed parameter of Point type) matches

the rule of Line 4 (Listing 4.14). For example, an implementation of LogRole declaring

the advice after(Point p): pointChange(p) && anotherPointcut() { .. } cor-

rectly matches the advice restriction rule.

We can also write advice restrictions without specifying any pointcut, with the use

of wildcards. For example, before(..): *; indicates that a before advice using any

pointcut and exposing any parameter must be present on the cclass which implements

LogRole.

4.6 CHAPTER SUMMARY

In this chapter we have introduced CaesarJ+, a language for increasing modularity of

CaesarJ, and discussed its constructs. The purpose of CaesarJ+ is to provide support

for modular development of OO and AO code. The DR construct introduced guide

programmers on the development of OO and AO code, helping them to identify what

they should be able to do or not. CaesarJ+ DRs enable the definition of restrictions more

expressive than the ones defined by using only CaesarJ ACIs.

Our language, however, does not verify if changes on role implementations break the

intents of an aspect. We believe that our design rules provide the necessary information

to help developers make their own decisions. For example, if one is implementing a DR

role A that specifies the pointcut execM: execution(* A.m*(..)), this developer must

realize that all methods whose name starts with m are subject to being intercepted by

an aspect. Thus, if he writes a method m2() or modifies a method name from m1() to

n1(), it should be a conscious decision, as he explicitly declares that he is following the

rules established on the DR role A. So, prior to making these changes, he must be aware

of the rules established on the DR.

Also, the restrictions enforced by our language are based on the syntax of the program.

We can define only structural restrictions now, but we do plan to enable the specification

of behavioral rules (see Section 7.2), like LSD [43] behavioral rules, which define what

Page 65: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

4.6 CHAPTER SUMMARY 50

must occur inside a specific scope (method call, attribute set, etc.). Semantic restrictions

such as the definition of what is a specific concern (for example, what the GUI concern

comprises), which demand the specification of a formal model of the system, are beyond

the scope of this work.

In the next chapter we introduce the transformations necessary to translate CaesarJ+

constructs into CaesarJ code. We also discuss the implementation of CaesarJ+ compiler.

Page 66: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CHAPTER 5

IMPLEMENTATION DETAILS

In order to evaluate the language constructs introduced in Chapter 4 we have developed a

CaesarJ+ compiler. The actual version is a prototype that verifies, validates, and trans-

forms CaesarJ+ constructs into valid CaesarJ code, which is then ready to be compiled

by CaesarJ original compiler.

In this chapter we detail how the CaesarJ+ compiler works, introducing the transfor-

mations to CaesarJ in Section 5.1. Moreover, in Section 5.2 we discuss the implementation

of such transformations, which is developed using the Stratego/XT [55] language for pro-

gram transformations. In the end of this section we discuss the actual limitations of our

compiler.

5.1 TRANSFORMATIONS

After concluding the specification of our constructs, we started to analyze how to intro-

duce them into CaesarJ. Three options were available, (1) build a new compiler from the

scratch, (2) modify the CaesarJ compiler, introducing the proposed constructs, and (3)

build a pre-compiler which handles the proposed constructs and transforms them into

valid CaesarJ code.

Building a new compiler for the scratch for both CaesarJ and CaesarJ+ would require

plenty of time and compiler knowledge. As we had limited time and were not experts on

compilers, the first option was discarded. Regarding (2), by introducing our constructs

into the existing CaesarJ compiler, our modifications would be highly coupled with the

actual implementation. Thus, any new release of the compiler could break all of our

modifications. Analyzing the third option, we have that CaesarJ is able to express our

restrictions, although it requires complex specifications and cannot statically check most

of them. In this way, we decided to develop a CaesarJ+ compiler which verifies the

proposed CaesarJ+ constructs, statically checks the restrictions, and then transforms the

CaesarJ+ code into valid CaesarJ code.

Next we describe through examples how each CaesarJ+ construct is transformed into

CaesarJ code.

51

Page 67: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.1 TRANSFORMATIONS 52

5.1.1 Design Rules

As CaesarJ does not support the design rule (dr) construct, it is necessary to transform

a design rule into a CaesarJ class. A naive way to make this transformation is to convert

a design rule directly into a collaboration, as presented in Listing 5.1.

Listing 5.1 Generated CaesarJ ACI for ExampleDR (Listing 4.5)

1 public abstract cclass ExampleDR {

2 public abstract cclass A {

3 public abstract void x ( ) ;

4 }

5

6 public abstract cclass B {

7 public abstract void y ( ) ;

8 }

9 }

As we can see, the generated code for the design rule of Listing 4.5 is a simple ACI,

with one virtual class for each role defined within the DR. Moreover, the parameters of the

DR were discarded, there is no sign of them in the depicted code. Hence, all classes which

declare to implement this ACI can collaborate with each other. However, as specified on

last the last chapter, our idea with CaesarJ+ is to have a restrict collaboration, allowing

only classes specified within a given context to collaborate with each other. Thus, only

this transformation of Listing 5.1 is not enough.

!!"#!$%&'("#)*+',-."

/"+"$)01!"#!$%'2134$!+#56$7!8)6+

1!"#!$%'213

1!"#!$%'213

1!"#!$%'2134$!+#56$7!8)6+56$'"!09'(,'3+#8!+0"

!"#$%&'(%)*&

+(*&(,-.#)/0123('2/%#1,/)*&&#/4#!*&25%#"63*&

Figure 5.1 Overview of Design Rules compilation process

As stated in Section 4.4, CaesarJ+ design rules generates one specific design rule for

each DR instance. Thus, initially each CaesarJ+ DR is transformed into a generic ACI,

Page 68: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.1 TRANSFORMATIONS 53

exactly as described in Listing 5.1. Moreover, this generic ACI is transformed for each

DR instance, which specifies all the classes that implement the DR roles, generating a

specific DR for each instance. Figure 5.1 describes this process.

This first part of the DR transformation, which generates the generic ACI, is respon-

sible for dealing with the complements construct. The transformations related to the

complements are detailed in Section 5.1.2. Next, the compiler analyzes the classes of the

system, looking for classes which declare to implement a DR, and verifies if these class

obey the DR restrictions. The transformations of the DR implementations are explained

in Section 5.1.3. After this, the compiler analyzes the DR instantiations, verifying if

the informed classes really implement the correspondent roles. Each DR instantiation

generates a specific ACI (highlighted in gray, Figure 5.1). These specific ACIs have the

same body of the generic one, di"ering only in the name, which is based on the following

rule: DR name plus the names of the classes which implement each DR role, separated

by underscores. For example, the ACI generated for the DR instance of Listing 4.8 is

named as ExampleDR ExampleA ExampleB. More details about the transformations of a

DR instance are detailed in Section 5.1.4.

5.1.2 Complements

As stated in Section 4.2, our objective with this construct is to enable the modularization

of part of a role (class, for example) on more than one module, enabling the parallel

development of this role. Thus, it is necessary that all these separated parts of this role

have access to each other operations.

We have identified two possible approaches for the complements transformation. The

first approach transforms the complements relationship into an inheritance relationship,

and then copies the signatures of the operations declared within the complementary

cclasses into the complemented cclass, similar to described in Section 3.3.2. The

second approach unifies the complemented and all of its complementary roles in a single

module, with the same name of the complemented role, copying all the attributes and op-

erations of all these complementary roles into this newly created module. This approach

results in a single cclass for each complemented role that contains all the operations

declared within the complementary roles. Both approaches have its advantages and dis-

advantages. The first approach restricts the visibility of the complemented roles, as they

can access only the operations of the complementary roles, not the attributes, whereas

complementary roles can access complemented roles methods and attributes. This occurs

Page 69: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.1 TRANSFORMATIONS 54

due to the use of the inheritance relationship. Also, it is necessary to make a slightly

modifications on pointcuts referencing the complemented role, as now this role has, be-

sides its original methods, the method signatures copied from the complementary roles.

The second approach, on the other hand, does not limit the roles visibility, as the roles

are now unified in a single module. However, as it eliminates all the complementary roles

from the interface, we have that all the references to the complementary types must be

modified to point now for the created role. Thus, it is also necessary to modify pointcuts

which used to reference the complementary roles.

We believe that the first approach is more intuitive, as it maintains all the virtual

classes specified within the design rule, resulting in a DR more consistent with the estab-

lished specifications. In this way, we have decided to use this approach on the comple-

ments transformations. However, we plan to do a more detailed analysis of this second

transformation approach as a future work (see Section 7.2).

In this way, we transform the CaesarJ+ complements construct into CaesarJ code

by (1) transforming the complements relationship in the complementary cclass into an

inheritance relationship, and (2) copying the signatures of the operations declared within

the complementary cclass into the complemented cclass.

Listing 5.2 Generic ACI after the transformation of the complements construct

1 public abstract cclass NextPieceDR {

2 abstract cclass Common {

3 abstract void paint ( ) ;

4 abstract void drawPiece ( int type ) ;

5

6 abstract void updatePiece ( ) ;

7 abstract void paintBox ( ) ;

8 }

9

10 abstract cclass Var iat i on extends Common {

11 abstract void updatePiece ( ) ;

12 abstract void paintBox ( ) ;

13 }

14 }

Listing 5.2 shows the generic ACI generated after the transformation of NextPieceDR

(see Listing 4.3). In Line 10 we have the declaration of the virtual class Variation,

which inherits from Common. In the original design rule, Variation is a complementary

cclass, which complements Common. Lines 6-7 depict the signatures of updatePiece

and paintBox, which are methods from the complementary class (Variation) that were

copied inside the complemented class in order to enable Common original methods (paint,

drawPiece) to access them, as this is assured by the complements construct semantics

Page 70: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.1 TRANSFORMATIONS 55

(Section 4.2). It is important to remember that developers write CaesarJ+ design rules,

which are clear, easy to understand and checked by the compiler. They should not have

access to this generated code, which is confusing and hard to understand, like the ACI

presented in Listing 3.4.

In order to maintain consistency it is necessary to adapt a few pointcuts of the generic

ACI during the transformation of the complements. Pointcuts which use wildcards to

reference methods of the complemented classes must be modified to avoid matching the

introduced complementary methods. For example, the pointcut call(* Common.*(..))

is transformed to call(* Common.*(..)) && ( !call(* Common.updatePiece() ) &&

!call(* Common.paintBox()) ), avoiding that the original pointcut, which was de-

signed considering the original design rule, matches methods that it is not supposed

to match. Table 5.1 lists which pointcuts need to be transformed in order to maintain

the DR consistency.

For all the call/execution pointcuts depicted in the table, the modifications are

similar to the call(* Common.*(..)) example. The within pointcut needs a di"erent

modification, it is necessary to add a !withincode into the pointcut in order to avoid

matching of the introduced methods. For example, whithin(Common) is transformed to

whithin(Common) && !withincode(updatePiece()) && !withincode(updatePiece()).

In order to avoid the generation of cotraditory pointcuts (such as call(A) && !call(A))

we still need to do a more detailed analysis of this pointcut transformation process, using

more complex examples.

Table 5.1 Pointcuts which need to be updated

Pointcut Wildcard on Note

call/execution(ReturnType Class.*(..)) methodName Class is a complemented role

call/execution(* Class.methodName(..)) ReturnType Class is a complemented role

call/execution(ReturnType Class.methodName(*)) args type Class is a complemented role

call/execution(ReturnType Class*.methodName(..)) Class name Class* matches a complemented role

within(Class) - Class is a complemented role

within(Class*) Class name Class* matches a complemented role

If the second transformation approach for the complements was used, instead of having

both Common and Variation cclasses in Listing 5.2, we would have only the Common

virtual class containing the signature of the four methods. Thus, all references to the

Variation virtual class must be updated, pointing now to the Common role. A more

detailed analysis of this second approach, comparing the advantages and disadvantages

of it with the used transformation approach, can be done as a future work.

Page 71: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.1 TRANSFORMATIONS 56

5.1.3 Implementation

As design rules are transformed into collaborations, it is necessary to implement its

roles (inner CaesarJ classes) inside virtual classes (as explained in Section 2.3). Though,

as introduced in Section 4.3, the implementations of design rules occur inside top-level

classes. Hence, it is necessary to transform these DR implementations into virtual-classes.

In this way, CaesarJ+ compiler analyzes the top-level classes that implement the DR,

verifying if they provide the implementations of the roles which they are responsible

for, and them transform these top-level classes into CaesarJ code. Listing 5.3 presents

ExampleA, a CaesarJ+ implementation of ExampleDR (Listing 4.5) role A, whereas List-

ing 5.4 shows how ExampleA looks after the transformation to CaesarJ code.

Listing 5.3 ExampleA before transformation

cclass ExampleA implements ExampleDR [A] {

public void x ( ) { . . . }

}

Listing 5.4 Generated code for ExampleA

cclass ExampleA Cjp extends ExampleDR {

cclass ExampleA extends A {

public void x ( ) { . . . }

}

}

This transformation process occurs as follows:

1. Generation of collaboration cclass: CaesarJ+ compiler generates a collabo-

ration cclass on top of the original cclass and uses the following rule to name

it: OriginalClassName plus the su!x Cjp. For example, in Listing 5.3 we have

ExampleA as a top-level cclass, and Listing 5.4 has the collaboration ExampleA Cjp

on top of ExampleA.

2. Inheritance organization: First, CaesarJ+ defines that the generated collabora-

tion inherits from the generic ACI originated after the transformation of the DR. For

example, ExampleA design rule is transformed into ExampleA generic ACI (described

in Section 5.1.1, Listing 5.1). This way, the compiler defines that ExampleA Cjp

inherits from ExampleA ACI (Line 1 of Listing 5.4). Thus, the compiler verifies if

the virtual class obeys all the restrictions specified on the ACI role. This estab-

lishes that the ExampleA Cjp is following the generic ACI, which means that any

virtual class of ExampleA Cjp can reference and use the roles (virtual classes) of the

generic ACI. After this, CaesarJ+ compiler declares that the virtual class inherits

from the roles that the top-level class declared to implement. In our example, as

the top-level class ExampleA was responsible for ExampleDR role A, the virtual class

ExampleA has to inherit from A after the transformation, as we can see in Line 2 of

Page 72: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.1 TRANSFORMATIONS 57

Listing 5.3. It makes the ExampleA virtual class responsible for the implementation

of the generic ACI virtual class A.

3. References update: CaesarJ+ compiler looks in the source code for references

to the top-level classes that were transformed. That way, all return types, vari-

able declarations and other references that points to the old top-level classes are

then updated to point to the virtual class of the new collaboration. Following

our example, all references on the code to the ExampleA cclass are updated to

ExampleA Cjp.ExampleA. Moreover, DR instances are also updated, replacing the

name of the original class for it new name with the Cjp su!x.

Other cclasses relationships, like interface implementation and class wrapping, can

still be used in cclasses that implement DR roles. However, after the compilation pro-

cess, these relationships are moved to the virtual class, as this is the class that originally

contains the code written by developers.

5.1.4 Instantiation

Design rules instances in CaesarJ+ are responsible for binding a set of classes that declare

to implement a DR in a specific context. Thus, a specific interface is generated for each

DR instance, restricting that only cclasses informed in a given instance can collaborate

with each other, as explained in Section 4.4. As the dr construct is not supported by

CaesarJ, it is necessary to transform it using an existing CaesarJ construct.

As mentioned in Section 4.4, mixin composition is the mechanism used in CaesarJ to

bind the implementations of a collaboration. Therefore, CaesarJ+ compiler transforms a

design rule instance into a mixin composition. As introduced in Section 5.1.1, design rules

are first transformed into generic ACIs, which then generate a specific ACI for each DR

instance. The transformation process of CaesarJ+ design rules instances into CaesarJ

code occurs as follows:

1. Generation of specific ACI: CaesarJ+ compiler analyzes the DR instance and

verifies if the informed classes are responsible for the correspondent DR roles. Next,

it uses the generic ACI as a base for the creation of the specific ACI, which has the

same content of the generic one, but with a di"erent name. The compiler uses the

following rule to name the specific ACI: generic ACI name (which is the same name

of the original DR) plus the names of the classes which implement each DR role,

separated by underscores. It is important to note that two di"erent DR instances

specifying the same classes as DR parameters generate di"erent specific ACIs.

Page 73: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.1 TRANSFORMATIONS 58

2. Inheritance update: In this compilation stage, CaesarJ+ compiler updates the

superclasses of each cclass informed on the DR instance parameters list. Here the

collaborations created in Section 5.1.3 (with the Cjp su!x) are updated, now they

inherit from the specific ACI instead of the generic ACI.

3. Mixin creation: In this step the compiler generates a new mixin collaboration,

which inherits from all the classes specified on the DR instance parameter list.

This generated mixin receives the same name informed at the DR instance. Also,

this mixin defines a static getInstance method, which returns the instance of

the mixin. Moreover, a new inner-mixin is created for each group of complement-

ed/complementary cclasses. This inner-mixin refines the complemented cclass,

stating that this cclass is now concrete and inherits from all the classes which

complemented it.

4. Update of references: CaesarJ+ compiler analyzes the source code, updating

the references of a given DR instance to the newly created mixin. That way,

there is a modification in the instantiation of DR roles. Now these instantiations

call the introduced static getInstance method. For example, the construction

DesignRuleInstace.new ClassImplementRole is updated to DesignRuleInstace.

getInstance().new ClassImplementRole.

Listing 5.5 presents examples of CaesarJ+ DR instance (NextPieceInstance in-

stance, Line 1), reference to a DR role type (Common, Line 4) and instantiation of a

DR role (Line 8). Listing 5.6 shows the generated CaesarJ code after the transforma-

tions. Note that, although not depicted in this listing, the first part of the DR instances

transformations (Generation of specific ACI ) generates the specific ACI for this instance,

while both classes specified as parameters are updated to inherit from this specific ACI

(second part of transformation, Inheritance update).

Listing 5.5 CaesarJ+ DR instance and references before transformation

1 dr NextPieceInstance = NextPieceDR [ NextPieceBase , EasyVar iat ion ]

2

3 public class Main {

4 NextPieceIns tance .Common common ;

5

6 public stat ic void main ( int [ ] a r gs ) {

7 . . .

8 common = NextPieceInstance .new NextPieceBase ( ) ;

9 }

10 }

Page 74: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.2 COMPILER IMPLEMENTATION 59

The third part of the DR instance transformation process (Mixin creation) orig-

inates NextPieceInstance mixin, which inherits from both NextPieceBase Cjp and

EasyVariation Cjp (Lines 1-11, Listing 5.6). NextPieceInstance also defines the inner-

mixin NextPieceBase (Lines 10-11), which refines the original virtual class declaring that

it is now concrete and inherits from EasyVariation. This inner-mixin is necessary in or-

der to enable the instantiation of the complemented class NextPieceBase. Besides that,

the static method getInstance (Lines 4-8) and the static field with the same name of

the mixin cclass (nextPieceInstance in our example, Line 2) are also created.

Listing 5.6 Generated CaesarJ code for DR instance

1 public cclass NextPieceIns tance extends NextPieceBase Cjp & EasyVar iat ion Cjp {

2 private stat ic NextPieceIns tance nextP i ece Ins tance ;

3

4 public stat ic NextPieceInstance ge t In s tance ( ) {

5 i f ( nextP i ece Ins tance == null )

6 nextP i ece Ins tance = new NextPieceInstance ( ) ;

7 return nextP i ece Ins tance ;

8 }

9

10 public cclass NextPieceBase extends EasyVar iat ion { }

11 }

12

13 public class Main {

14 NextPieceDR NextPieceBase EasyVariation .Common common ;

15

16 public stat ic void main ( int [ ] a r gs ) {

17 . . .

18 common = NextPieceInstance . g e t In s tance ( ) .new NextPieceBase ( ) ;

19 }

20 }

The last part of the DR instance transformation (Update of references) is responsible

for updating the references to the DR instance on the source code. Thus, references

to instances of DR roles are updated, replacing NextPieceInstance.new.. (Line 8 of

Listing 5.5) for NextPieceInstance.getInstance().new ..., as we can see in Line 18

of Listing 5.6.

5.2 COMPILER IMPLEMENTATION

CaesarJ+ compiler is responsible for checking the restrictions of the introduced constructs

and for transforming CaesarJ+ code into valid CaesarJ code, which can be later compiler

by CaesarJ compiler. We have implemented a prototype of this compiler, using the

Stratego/XT language and toolkit for program transformations.

Page 75: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.2 COMPILER IMPLEMENTATION 60

In this section we describe the implementation of CaesarJ+ compiler. We start by in-

troducing Stratego/XT in Section 5.2.1, whereas Section 5.2.2 depicts the implementation

of the compiler. The complete code of CaesarJ+ compiler can be dowloaded at [48].

5.2.1 Stratego/XT

According to [8] and [55], Stratego/XT combines Stratego, a small and e!cient domain-

specific language for implementing transformations based on the paradigm of programmable

rewriting strategies, with XT, a collection of reusable components and tools for the devel-

opment of transformation systems, such as powerful parser and pretty-printer generators

and grammar engineering tools.

Figure 5.2 Overview of Stratego/XT transformation process [9].

Stratego/XT supports the development of program transformation infrastructure,

domain-specific languages, compilers, program generators, and a wide range of meta-

programming tasks. It represents programs by means of terms, which are essentially

trees. Stratego/XT parses the original program into a tree of specific terms, which are

then manipulated (transformed) and then parsed to the output language, as depicted in

Figure 5.2.

Stratego language constructs rules and strategies are used to specify the trans-

formations. The rules are responsible for transforming a given term into another term.

These rules are executed only when specific conditions (restrictions), which are expressed

Page 76: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.2 COMPILER IMPLEMENTATION 61

within strategies, are valid (do not fail).

Before starting the transformations, it is necessary to parse the input program into a

tree of terms. Stratego/XT parser uses a table of symbols that is generated by the XT

tools using the language definition specified in the SDF grammar. It is also necessary to

define the pretty-printer for the output language, which is responsible for converting the

tree of transformed terms into the output code.

Next section depicts the main steps of CaesarJ+ compiler.

5.2.2 CaesarJ+ Compiler

CaesarJ+ compiler is a Stratego/XT program which receives CaesarJ+ code, analyzes

it, verifies its constructs and then transforms the input code, generating CaesarJ valid

code. CaesarJ+ is a superset of CaesarJ, containing all of its constructs plus the ones

introduced in Chapter 4.

The compilation process starts by constructing the tree of terms after parsing the

input CaesarJ+ program. After this, the main function starts the transformations by

applying the ManipulateCompilationUnit transformation rule (see Listing 5.7) to the

tree of terms. A Stratego rule is composed of a LHS representing the expected term

to be transformed (Line 3) and a RHS which is the result of the transformation. The

transformation itself is composed by the application of other rules and strategies, which

are depicted after the where construct. It only occurs if the rules and expressions of the

where clause do not fail.

Listing 5.7 Main transformation rule of CaesarJ+ compiler

1 rules

2 ManipulateCompilationUnit :

3 CompilationUnit ( packageDec , importDec , typeDec )

4 !>

5 CompilationUnit ( packageDec , importDec , typeDecMod )

6 where

7 // F i l t e r i n g the Design!Rules and Non Design!Rules de c l a ra t i on s

8 drDec := < f i l t e r (HasDr)> typeDec ;

9 nonDrDec := < f i l t e r (not (HasDr))> typeDec ;

10 //Manipulation of Design Rules

11 <map(ManipDrDec)> drDec => drDecMod ;

12 //Compiling the c c l a s s e s t ha t implement DRs, updat ing r e f e r enc e s

13 <handleNonDrDec ( | drDecMod , drDec)> nonDrDec ;

14 //Handling Design Rule i n s t an t i a t i o n

15 hand l eDr Ins tan t i a t i on ( | drDecMod) ;

16 //El iminat ing the Design!Rule con s t ruc t s

17 removeComplementsFromSignatures => typeDecMod ;

Page 77: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.2 COMPILER IMPLEMENTATION 62

As depicted above, ManipulateCompilationUnit receives a CompilationUnit term

(Line 3), which is the main node of the tree terms generated after parsing a Java-like (Cae-

sarJ+) file, and transforms its type declarations (design rules, classes, cclasses, etc.),

replacing typeDec for typeDecMod (Line 5). Lines 7-17 depicts the strategies which

are applied in order to enable this transformation and generate the modified declarations.

Three main steps are executed during this transformation process of the declarations,

which are:

1. Manipulation of Design Rules: This step is responsible for handling the design

rules declared on CaesarJ+’s code. It starts with the application of ManipDrDec

rule to each DR identified in the source code (Line 11). Also, during this activity the

complements construct is transformed into an inheritance relationship, as described

in Section 5.1.2.

2. Compilation of DR implementations: This transformation phase is responsible

for checking all the cclasses that declare to implement design rules, verifying

if they provide the necessary implementations for each DR role. It starts with

the application of handleNonDrDec strategy, which receives two parameters, the

recent modified DR declaration list and the initial DR declaration list, to the list of

declarations which are not DRs (see Line 13). Also, this step transforms the classes

which implement the DR, creating the collaboration, updating the inheritances, and

updating the references to these classes in the rest of the source code, as described

in Section 5.1.3.

3. Manipulation of DR instances: This step is responsible for handling the DR

instances. It starts with the application of the handleDrInstantiation strategy,

which receives the modified DR declaration list as a parameter, to the tree originated

from step 2 (Line 15). During this step the compiler verifies if the DR instances

provide the correct classes for each DR parameter, creates a mixin for each DR

instance, and updates the references to a DR instance, pointing to this newly created

mixin, as described in Section 5.1.4.

After these three steps we have a modified version of the declarations tree, with the

CaesarJ+ constructs transformed into CaesarJ valid code. However, it is still necessary to

remove the complements construct, which is still present on the specific ACI declarations.

This removal occurs by calling the strategy removeComplementsFromSignatures (see

Line 17 of Listing 5.7).

Next we detail the implementation of each of the three steps introduced above.

Page 78: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.2 COMPILER IMPLEMENTATION 63

5.2.2.1 Manipulation of Design Rules

The manipulation of CaesarJ+ design rules is composed of two specific activities, trans-

formation of the complements construct into an inheritance relationship, and duplication

of complementary cclasses method signatures into the complemented cclasses. List-

ing 5.8 shows ManipDrDec, the Stratego/XT rule responsible for this transformation step.

Listing 5.8 Manipulation of Design Rules

1 rules

2

3 ManipDrDec :

4 DrDec (DrDecHead ( drId , params ) ,DrBody(members ) )

5 !>

6 DrDec (DrDecHead ( drId , params ) ,DrBody(membersMod) )

7 where

8 <copyComplementsToExtends>members ;

9 membersMod := <complementDrClassesSignatures> ;

As we can see, ManipDrDec modifies the members declared inside the DR body (Lines

4-6), which are declarations of DR roles. Strategy copyComplementsToExtends (Line 8) is

responsible for transforming the complements construct into an inheritance relationship.

However, the complements construct are not yet removed, they are also used during

the manipulation of DR instances. Then, complementDrClassesSignatures strategy is

applied over the resulting term, copying method signatures of complementary roles to the

complemented roles. After this step, the design rules are ready to be transformed into

generic ACIs.

5.2.2.2 Compilation of DR implementations

The compilation of cclasses which implements CaesarJ+ design rules is composed by

three activities: verification of the provided methods, compilation of cclasses and up-

date of references. Listing 5.9 presents handleNonDrDec, the strategy responsible for this

second step of our transformation process. The list of DR declarations is provided as a

parameter for this strategy (initialDrDecList).

This step starts by obtaining the list of cclasses which implement design rules. This

is done by the strategy getCClassImplementsDr (see Line 5), which applies some list

filters to retrieve these cclasses. In Line 6 we have verifyClassesImplementations,

strategy responsible for verifying if the cclasses provide all the implementations of the

DR roles that they declare to implement. This strategy is applied over the term resultant

of getCClassImplementsDr and uses the list of DR declarations as a parameter.

Page 79: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.2 COMPILER IMPLEMENTATION 64

Listing 5.9 Compilation of DR implementations

1 strategies

2

3 handleNonDrDec ( | i n i t i a lD rDe cL i s t ) =

4 ? al lSystemDec ;

5 getCClassImplementsDr => cc lasses ImplementDr ;

6 ver i f yC las s es Impl ementa t i on s ( | i n i t i a lD rDe cL i s t ) ;

7 <compileDrRelatedCClasses> cc lasses ImplementDr => compi l edCc las s es ;

8 l i s tCc las sUpdated := <getListCclassUpdated ( | [ ] ) > compi l edCc las s es ;

9 <mergeClasses ( | compi ledCclasses , l i s tCc l as sUpdated )> al lSystemDec ;

10 updateReferencesCompi ledCClasses ( | l i s tCc l as sUpdated )

The compilation of cclasses, which is responsible for creating the collaboration and

updating the inheritances of the cclasses, is done inside compileDrRelatedCClasses

(Line 7). Strategy getListCclassUpdated generates a list of pairs, with the old cclasses

name and their new name after the compilation, whereas mergeClasses (Line 9) merges

this list of compiled cclasses with the other cclasses of the system. In Line 10 we have

updateReferencesCompiledCClasses, strategy which is responsible for the last activity

of this step, the actualization of references to the compiled cclasses.

After this second step, all the cclasses which implement design rules are now col-

laborations, and references to this classes have been updated, pointing now to the virtual

classes of the created collaborations.

5.2.2.3 Manipulation of DR instances

Four activities compose the manipulation of DR instances transformation step: verifi-

cation of DR instances, generation of specific interfaces, generation of mixins and actu-

alization of DR instance references. Listing 5.10 depicts handleDrInstantiation, the

strategy responsible for this transformation step. It starts by separating the declarations

of DR instances from the other declarations of the program (Lines 5-6).

Strategy verifyClassesInstantiation (Line 7) verifies if cclasses specified at the

DR instances implement the correct parameters of the DR that is being instantiated.

The strategy genInterfacesAndInstanceListParam (Lines 9-11) is responsible for

generating the specific ACIs for each DR instance. We use the hashGenInterfaceIds

hashtable to avoid the generation of two specific ACIs with the same name, as it could

occur if we have more than one instantiation of the same DR using the same classes as pa-

rameters (see Section 5.1.4). Strategy genInterfacesAndInstanceListParam generates

a tuple composed by (1) a list with the generated specific ACIs, and (2) a list of pairs of

the form (class, List-Of-Interfaces-To-Implements) for all classes declared within

Page 80: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.2 COMPILER IMPLEMENTATION 65

an DR instance. In this way, updateReferences (Lines 12-14) uses this list of pairs to

update the inheritances of each class that implements a DR role, replacing the inheritance

of the generic ACI for the newly created specific ACI.

Listing 5.10 Manipulation of DR instances

1 strategies

2

3 hand l eDr Ins tan t i a t i on ( | l i s tDrDec ) =

4 ? al lSystemDec ;

5 < f i l t e r (? DrInstance ( , , ))> al lSystemDec => l i s tD r I n s t a n c e s ;

6 < f i l t e r (not (? DrInstance ( , , )))> al lSystemDec => l i s tNo tDr In s tance s ;

7 <v e r i f yC l a s s e s I n s t a n t i a t i o n ( | l i s tDrDec , l i s tNo tDr In s tance s)> l i s tD r I n s t a n c e ;

8 new!hashtab l e => hashGenInter f ace Ids ;

9 ( i n t e r f a c e L i s t , l i s tDrInstancesAndParams) :=

10 <genInter facesAndInstanceListParam ( | l i s tDrDec ,

11 hashGenInter face Ids , [ ] , [ ] )> l i s tD r I n s t a n c e s ;

12 newSystemDec :=

13 <updateReferences ( | l i s tDrDec ,

14 l i s tDrInstancesAndParams)> l i s tNo tDr In s tance s ;

15 generatedMixins :=

16 <generateMixinsFromInstances ( | [ ] , l i s tNotDr Ins tance s ,

17 l i s tDrDec)> l i s tD r I n s t a n c e s ;

18 <concat> [ i n t e r f a c eL i s t , newSystemDec , generatedMixins ]

Strategy generateMixinsFromInstances (Lines 15-17) is responsible for generating

the mixins for each DR instance, as introduced in Section 5.1.4. Here it is necessary to

analyze which classes are complemented (by analyzing the complements construct which

is still present), in order to create the inner-mixins for the complemented classes (see

Section 5.1.4).

The last activity of this step, actualization of DR instances references, is not yet

implemented. More details about the actual limitations of CaesarJ+ compiler are detailed

in Section 5.2.3. Finally, in Line 18 we have the concatenation of the generated interfaces,

the updated system declarations and the newly generated mixins, which compose our

transformed CaesarJ program.

After this step we have transformed almost all CaesarJ+ construct of the input pro-

gram into CaesarJ code. However, it is still necessary to remove the complements con-

struct from the generated specific ACIs, which are still present in the tree of terms.

Strategy removeComplementsFromSignatures, depicted in Line 19 of Listing 5.7, is re-

sponsible for removing this constructor.

Page 81: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.2 COMPILER IMPLEMENTATION 66

5.2.3 Compiler Limitations

CaesarJ+ compiler prototype was developed in order to evaluate the constructs proposed

in this work. In this way, some functionalities were not implemented, while some of the

implemented functionalities have restrictions. In this section we discuss the limitations

of the actual implementation.

Regarding the whole compilation process, our compiler can handle only a single file

as input. Thus, in order to compile a CaesarJ+ program, it is necessary to copy all of its

code into a single archive. As our idea is to validate the proposed constructs, we prefer

not to lose time extending the compiler to handle multiples CompilationUnit (multiple

files) at the same time.

Considering the complements construct, the update of pointcuts described in Sec-

tion 5.1.2 is not yet implemented. Also, the transformation of the DR instances is not

completely implemented. The actual compiler does not support references to specific

DR instances (or DR roles), as the updating of DR instances references (fourth stage of

Section 5.1.4) is still to be implemented. For example, the code of Listing 5.5, which

depicts the syntax designed for our language, actually must be written as described in

Listing 5.11. As we can see, it is necessary to direct reference the cclass which im-

plement the DR role during variable declarations (NextPieceBase, Line 3) and cclass

instantiation (Line 7).

Listing 5.11 How currently CaesarJ+ compiler accepts references to DR roles

1 dr NextPieceInstance = NextPieceDR [ NextPieceBase , EasyVar iat ion ]

2

3 public class Main {

4 NextPieceBase common ;

5

6 public stat ic void main ( int [ ] a r gs ) {

7 . . .

8 common = new NextPieceBase ( ) ;

9 }

10 }

Another limitation of the actual compiler is related to the enhancement of expressive-

ness introduced in Section 4.5. The method signatures that use wildcards and the advice

restrictions are not complete, so they are not copied into the generated specific ACIs.

Instead, they should be verified in order to check if their restrictions are being matched.

However, these verifications are not yet implemented.

The actual implementation also lacks a more precise and accurate validation and

error message mechanism for invalid structures. Stratego/XT error messages are vague,

Page 82: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

5.2 COMPILER IMPLEMENTATION 67

general. In this way, the error messages generated by CaesarJ+ compiler are also general,

without informing, for example, the specific position of the error. Besides that, some

validations are not yet implemented. A possible improvement is to make a verification

using a compiler system, like JastAdd [26, 27], which is more suitable for validate the

code structure and generate proper error messages, before applying the Stratego/XT

transformations.

Page 83: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CHAPTER 6

EVALUATION

In this chapter we present an evaluation of CaesarJ+. As the objective of this work is to

enable the definition of design rules which increase CaesarJ modularity, our evaluation

compares CaesarJ implementations using ACIs with CaesarJ+ implementations which

use the introduced Design Rules to specify interfaces.

For this, we consider the same criteria of [43] for comparing languages, which are [18]:

• Language expressiveness: quantifies the degree to which a language is able to

express a restriction. It is a three level factor — a language supports, does not

support, or partially supports a specific rule.

• Language conciseness: measures how simple it is to express a restriction in

a language. We use the number of tokens required to express a constraint as a

measurement of conciseness.

Three examples are used in this evaluation, the Tetris SPL di!culty feature (Sec-

tion 6.1), an implementation of the Observer design pattern (Section 6.2), and one con-

cern of the Health Watcher System [53] (Section 6.3). The latter example also compares

the LSD (see Section 7.1.4) design rules with CaesarJ+ design rules.

6.1 TETRIS SPL - DIFFICULTY FEATURE

The Tetris SPL di!culty feature (briefly introduced in Section 3.1) is responsible for

displaying the box which shows the next tetris block (piece) of the game. This feature

has several variations, such as easy and normal, which show, respectively, the next two

pieces or the next piece that appear on the screen. The only di"erence between the

variations are (1) the update of the piece(s) to be displayed, and (2) the dimensions and

caption of the box which displays the next piece(s) on the screen. It is important to

note that the update of the next block(s) happens in several places of the source code,

for example, after a piece is dropped, when the game is restarted, when it is paused or

resumed, etc.

68

Page 84: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.1 TETRIS SPL - DIFFICULTY FEATURE 69

In this way, in order to have a modular development of this feature, we should be able

to specify the following restrictions:

(R1) The implementation of the feature must contains two types of operations:

• Invariant operations, which are reused independently of the selected vari-

ation (easy or normal, for instance). They are responsible (1) for the initial

configuration of the component, which receives the dimensions of the box and

the class that has the graphic component (setup method, for example), (2) for

the representation of each piece (drawPiece) on the box, and (3) for the gen-

eral steps necessary for painting (paint) the box on the screen. These general

paint steps are independent of the selected variation, for example, defining the

initial position of the box (x and y), setting the background color, etc.

• Variant operations, which have a specific implementation depending on

which variation is selected. They are responsible for updating (update) the

pieces that appear on the game and for painting the box (paintBox) which

displays the next piece(s) to be dropped.

(R2) We aim to separate development of common (invariant) and variant operations. The

design rule which express these restrictions needs to have at least two roles, one

for the common operations and the other for the variant methods (NextPieceBase

and NextPieceVariation, for instance).

(R3) Common and variant operations depend on each other, as the general paint method

(paint) calls the specific paint operation (paintBox) provided by each variation,

and, in order to represent the next piece that is displayed, these specific paint oper-

ations call the invariant operation responsible for drawing each piece on the screen

(drawPiece). Moreover, the variant method updatePiece, which is responsible

for the update of the next block that is dropped, needs to call the generic paint

method. This implies that we have a bi-directional dependency between modules

which express common and variant operations.

(R4) As the update of the next piece to be displayed is scattered throughout di"er-

ent places (methods), we need a pointcut which specifies the set of join points

that should match. For example, the execution of Canvas class methods init and

updateBoxes. This pointcut is independent of which variation is selected.

Page 85: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.1 TETRIS SPL - DIFFICULTY FEATURE 70

(R5) We need to specify that an advice, which uses at least the pointcut defined in R4,

must be implemented by the module responsible for the invariant operations. In

this case, it might be after advice.

(R6) It is also necessary to define that classes and methods used in the pointcuts declared

on the DR must exist. In this way, we can assure that classes and operations

specified on the pointcuts have an implementation.

Listing 6.1 shows a design rule specified using CaesarJ ACIs for the Tetris SPL di!-

culty feature, which is a more detailed version of the DR introduced in Listing 3.9. This

interface tries to impose restrictions R1 to R6. Lines 7-9 and 19-20 specify the common

and the variant methods of R1, respectively, whereas Lines 4-5 depict the attributes used

by these methods1.2.

Listing 6.1 CaesarJ ACI for the di!culty feature

1 public abstract cclass NextPieceCI {

2 public abstract cclass NextPieceBase {

3

4 protected int width , he i ght ;

5 protected Tetr i sCanvas tc ;

6

7 public abstract void setup ( int width , int height , Tetr i sCanvas tc ) ;

8 protected abstract void paint ( ) ;

9 protected abstract void drawPiece ( int type ) ;

10

11 protected abstract void paintBox ( ) ; // Implemented by var i a t i on

12 public abstract void updatePiece ( ) ; // Implemented by var i a t i on

13

14 pointcut matchCanvas ( ) : execution (! Canvas+. i n i t ( . . ) )

15 | | execution (! Canvas+. s ideBoxes ( . . ) ) ;

16 after ( ) : matchCanvas ( ) { }

17 }

18 public abstract cclass NextPieceVar iat ion extends NextPieceBase {

19 protected abstract void paintBox ( ) ;

20 public abstract void updatePiece ( ) ;

21 }

22 public abstract cclass Canvas {

23 protected abstract void i n i t ( Graphics g ) ; //Used by the po in t cu t s

1On theory the Canvas cclass must inherit from the JME Api Canvas class. However, as CaesarJ

classes cannot inherit from Java classes, we use the TetrisCanvas type, which inherits from Canvas

JME API class and is responsible for instantiate and communicate with the Canvas CaesarJ class of

Listing 6.1.2We use the TetrisCanvas type because CaesarJ classes cannot inherit from Java classes, i.e., the

Canvas role cannot inherit from the Java class which provides the paint component.

Page 86: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.1 TETRIS SPL - DIFFICULTY FEATURE 71

24 protected abstract void s ideBoxes ( Graphics g ) ; //Used by the po in t cu t s

25 }

26 }

As we can see, this DR defines two roles, one for the common operations (NextPiece-

Base, 2-17) and another for the variant operations (NextPieceVariation, 18-21), which is

demanded by R2. However, the CaesarJ compiler does not enforce that all the virtual

classes defined within a given ACI must be implemented, which means that R2 is only par-

tially assured (checked). Restriction R3 can be specified with the duplication of method

signatures of one role inside another role (NextPieceVariation methods duplicated in-

side NextPieceBase, Lines 11-12), as detailed in Sections 3.2.2 and 3.3.2. However, it

compromises the comprehensibility of the DR, as this duplication generates a confusing

interface.

The matchCanvas pointcut (Lines 14-15) specifies R4. However, the pointcut alone

is not enough to guarantee that methods init and sideBoxes of a Canvas class exist,

which is required by R6. In this way, the Canvas role is declared in Lines 22-25, defining

that its implementations must provide at least methods init and sideBoxes. However,

as already stated, CaesarJ compiler does not enforce that Canvas virtual class will have

an implementation, which leaves R6 partially assured.

Line 16 presents an after advice which attempts to represent R5. However, it is a

weak condition, since R5 states that an after advice, which uses at least matchCanvas

pointcut, must be present in the implementation of the invariant operations, whereas Line

16 means that this DR role has an empty after advice. In this way, if the implementation

of NextPieceBase does not have an advice, or has one which does not use matchCanvas,

no error message is indicated by CaesarJ compiler.

Listing 6.2 CaesarJ+ Design Rule for the di!culty feature

1 dr NextPieceDR [Common, Var iat ion , Canvas ] {

2 public abstract cclass Common {

3 protected int width , he i ght ;

4 protected Tetr i sCanvas tc ;

5

6 public abstract void setup ( int width , int height , Tetr i sCanvas tc ) ;

7 protected abstract void paint ( ) ;

8 protected abstract void drawPiece ( int type ) ;

9

10 pointcut matchCanvas ( ) : execution (! Canvas+. i n i t ( . . ) )

11 | | execution (! Canvas+. s ideBoxes ( . . ) ) ;

12 after ( . . ) : matchCanvas ( ) . . ;

13 }

14 public abstract cclass Var iat i on complements Common {

15 protected abstract void paintBox ( ) ;

Page 87: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.1 TETRIS SPL - DIFFICULTY FEATURE 72

16 public abstract void updatePiece ( ) ;

17 }

18 public abstract cclass Canvas {

19 protected abstract void i n i t ( . . ) ; //Used by the po in t cu t s

20 protected abstract void s ideBoxes ( . . ) ; //Used by the po in t cu t s

21 }

22 }

The use of CaesarJ+ design rules can mitigate these problems. Listing 6.2 depicts

NextPieceDR, a CaesarJ+ design rule for this feature. This DR looks similar to the

ACI of Listing 6.1, however, it guarantees restrictions R1 to R6. CaesarJ+ compiler

enforces that all the roles declared as NextPieceDR parameters must be implemented

when this DR is being used, encompassing R2 and R6. Line 13 depicts an after advice

which uses the matchCanvas pointcut, the wildcard “..”, and does not have a body. This

declaration means that the implementation of the Common role must have an after advice

which uses at least the matchCanvas pointcut (minimum requirement that matches the

wildcards), otherwise an error is raised by the compiler3. Moreover, the complements

construct enables the bi-directional dependency among two roles (restriction R3), without

compromising the comprehensibility of the DR.

Table 6.1 summarizes our evaluation for this example. Regarding expressiveness,

restrictions R1, R3 and R4 are statically checked by CaesarJ compiler, although the

representation of R3 compromises the ACI comprehensibility. R5 cannot be expressed

(nor checked), whereas R2 and R6 are only partially checked, as the compiler raises error

if the implementation of the roles do not provide the correct methods, but no error is

given if the ACI is used without an implementation for these roles. Instead, CaesarJ+

DRs can statically check all the imposed restrictions (R1 to R6).

Table 6.1 Tetris SPL Di!culty Feature: Summary of the evaluation. The acronyms mean

Statically checked (SC), Partially checked (P) and No checking (N).

Expressiveness Conciseness

R1 R2 R3 R4 R5 R6 R1 R2 R3 R4 R5 R6

CaesarJ ACI SC PC SC* SC N PC 45 16 16 27 - 24

CaesarJ+ DR SC SC SC SC SC SC 45 19 2 27 10 26

Analyzing conciseness, we have similar numbers of tokens for both ACI and DR.

3As discussed in Section 5.2.3, this feature is not yet implemented in the actual CaesarJ+ compiler

prototype.

Page 88: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.2 OBSERVER DESIGN PATTERN 73

We consider the following as a token: language keywords (such as public, abstract),

operators (ex. &&, ||), delimiters (ex. “.”, “,”), brackets and parenthesis. Restriction,

R2 is expressed by the declarations of NextPieceBase and NextPieceVariation (Lines 2

and 18, Listing 6.1) on CaesarJ ACI, whereas it is represented by the signatures of Common

and Variation (Lines 2 and 15, Listing 6.2) plus the parameters Common and Variation

of NextPieceDR (Line 1). Similar occurs with R6, which needs two more tokens on the

DR due to the parameter Canvas (Line 1). Although there is a slight increase for this two

restrictions, the DR enables the static checking of them, which was not possible using

ACIs. Restriction R5, which cannot be expressed by the ACI, is expressed by the DR

using 10 tokens.

Considering the implementation of ACIs and DRs, when using DR we have a small

reduction on the number of tokens used, as developers now use top-level classes to im-

plement the DR roles, instead of using virtual-classes (see Section 5.1.3). Finally, the

instantiations process of ACIs and DRs uses the same quantity of tokens (Section 5.1.4).

As we can see, the use of CaesarJ+ design rules enable the specification of restrictions

which were not able to be expressed using only CaesarJ ACIs. Moreover, CaesarJ+ DRs

allows the static checking of restrictions which could not be checked by CaesarJ compiler,

representing a gain of expressiveness. Furthermore, the amount of tokens necessary by

CaesarJ+ to impose those restrictions is almost the same used by CaesarJ ACI which

can only partially express some of the restrictions.

6.2 OBSERVER DESIGN PATTERN

Mezini and Ostermann introduces in [42] the initial concepts of CaesarJ. They argue that

AspectJ Join point Interception model has some deficiencies, such as lack of support for

sophisticated mapping, as all methods of a given aspect are top-level methods of the

enclosing aspect, it is not possible to separate the roles inside an aspect. Another problem

listed is related to the aspect binding, as in AspectJ every aspect binding is coupled to

one specific implementation, it is not possible to reuse an specific binding with a di"erent

aspect implementation.

In order to detail these and other problems related to the AspectJ Join point inter-

ception mechanism, Mezini and Ostermann use an implementation of the observer design

pattern in CaesarJ4, comparing it to the AspectJ implementation of the same pattern pro-

posed by Hannemann and Kiczales [25]. The authors state that the following restrictions

4In fact, the authors detail an implementation in Caesar, which later became CaesarJ.

Page 89: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.2 OBSERVER DESIGN PATTERN 74

should be respected:

(R1) We must be able to define multiple abstractions (facets) inside the aspect, one

representing the Subject and the other representing the Observer. This increases

the aspect internal separation of concern, which cannot be done using AspectJ.

(R2) The implementation of the Aspect facets must contain the following operations:

• Subject: Amethod for inserting a new Observer (addObserver), an operation

which removes a specific observer (removeObserver), and a method for up-

dating the observers (update) are needed. A method which returns a String

containing informations about the specific state of the updated subject is also

necessary (getState).

• Observer: This facet needs a method which is notified about modifications

that occur within a subject which is being observed (notify).

(R3) The Aspect implementation should be separate from the binding, allowing the reuse

of an Aspect implementation in di"erent contexts (with di"erent bindings), and the

reuse of an Aspect binding (for a specific context) with di"erent implementations.

The Subject abstraction, for example, has operations related to the Aspect im-

plementation (addObserver, removeObserver and update, these implementations

depend on the date structure used), and one method related to the class which is

being a"ected by the aspect (getState).

Listing 6.3 depicts ObserverProtocol, the CaesarJ ACI for the observer design pat-

tern implementation5. The definition of virtual classes Subject and Observer (Lines 2

and 9) specifies R1. However, as previously discussed, CaesarJ compiler does not enforce

that these virtual classes will be implemented. For example, no error is given if only

an implementation of Observer is provided. Lines 3-6 and Line 10 guarantee that the

implementation of Subject and Observer, if provided, have all the needed methods (R2).

Listing 6.3 CaesarJ ACI for the observer design pattern

1 public abstract cclass ObserverProtocol {

2 public abstract cclass Subject {

3 public abstract void addObserver ( Observer o ) ;

4 public abstract void removeObserver ( Observer o ) ;

5 public abstract void update ( ) ;

6 public abstract Str ing getState ( ) ;

5The Observer is an o!cial CaesarJ example and its source code can be downloaded at [10].

Page 90: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.2 OBSERVER DESIGN PATTERN 75

7 }

8

9 public abstract cclass Observer {

10 public abstract void no t i f y ( Subject s ) ;

11 }

12 }

The implementations of this ACI roles use the wrapper (see Section 2.3.4) mechanism

to adapt (bind) existing classes to the aspect facets (roles) Subject and Observer, as we

can see in Listing 6.4. However, considering R3, the ObserverProtocol ACI does not

have any indication that the getState method should be developed separated from the

other methods, inside a module responsible only for the aspect binding. We can extend

this ACI splitting the Subject role into two roles, Subject and SubjectImplementation,

similar to NextPieceBase and NextPieceVariation of Listing 6.1. However, even with

this extension we can only partially express R3, as the extension would lead to the same

problems of duplicated methods discussed in Sections 3.2.2 and 3.3.2.

Listing 6.4 CaesarJ Implementation of Subject binding

1 public abstract cclass ColorObserver extends ObserverProtocol {

2 public cclass PointSubject extends Subject wraps Point {

3 public Str ing getState ( ) {

4 return ”Point co l o r ed ” + wrappee . getColor ( ) ;

5 }

6 after ( Point p ) : ( ca l l (void Point . s e tCo lor ( Color ) ) && target (p ) ) {

7 PointSubject (p ) . update ( ) ;

8 }

9 }

10 . . .

11 }

Listing 6.5 CaesarJ+ design rule for the observer design pattern

1 dr ObserverDR [ Subject , SubjectImplementat ion , Observer ] {

2 public abstract cclass Subject {

3 public abstract Str ing getState ( ) ;

4 }

5 public abstract cclass SubjectImplementation complements Subject {

6 public abstract void addObserver ( Observer o ) ;

7 public abstract void removeObserver ( Observer o ) ;

8 public abstract void update ( ) ;

9 }

10 public abstract cclass Observer {

11 public abstract void no t i f y ( Subject s ) ;

12 }

13 }

Listing 6.5 depicts a possible CaesarJ+ design rule for this example. Di"erent from

the ObserverProtocol ACI, now we have a clear identification on the design rule of

Page 91: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.2 OBSERVER DESIGN PATTERN 76

roles Subject, responsible for the binding, and SubjectImplementation, responsible for

the implementation facet. In this way, R3 is now guaranteed, as the implementation

of Subject provides the binding method getState, whereas the cclass implementing

SubjectImplementation provides the methods of the implementation facet, otherwise

a compiler error is raised. Due to the complements relationship, the Subject object

received by Observer method notify (Line 11) has access to both operations of Subject

and SubjectImplementation, which is necessary by the pattern.

Restriction R1 is now enforced by CaesarJ+ compiler, as all the roles (inner cclasses)

are declared as parameters of the DR, which means that an implementation for each of

them must be provided. The other restriction, R2, is specified by Lines 3, 6-8 and 11,

which guarantee that both Subject and Observer roles have the needed methods. The

implementation of ObserverDR binding roles is similar to the implementation of a non-

binding DR role, the only di"erence is the use of the wrapper keyword and the name of

the class that we want to bind on the cclass signature, as we can see in Listing 6.6.

Listing 6.6 CaesarJ+ implementation of ObserverDR Subject binding role

1 public cclass PointSubject implements ObserverDR [ Subject ] wraps Point {

2 public Str ing getState ( ) {

3 return ”Point co l o r ed ” + wrappee . getColor ( ) ;

4 }

5 after ( Point p ) : ( ca l l (void Point . s e tCo lor ( Color ) ) && target (p ) ) { . . . }

6 }

Table 6.2 summarizes our evaluation for the Observer example, depicting the results

for the solutions using ACI (the first and the extended one) and CaesarJ+ DR to express

the interface. Considering expressiveness, the DR is able to guarantee R1 to R3, whereas

the first ACI can only express R1 and R2, but cannot statically check R2. The extended

ACI can express the three restrictions, but can only statically check R2.

Table 6.2 Observer Example: Summary of the evaluation.

Expressiveness Conciseness

R1 R2 R3 R1 R2 R3

CaesarJ ACI PC SC N 12 41 -

Extended CaesarJ ACI PC SC PC 12 41 33

CaesarJ+ DR SC SC SC 15 41 10

In order to express R1, the number of tokens used by the DR has a slightly in-

Page 92: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.3 HEALTH WATCHER TRANSACTION CONCERN 77

crease comparing to the ACI solutions (15 to 12), however the DR solution now enforces

this restriction, whereas the ACI solutions can only partially check it. Moreover, the

ObserverDR uses only 10 tokens (8 tokens of SubjectImplementation signature plus 2

tokens of its parameter on the DR signature) to guarantee R3, whereas the first ACI can-

not express this restriction and the extended one uses 33 tokens (due to the duplicated

method signatures inside the Subject role) only to express R3, as it cannot statically

check it.

6.3 HEALTH WATCHER TRANSACTION CONCERN

The Health Watcher (HW) system [53] is a web-based information system originally im-

plemented in Java and later restructured with AspectJ [32]. It was developed to improve

the quality of the services provided by health care institutions, allowing citizens to reg-

ister complaints regarding health issues, so that health care institutions can investigate

and take required actions. HW design has a significant number of non-crosscutting and

crosscutting concerns, requiring a number of recurrent design decisions related to Trans-

actions, GUI, persistence, and other concerns. The HW system has been used as a case

study of several aspect-oriented works [23, 53, 43].

Costa Neto [43] uses the HW Transactional Concern as one case study of his Language

for Specifying Design Rules (LSD), comparing the specification of this concern in LSD

with another implementation that uses the XPI approach [24]. In this section we compare

one CaesarJ+ DR for this example with the LSD DR introduced by Costa Neto and with

an implementation using CaesarJ ACIs.

In order to enable the parallel development between classes and aspects responsible

for implementing the transaction concern, the following restrictions must be specified by

our interface [43]:

(R1) There must exist an interface (ITransactionMechanism) that defines methods for

starting (begin), committing (commit), and rolling back transactions (rollback);

(R2) These methods may throw an exception TransactionException in case of error;

(R3) Also, in order to enable the definition of the pointcuts, we need to specify a facade

named HWFacade;

(R4) The transaction aspect HWTransactionAspect must call ITransactionMechanism

methods. Moreover, these calls have to occur at specific places, detailed in what

follows:

Page 93: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.3 HEALTH WATCHER TRANSACTION CONCERN 78

• A transaction must be started before any facade method (the aspect should

call ITransactionMechanism.begin());

• After the return of any facade method, the current transaction should be

committed (the aspect should call ITransactionMechanism.commit());

• If any exception is raised by facade methods, the current transaction should

be rolled back (the aspect should call ITransactionMechanism.rollback());

and

(R5) These calls must only occur within the aspect HWTransactionAspect.

Listing 6.7 shows the LSD (see Section 7.1.4) design rule for the HW Transaction

Concern. Without discussing syntax details, TransactionManagementDR restricts that

ITransactionMechanism must be an interface with three methods that throw an excep-

tion (R1 and R2), and that TransactionManagement must be an aspect, otherwise a

compilation error is raised. In addition, LSD xcall construct assures that a call occurs

only within a specified scope among the DR components. In this way, the DR restricts

that begin, commit and rollback can only be called within before, after returning

and after throwing advice, respectively (R4 and R5). The DR also states that a class

named HWFacade must exists (R3).

Listing 6.7 LSD design rule for the HW Transaction Concern

1 dr TransactionManagementDR

2 [ ITransactionMechanism , TransactionManagement , HWFacade ] {

3

4 interface ITransactionMechanism {

5 void begin ( ) throws Transact ionException ;

6 void commit ( ) throws Transact ionException ;

7 void r o l l ba ck ( ) throws Transact ionException ;

8 }

9 aspect TransactionManagement {

10 pointcut t r an s ac t i ona lPo i n t s ( ) : ca l l (! HWFacade . ! ( . . ) ) ;

11

12 be f o r e ( ) : t r an s a c t i ona lPo i n t s ( ) {

13 xcal l (void ITransactionMechanism . begin ( ) ) ;

14 }

15 after ( ) returning : t r an s a c t i ona lPo i n t s ( ) {

16 xcal l (void ITransactionMechanism . commit ( ) ) ;

17 }

18 after ( ) throwing : t r an s a c t i ona lPo i n t s ( ) {

19 xcal l (void ITransactionMechanism . r o l l ba ck ( ) ) ;

20 }

21 }

22 class HWFacade { }

23 }

Page 94: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.3 HEALTH WATCHER TRANSACTION CONCERN 79

Listing 6.8 depicts the implementation for the Transaction Management feature using

CaesarJ+ DR. The abstract cclass ITransactionMechanism (Lines 2-6) specifies R1 and

R2, depicting the three methods throwing a specific exception (TransactionException),

whereas HWFacade (Line 13) specifies R4. The TransactionManagement role specifies that

its implementation must have three advices using the transactionalPoints pointcut, but

it is not possible to define restrictions over the behavior of this advice, which is demanded

by R4. However, as stated in Section 7.2, we do plan to include behavioral restrictions

in CaesarJ+. Regarding R5, it is also not possible to express in CaesarJ+ that calls to

a method must occur only inside a given scope, which is defined in LSD by the xcall

construct.

Listing 6.8 CaesarJ+ design rule for the HW Transaction Concern

1 dr TransactionDR [ ITransactionMechanism , TransactionManagement , HWFacade ] {

2 public abstract cclass ITransactionMechanism {

3 public abstract void begin ( ) throws Transact ionException ;

4 public abstract void commit ( ) throws Transact ionException ;

5 public abstract void r o l l ba ck ( ) throws Transact ionException ;

6 }

7 public abstract cclass TransactionManagement {

8 pointcut t r an s ac t i ona lPo i n t s ( ) : ca l l (! HWFacade . ! ( . . ) ) ;

9 b e f o r e ( ) : t r an s a c t i ona lPo i n t s ( ) ;

10 after ( ) returning : t r an s a c t i ona lPo i n t s ( ) ;

11 after ( ) throwing : t r an s a c t i ona lPo i n t s ( ) ;

12 }

13 public abstract cclass HWFacade { }

14 }

Table 6.3 shows the results of our evaluation for the HW Transaction Concern. Note

that neither CaesarJ ACI (see Listing 6.9) nor CaesarJ+ DR can express R5, while

CaesarJ+ DR can only partially express R4, as it can specify that some advice, which

use a specific pointcut, must be present on the role implementation, but it cannot enforce

that those advice have to call a specific method. Moreover, CaesarJ ACI cannot express

restrictions over advice, and CaesarJ compiler does not statically check R1 and R3, as

no error is given if implementations of ITransactionMechanism nor HWFacade virtual

classes are not provided.

Listing 6.9 CaesarJ ACI for the HW Transaction Concern

1 public abstract cclass TransactionACI {

2 public abstract cclass ITransactionMechanism {

3 public abstract void begin ( ) throws Transact ionException ;

4 public abstract void commit ( ) throws Transact ionException ;

5 public abstract void r o l l ba ck ( ) throws Transact ionException ;

6 }

7 public abstract cclass TransactionManagement {

Page 95: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

6.3 HEALTH WATCHER TRANSACTION CONCERN 80

8 pointcut t r an s ac t i ona lPo i n t s ( ) : ca l l (! Facade . ! ( . . ) ) ;

9 }

10 public abstract class Facade { }

11 }

Table 6.3 HW Transaction Concern: Summary of the evaluation.

Expressiveness Conciseness

R1 R2 R3 R4 R5 R1 R2 R3 R4 R5

LSD DR SC SC SC SC SC 20 6 6 81 9

CaesarJ ACI PC SC PC N N 27 6 6 - -

CaesarJ+ DR SC SC SC PC N 28 6 8 50 -

Analyzing conciseness, we have similar number of tokens used in both LSD DR and

CaesarJ+ DR. CaesarJ+ needs more tokens to express some restrictions due to the key-

words public and abstract, which must be present on the DRs. If we had a construct

similar to LSD call or xcall in CaesarJ+, we would use 30 more tokens to express and

check R4, resulting in 83 tokens, only two tokens more than LSD. As already said, these

two tokens are relative to the keywords public and abstract (Line 7 of Listing 6.8).

Page 96: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

CHAPTER 7

CONCLUDING REMARKS

In this work we present CaesarJ+, an extension to increase CaesarJ modularity. CaesarJ+

introduces design rules construct, which enforces syntactic restrictions over multiple roles

that collaborate in a specific context. As these roles are implemented by caesarj classes, we

can define restrictions on the DR relative to both Object-Oriented and Aspect-Oriented

code. In this way, by using the design rules we can obtain crosscutting modularity with-

out compromising class modularity. A CaesarJ+ compiler was developed to verify wether

the rules specified within the DRs are being obeyed. It uses the Stratego/XT [8] trans-

formation language and generates valid CaesarJ code after the compilation process. We

evaluate CaesarJ+ by specifying interfaces for three di"erent examples, using CaesarJ+

DRs and CaesarJ ACI, and them comparing the expressiveness and conciseness of both

approaches.

Initially we studied the use of CaesarJ ACIs to specify interfaces for OO and AO code.

However, regarding modularity, we have found several issues when specifying ACI inter-

faces. For example, some roles cannot be well defined on the ACIs (duplicated code), and

CaesarJ compiler does not enforce that all the specified roles must have an implementa-

tion, compromising the parallel (independent) development. CaesarJ+ design rules, for

instance, enforces that all roles specified within a DR must have an implementation. Our

extension introduces the complements relationship, enabling the parallel development of

parts of a class. CaesarJ+ is also more expressive than CaesarJ, as our DR notion allows

the use of AspectJ like wildcards to specify rules for methods and advice restrictions,

whereas CaesarJ ACIs has only exact restrictions, and they cannot express advice re-

strictions. Nevertheless, CaesarJ+ can only express syntactic restrictions. Our DRs are

not able to express semantic restrictions. CaesarJ+ also facilitates the implementation

of the DR roles, as developers use top-level classes to implement the DRs roles, while,

when using ACIs, they had to define both a top-level class and a virtual class.

In order to use CaesarJ+, developers must get used to the new languages constructs.

On the other hand, it helps the development of the new OO and AO code, as the DRs

express and check restrictions that should be obeyed by the developers. Our language,

does not verify wether changes on roles implementations break the intents of an aspect.

81

Page 97: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

7.1 RELATED WORK 82

However, it provide the necessary informations for the identification of these issues by

developers, as classes participating of a collaboration must explicitly implement a DR,

indicating to the developer that he must analyze the DR code prior to any changes. We

believe that it helps to mitigating the fragile pointcut problem [36].

Although we discuss the use of CaesarJ+ DRs to guide the independent development

of OO and AO code, our design rules can also be useful to existing CaesarJ systems.

In this scenario, some modifications on the source code need to be applied, but after

established, CaesarJ+ DRs assist software maintenance and evolution, guiding developers

to discover what changes they are able to do without modifying the aspects intentions.

In summary, the main contributions of this work are:

• An analysis of the use of CaesarJ ACIs focusing on the specification of modular

interfaces for OO and AO code;

• CaesarJ+, a language that enables the specification of design rules for increase

CaesarJ modularity;

• A compiler for CaesarJ+, which allows the static checking of the restrictions spec-

ified on the design rules.

7.1 RELATED WORK

Several authors have been discussing modularity problems in aspect-oriented languages [50,

54, 57, 12]. For instance, Rajan and Sullivan [50] argue that the asymmetry of classes

and aspects complicates system composition, harming modularity. For them, separating

classes and aspects reduces the conceptual integrity of the programming model. In this

way, they propose Classpects, a construct that unifies the capabilities of classes and as-

pects. As a proof of concept, they use a classpect-oriented language, which uses static

and non-static binding along with method calls (binding methods) to replace the un-

named AspectJ-like advice. This static and non-static binding are similar to CaesarJ

dynamic binding, while both languages enable aspects instances. However, di"erent from

CaesarJ+, Classpects does not have any interface mechanism which can specify and check

restrictions of related OO and AO code.

In a similar way, Clifton and Leavens state that AOP languages harm comprehensibil-

ity, since they require system to be studied in their entirety [12]. They propose a simple

set of restrictions to improve comprehensibility in AOP systems, which characterizes as-

pects as (1) observers, which does not change modules specifications, or as (2) assistants,

Page 98: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

7.1 RELATED WORK 83

aspects that might change module specifications. Observers preserve modular reasoning

even in the cases that advised modules do not make explicit references to them. The

authors argue that modules advised by assistants aspects should make explicit references

them, in order to preserve the modular reasoning. They introduce accept type, a new

construct which indicates that a module accepts to be advised by an assistant aspect.

In this way, class developers become aware that an assistant aspect exists and should be

studied before any modifications on the code. CaesarJ+ DRs, for instance, can depict the

necessary pointcuts and also have informations about advice. Thus, it informs developers

that a specific AO implementation should be observed, avoiding the need of a complete

system study.

Chavez et al [11] present crosscutting interfaces as a conceptual tool for dealing with

complexity of heterogeneous aspects at the design level. This work also presents a mod-

eling notation for description of architectural-level aspects that also supports the explicit

representation of crosscutting interfaces. However, despite of using a visual notation is

important for documentation purpose, it does not enable to check if the code was built

according to established interfaces.

On AspectJ [34, 33] we can define abstract aspects, which may work like an interface.

However, they can only specify restrictions related to structure of aspects, its not possible

to specify classes restrictions. Moreover, we cannot define multiple roles inside an abstract

aspects, in order to organize the multiple facets of a given crosscutting concern, as we

can do with CaesarJ+ DRs. Also, it is not possible to define any restrictions related to

advice. CaesarJ+ DRs, for instance, can enforce restrictions to aspects and classes. It is

possible to define multiple facets (roles) inside our DRs, and they can specify restrictions

related to advice.

Other works discuss how to expose more stable aspect-oriented interfaces and how to

compute module interfaces in AOP systems. In the following sections we discuss some of

these work, which are more related to our proposal.

7.1.1 Open Modules

Open Modules is an approach for dealing with modularity issues in AOP [3]. Aldrich

suggested that any exposed joinpoint must be declared in the interface of a module. In

this way, the maintainer of this module has to preserve the joinpoint behavior, helping

to mitigate the fragile pointcut problem. Clients of these modules can advise only the

exported pointcuts, which introduces a form of module joinpoint encapsulation. A later

Page 99: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

7.1 RELATED WORK 84

work provides a open-modules implementation for AspectJ [45], generalizing the open

modules to handle arbitrary AspectJ pointcuts.

However, this joinpoint hiding mechanism does not provide any information to the

aspect developer beyond the exported joinpoints and public methods, like advice infor-

mation and use of a certain pointcut by an advice, which are useful for helping aspects

developers. CaesarJ+, on the other hand, o"er mechanisms to describe all the types that

participate of a given collaboration, beyond the possibility to describe aspect responsi-

bilities, as the existence of a specific advice. As a consequence, module developers are

still able to unintentionally implement part of a concern assigned to a di"erent team

because they cannot assume the existence of any behavior expected to be modularized

as an aspect.

7.1.2 Aspect Aware Interfaces

Kiczales and Mezini discuss in [35] about interfaces for modules in systems developed

with AOP. The authors state that, when using Aspects, it is necessary to analyze the

whole system in order to determine the complete interface of a module. They introduce

Aspect-Aware Interfaces (AAI), a new type of interface which is automatically computed

after each modification on the source code. This interface shows the dependencies between

related classes and aspects, specifying where a given aspect a"ects each system class. The

authors argue that Aspect-Aware interface helps developers to reason about the e"ects

of new modifications on the source code.

A later work [52] stores the computed AAIs and compare then with new interfaces

generated after modifications on the source code, verifying if there is any change on the

join points intercepted by the aspects. This approach identifies missing and accidentally

captured join points. In this way, AAIs are very useful for evolution of a AO system.

However, this approach does not support earlier development phases, as this interfaces

are only generated after the whole system is ready. CaesarJ+ DRs, for instance, should

be specified before the development of the OO and AO code, being used as a guide for

the development of both classes and aspects. Moreover, the use of CaesarJ+ DRs enables

the static checking of the development code, verifying if they match the established rules.

7.1.3 Crosscutting Programming Interfaces (XPIs)

Sullivan et al. present in [57] a comparative analysis between an AO system developed

using the oblivious approach and the same system developed with clear design rules that

Page 100: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

7.1 RELATED WORK 85

document interfaces between classes and aspects. The latter approach promises benefits

when relevant crosscutting behavior are anticipated and when new code, anticipated or

not, can be written against existing interfaces (design rules). However, this work uses

natural language to describe the design rules, which may lead to long and ambiguous

interpretations that cannot be statically checked.

In a subsequent work [24], they propose the Crosscutting Programming Interfaces

(XPIs), which uses AspectJ to express and check their design rules. The authors argue

that the main advantages of their XPIs are that (1) it does not require any new construct

in the AspectJ language; and (2) there is no restriction to the pointcut visibility. These

characteristic encourage the use of XPIs in sites that are already using the AspectJ

language. However, most of the constraints required for defining the responsibilities of

both class developers and aspect developers cannot be checked using the proposed XPI

language, specially the restrictions relative to classes contents. In this way, di"erent

from CaesarJ+, XPIs cannot guarantee (static check) that certain design rules are being

obeyed. It happens because pointcut constructs in AspectJ were proposed for specifying

points of execution that should be augmented by advices, not for specifying restrictions

applied for base code developing.

Although it is possible to check part of the design rules using XPIs by means of AspectJ

declare warning and declare error, the use of a language not designed to this purpose leads

frequently to complex specifications (in this case, complex AspectJ pointcuts). Finally,

when using CaesarJ+ we also have all the benefits of CaesarJ aspects, such as dynamic

deploy and aspect polymorphism (Section 2.3).

7.1.4 Language for Specifying Design Rules (LSD)

Costa Neto [43, 44] proposes LSD, a language for specifying design rules in systems imple-

mented with AspectJ. As in this work, the author argues that through the establishment

of design rules it is possible to obtain crosscutting modularity and preserve class mod-

ularity. LSD provides structural and behavioral rules witch enable the establishment of

minimum requirements necessary for a independent development of related classes and

aspects. The structural rules specify which artifacts should be implemented (interfaces,

classes or aspects) and what should be implemented by these artifacts (methods, at-

tributes, pointcuts, advice), whereas the behavioral rules restricts what should happen

inside a specific scope, for example, a method call or the definition (set) or retrieval (get)

of a specific attribute.

Page 101: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

7.1 RELATED WORK 86

LSD provides powerful constructs for rules quantification, such as all (for instance,

for all public methods of a class, apply one restriction), exists and none. Moreover, it

is also possible to combine LSD DR constructs with boolean operators (&&, ||) or deny

them using the negation operator (!).

CaesarJ+ is inspired on LSD, both have similar syntax, design rule parameters, and

DR instance. In this way, CaesarJ+ put together the concept of Design Rules with the

benefits of CaesarJ, allowing the static checking of the established rules, aiming to increase

CaesarJ modularity. The actual version of CaesarJ+ has only behavioral rules, however

we do plan to insert behavioral rules to our extension (see Section 7.2). Finally, LSD

is more expressive than CaesarJ+, as it has many constructs for express quantification

of rules, and its design rules instances can specify multiple classes or a package as a

DR parameter, whereas in CaesarJ+ we can only specify one class for each DR instance

parameter (Section 5.1.4).

7.1.5 CrossMDA2

CrossMDA2 [19] is a model based approach for minimizing the fragile pointcut prob-

lem. It proposes Conceptual-View Based Pointcuts , a particular instance of Kellens

model-based pointcut [29] approach, and uses View-based pointcuts [30] as a base, which

introduces an intermediate model (Conceptual Model) in order to decouple the pointcuts

from the base model (Business Model), increasing modularity. CrossMDA2 extends this

intermediate model, introducing more relationships and restrictions, increasing the model

flexibility.

This conceptual model defines design rules that must be obeyed during the devel-

opment process. It is composed of views, which are similar to our DR roles. However,

CrossMDA2 design rules are only unidirectional, their rules are only related to classes.

CaesarJ+ DRs are multidirectional, they define restriction to both classes and aspects.

Moreover, as this approach is model based, their restrictions are specific, they cannot

be generalized, relaxed. Our DRs can impose more generic restrictions with the use of

wildcards, as introduced in Section 4.5.1 (although the actual implementation does not

support it). Also, the restrictions imposed by this Conceptual Model are only structural,

similar to our restrictions and di"erent from LSD 7.1.4, which can define both behavioral

and structural restrictions.

CrossMDA2 has a map between the Conceptual Model and the Business Model, which

is similar to our design rules instantiation process. However, this mapping is much more

Page 102: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

7.2 FUTURE WORK 87

powerful than the our DR instantiation process, being even more powerful than LSD DR

instantiation process. In CrossMDA2 it is possible to define alternative instantiations

to the model, using expressions to define members responsible for each view (role), and

them verify if both alternative expressions results in the same set of members (classes,

methods, etc.), otherwise an error is raised. The actual version of CaesarJ+ allows only

a single class for each DR role in the instantiation process, whereas LSD allows group of

classes, like all classes of a given package. For example, if this alternative instantiation

process was enabled in CaesarJ+ it would look like code of Listing 7.1.

Listing 7.1 Possible alternative DR instantiation process

1 dr Al t e r na t i v e In s t = DR[ Impl ! , Example ! ]

2 | | DR[ Implementation , example . ! ]

The depicted code would mean that instance AlternativeInst of design rule DR

(two parameters) would have all classes of the system whose name starts with Impl as

the first parameter and all classes of the system whose name starts with Example as the

second parameter (Line 1). Moreover, the alternative instance in Line 2 would mean

that Implementation must be the only class which name starts with Impl, while all the

classes whose name starts with Example must be inside the example package (and the

example package must have only classes with name starting by Example).

Finally, the restrictions of CrossMDA2 does not enforce that a given member (class or

method) must exist, whereas the restrictions of our design rules obligates that classes re-

sponsible for a given role must provide all the methods specified within the DR, otherwise

an error is raised.

7.2 FUTURE WORK

First, we plan to conclude the implementation of CaesarJ+ compiler, as the actual ver-

sion does not encompasses the whole language. The most important points which are not

covered by the compiler are the references to DR instances, the update of the comple-

mented roles pointcuts, the DR advice restrictions and the use of wildcards on methods

and advice, as discussed in Section 5.2.3. We also need to make more evaluations of

CaesarJ+, analyzing the implementation of new examples. Another thing to do is to

increase the tool support for developers, as the the actual compiler is a command-line

application, which displays the error messages on the console. An Eclipse [15] plugin for

CaesarJ+ could facilitate the use of the language.

We also intend to insert new constructs to CaesarJ+. We have identified the need

Page 103: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

7.2 FUTURE WORK 88

of enhanced quantification mechanisms for expressing rules, such as LSD constructs all,

exists, one and none [43]. Functionalities such as DR inheritance are also needed, in

order to enable the specification of high-level general design rules which could be then

inherited and adapted to a specific context, increasing the possibility of DRs reuse. We

also plan to extend CaesarJ+ to support behavioral rules, with constructs similar to LSD

call and xcall. These kind of rules are important because aspect developers usually

trust on some calls at a pointcut specification.

Another possible future work is the integration of CaesarJ+ with Van Landuyt et

al. [37] work, which introduces a domain-driven process for identifying abstractions that

lead to reusable pointcut signatures. In this way, we could adapt Van Landuyt approach

for generating CaesarJ+ DR instead of generating their pointcut interfaces. Finally, we

also plan to analyze how can we apply the proposed CaesarJ+ constructs into ECae-

sarJ [22], a language that extends CaesarJ and integrates it with the events and state

machine features of EAOP [14]. As ECaesarJ is yet to be released, it was not possible to

already compare and see how it could be integrated with CaesarJ+.

Page 104: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

APPENDIX A

CAESARJ+ SDF GRAMMAR

A.1 GENERAL CAESARJ+ SPECIFICATION

module CaesarJP[CaesarJCtx]

imports

languages/java/JavaMix[CaesarJCtx]

languages/java/JavaMix[AspectTheCtx]

languages/java/JavaMix[PointcutTheCtx]

languages/java/JavaMix[PatternTheCtx]

languages/aspectj/lexical/Keyword

languages/aspectj/aspect/Declaration[AspectTheCtx JavaTheCtx]

languages/aspectj/pattern/Main[PatternTheCtx]

languages/aspectj/pointcut/Declaration[PointcutTheCtx]

languages/aspectj/pointcut/Expression[PointcutTheCtx JavaTheCtx]

languages/aspectj/common/BooleanComposition[PointcutExpr[[CaesarJCtx]]]

languages/aspectj/ajf/Keyword

DrDec

exports

sorts JavaTheCtx AspectTheCtx PointcutTheCtx PatternTheCtx

context-free start-symbols CaesarJCtxCompilationUnit

context-free syntax

CompilationUnit[[CaesarJCtx]] -> CaesarJCtxCompilationUnit

Externalization? ImportDec[[CaesarJCtx]]* TypeDec[[CaesarJCtx]]+

-> CompilationUnit[[CaesarJCtx]] {cons("CompilationUnit"),prefer}

%%% CCLASS %%%

"cclass" PackageName[[CaesarJCtx]] ";" -> Externalization {cons("Externalization")}

89

Page 105: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

A.1 GENERAL CAESARJ+ SPECIFICATION 90

(Anno[[CaesarJCtx]] | ClassMod[[CaesarJCtx]])* "cclass"

Id[[CaesarJCtx]] TypeParams[[CaesarJCtx]]?

Super[[CaesarJCtx]]?

Complements[[CaesarJCtx]]?

InterfacesDr[[CaesarJCtx]]?

Wraps[[CaesarJCtx]]?

-> ClassDecHead[[CaesarJCtx]] {cons("CClassDecHead")}

%%% COMPLEMENTS %%%

"complements" {ClassType[[CaesarJCtx]] "&"}+

-> Complements[[CaesarJCtx]] {cons("Complements")}

%%%

"extends" ClassType[[CaesarJCtx]] "&" {ClassType[[CaesarJCtx]] "&"}+

-> Super[[CaesarJCtx]] {cons("SuperDec")}

"wraps" ClassType[[CaesarJCtx]]

-> Wraps[[CaesarJCtx]] {cons("Wraps")}

context-free syntax

%%% IMPLEMENTS DR %%%

"implements" {(ExtendLine1 | ExtendLine2) ","}+

-> InterfacesDr[[CaesarJCtx]] {cons("Implements")}

ClassType[[CaesarJCtx]] -> ExtendLine1 {cons("ImplementsDec")}

ClassType[[CaesarJCtx]] DrParams[[CaesarJCtx]]

-> ExtendLine2 { cons("ImplDrDec"), prefer}

%%%

context-free syntax

Mixin -> MethodMod[[CaesarJCtx]]

"mixin" -> Mixin {cons("Mixin")}

"deployed" -> ClassMod[[CaesarJCtx]] {cons("Deployed")}

Page 106: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

A.1 GENERAL CAESARJ+ SPECIFICATION 91

context-free syntax

DeployDec[[CaesarJCtx]] -> ClassMemberDec[[CaesarJCtx]]

"deploy" Expr[[CaesarJCtx]] ";"-> DeployDec[[CaesarJCtx]] {cons("DeployDec")}

context-free syntax

PointcutDec[[CaesarJCtx]] ->ClassMemberDec[[CaesarJCtx]]

%%% ASPECTJ-LIKE POINTCUTS %%%

PointcutDecHead[[CaesarJCtx]] PointcutBody[[CaesarJCtx]]

-> PointcutDec[[CaesarJCtx]] {cons("PointcutDec")}

(Anno[[CaesarJCtx]] | Modifier[[CaesarJCtx]])* "pointcut"

Id[[CaesarJCtx]] "(" {FormalParam[[CaesarJCtx]] ","}* ")"

-> PointcutDecHead[[CaesarJCtx]] {cons("PointcutDecHead")}

":" PointcutExpr[[CaesarJCtx]] ";" -> PointcutBody[[CaesarJCtx]] {cons("PointcutBody")}

%%%

context-free syntax

"call" "(" MethodConstrPattern ")" -> PointcutExpr[[CaesarJCtx]] {cons("Call")}

"execution" "(" MethodConstrPattern ")" -> PointcutExpr[[CaesarJCtx]] {cons("Exec")}

%%%NAMED POINTCUT %%%

PointcutName[[CaesarJCtx]] "(" {TypeOrIdPattern ","}* ")"

-> PointcutExpr[[CaesarJCtx]] {cons("NamedPointcut")}

sorts PointcutName

context-free syntax

Id[[CaesarJCtx]] -> PointcutName[[CaesarJCtx]] {cons("PointcutName")}

ClassOrInterfaceType[[CaesarJCtx]] "." Id[[CaesarJCtx]]

-> PointcutName[[CaesarJCtx]] {cons("PointcutName")}

%%%

Page 107: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

A.1 GENERAL CAESARJ+ SPECIFICATION 92

context-free syntax

"if" "(" Expr[[CaesarJCtx]] ")" -> PointcutExpr[[CaesarJCtx]] {cons("If")}

context-free syntax

"this" "(" TypeOrIdPattern")" -> PointcutExpr[[CaesarJCtx]] {cons("This")}

"target" "(" TypeOrIdPattern")" -> PointcutExpr[[CaesarJCtx]] {cons("Target")}

"args" "(" {TypeOrIdPattern ","}* ")" -> PointcutExpr[[CaesarJCtx]] {cons("Args")}

Type[[CaesarJCtx]] "." "cclass" -> ClassLiteral[[CaesarJCtx]] {cons("Class")}

"void" "." "cclass" -> ClassLiteral[[CaesarJCtx]] {cons("VoidClass")}

%%% ADVICE %%%

sorts AdviceDec AdviceMod

context-free syntax

AdviceDec[[CaesarJCtx]] -> ClassMemberDec[[CaesarJCtx]]

AdviceMod[[CaesarJCtx]]* AdviceSpec[[CaesarJCtx]] Throws[[CaesarJCtx]]? ":"

PointcutExpr[[CaesarJCtx]] MethodBody[[CaesarJCtx]]

-> AdviceDec[[CaesarJCtx]] {cons("AdviceDec")}

StrictFP[[CaesarJCtx]] -> AdviceMod[[CaesarJCtx]]

Anno[[CaesarJCtx]] -> AdviceMod[[CaesarJCtx]]

sorts AdviceSpec

context-free syntax

"before" "(" {FormalParam[[CaesarJCtx]] ","}* ")"

-> AdviceSpec[[CaesarJCtx]] {cons("Before")}

"after" "(" {FormalParam[[CaesarJCtx]] ","}* ")" ExitStatus?

-> AdviceSpec[[CaesarJCtx]] {cons("After")}

ResultType[[CaesarJCtx]] "around" "(" {FormalParam[[CaesarJCtx]] ","}* ")"

-> AdviceSpec[[CaesarJCtx]] {cons("Around")}

"returning" -> ExitStatus {cons("Returning")}

Page 108: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

A.1 GENERAL CAESARJ+ SPECIFICATION 93

"returning" "(" ")" -> ExitStatus {cons("Returning")}

"returning" "(" FormalParam[[CaesarJCtx]] ")" -> ExitStatus {cons("Returning")}

"throwing" -> ExitStatus {cons("Throwing")}

"throwing" "(" ")" -> ExitStatus {cons("Throwing")}

"throwing" "(" FormalParam[[CaesarJCtx]] ")" -> ExitStatus {cons("Throwing")}

%%%

lexical syntax

"cclass" -> Keyword[[CaesarJCtx]]

"deployed" -> Keyword[[CaesarJCtx]]

"wraps" -> Keyword[[CaesarJCtx]]

"complements" -> Keyword[[CaesarJCtx]]

[\ \t \r \n] -> LAYOUT

lexical syntax

"cclass" -> Keyword[[CaesarJCtx]]

"deployed" -> Keyword[[CaesarJCtx]]

"wraps" -> Keyword[[CaesarJCtx]]

"complements" -> Keyword[[CaesarJCtx]]

[\ \t \r \n] -> LAYOUT

lexical restrictions

"cclass" -- [A-Za-z0-9 $]

"uses" -- [A-Za-z0-9 $]

"requires" -- [A-Za-z0-9 $]

"deployed" -- [A-Za-z0-9 $]

"complements" -- [A-Za-z0-9 $]

Page 109: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

A.2 DESIGN RULES CONSTRUCT SDF 94

A.2 DESIGN RULES CONSTRUCT SDF

module DrDec[CaesarJCtx]

imports

languages/java/JavaMix[CaesarJCtx]

exports

sorts CaesarJCtx

context-free syntax

DrDecHead[[CaesarJCtx]] DrBody[[CaesarJCtx]]

-> DrDec[[CaesarJCtx]] { cons("DrDec") }

"{" DrMemberDec[[CaesarJCtx]]* "}" -> DrBody[[CaesarJCtx]] {cons("DrBody")}

"dr" Id[[CaesarJCtx]] DrParams[[CaesarJCtx]]

-> DrDecHead[[CaesarJCtx]] { cons("DrDecHead") }

"[" {Id[[CaesarJCtx]] ","}+ "]" -> DrParams[[CaesarJCtx]] {cons("DrParam")}

DrDec[[CaesarJCtx]] -> TypeDec[[CaesarJCtx]]

"dr" Id[[CaesarJCtx]] "=" DrReference[[CaesarJCtx]] DrParams[[CaesarJCtx]]

-> DrInstance[[CaesarJCtx]] { cons("DrInstance") }

Id[[CaesarJCtx]] -> DrReference[[CaesarJCtx]] { cons("DrReference") }

DrInstance[[CaesarJCtx]] -> TypeDec[[CaesarJCtx]]

context-free syntax

ConstantDec[[CaesarJCtx]] -> DrMemberDec[[CaesarJCtx]]

AbstractMethodDec[[CaesarJCtx]] -> DrMemberDec[[CaesarJCtx]]

ClassDec[[CaesarJCtx]] -> DrMemberDec[[CaesarJCtx]]

Page 110: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

A.2 DESIGN RULES CONSTRUCT SDF 95

";" -> DrMemberDec[[CaesarJCtx]] {cons("Semicolon")}

lexical syntax

"dr" -> Keyword[[CaesarJCtx]]

lexical restrictions

"dr" -- [A-Za-z0-9 $]

Page 111: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

BIBLIOGRAPHY

[1] abc: The AspectBench Compiler for AspectJ. http://aspectbench.org/.

[2] Ajdt. Getting started with ajdt. http://www.eclipse.org/ajdt/gettingstarted.php,

September, 2009.

[3] Jonathan Aldrich. Open modules: Modular reasoning about advice. In Proceed-

ings ECOOP 2005, volume 3586 of LNCS, pages 144–168, Glasgow, UK, July 2005.

Springer Verlag.

[4] Ivica Aracic, Vaidas Gasiunas, Mira Mezini, and Klaus Ostermann. An overview

of CaesarJ. Transactions on Aspect-Oriented Software Development, 3880:135–173,

2006.

[5] Aspectj.org. Aspectj. http://www.eclipse.org/aspectj/, October, 2009.

[6] Carliss Y. Baldwin and Kim B. Clark. Design Rules, Volume 1: The Power of

Modularity. MIT Press, Cambridge, MA, USA, 1999.

[7] Rodrigo Bonifacio and Paulo Borba. Modeling scenario variability as crosscutting

mechanisms. In AOSD ’09: Proceedings of the 8th ACM international conference on

Aspect-oriented software development, pages 125–136, New York, NY, USA, 2009.

ACM.

[8] Martin Bravenboer, Karl Trygve Kalleberg, Rob Vermaas, and Eelco Visser. Strat-

ego/XT 0.17. A language and toolset for program transformation. Science of Com-

puter Programming, 2008. Special issue on Experimental Systems and Tools.

[9] Martin Bravenboer, Karl Trygve Kalleberg, and Eelco Visser. Stratego/xt manual.

http://hydra.nixos.org/build/428755/download/1/manual/, December, 2009.

[10] Caesarj.org. Caesarj. http://www.caesarj.org, March, 2010.

96

Page 112: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

BIBLIOGRAPHY 97

[11] Cristina Chavez, Alessandro Garcia, Uira Kulesza, Claudio Sant’Anna, and Car-

los Lucena. Crosscutting interfaces for aspect-oriented modeling. Journal of the

Brazilian Computer Society, 12(1):43–58, 2006.

[12] Curtis Clifton and Gary T. Leavens. Observers and assistants: A proposal for mod-

ular aspect-oriented reasoning. In Gary T. Leavens and Ron Cytron, editors, FOAL

2002 Proceedings: Foundations of Aspect-Oriented Languages Workshop at AOSD

2002, number 02-06 in Technical Reports, pages 33–44. Department of Computer

Science, Iowa State University, April 2002.

[13] Alberto Costa Neto, Marcio de Medeiros Ribeiro, Marcos Dosea, Rodrigo Bonifacio,

Paulo Borba, and Sergio Soares. Semantic dependencies and modularity of aspect-

oriented software. In ACoM ’07: Proceedings of the First International Workshop

on Assessment of Contemporary Modularization Techniques, page 11, Washington,

DC, USA, 2007. IEEE Computer Society.

[14] Remi Douence and Mario Sudholt. A model and a tool for event-based aspect-

oriented programming (EAOP). Technical report, Ecole des Mines de Nantes, De-

cember 2002.

[15] Eclipse.org. Eclipse. http://www.eclipse.org/, November, 2009.

[16] Ulrich W. Eisenecker and Krzysztof Czarnecki. Generative Programming: Methods,

Tools, and Applications. Addison-Wesley, 2000.

[17] Erik Ernst. Propagating class and method combination. In ECOOP ’99: Proceedings

of the 13th European Conference on Object-Oriented Programming, pages 67–91,

London, UK, 1999. Springer-Verlag.

[18] Matthias Felleisen. On the expressive power of programming languages. In Science

of Computer Programming, pages 134–151. Springer-Verlag, 1990.

[19] Victor Fernandes, Flavia Delicato, Paulo Pires, Uira Kulesza, and Thais Vascon-

celos Batista. Crossmda2: Uma abordagem baseada em modelos para gerencia de

evolucao de pointcuts. In SBCARS’09: Proceedings of 2nd Brazilian Symposium on

Components, Architecture and Software Reuse, oct 2009.

[20] Robert E. Filman and Daniel P. Friedman. Aspect-oriented programming is quan-

tification and obliviousness. In Aspect-Oriented Software Development, pages 21–35.

Addison-Wesley, 2005.

Page 113: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

BIBLIOGRAPHY 98

[21] Erich Gamma., Richard Helm., Ralph Johnson Johnson, and John Vlissides. Design

patterns. Addison-Wesley Reading, MA, 1995.

[22] Vaidas Gasiunas, Mira Mezini, Jacques Noye, Angel Nunez, Nicolas Anquetil,

Ludger Fiege, Iris Groher, Christine Schwanninger, Markus Volter, Pablo Sanchez,

and Lidia Fuentes. Ample deliverable D3.3: Implementation platform and doc-

umentation for using it. Technical report, Ample project, November, 2009.

http://www.ample-project.net/.

[23] Phil Greenwood, Thiago T. Bartolomei, Eduardo Figueiredo, Marcos Dosea, Alessan-

dro F. Garcia, Nelio Cacho, Claudio Sant’Anna, Sergio Soares, Paulo Borba, Uira

Kulesza, and Awais Rashid. On the impact of aspectual decompositions on design

stability: An empirical study. In Erik Ernst, editor, ECOOP 2007 - Object-Oriented

Programming, 21st European Conference, Berlin, Germany, July 30 - August 3,

2007, Proceedings, volume 4609 of Lecture Notes in Computer Science, pages 176–

200. Springer, 2007.

[24] William G. Griswold, Kevin Sullivan, Yuanyuan Song, Macneil Shonle, Nishit

Tewari, Yuanfang Cai, and Hridesh Rajan. Modular software design with cross-

cutting interfaces. IEEE Software, 23(1):51–60, 2006.

[25] Jan Hannemann and Gregor Kiczales. Design pattern implementation in Java and

AspectJ. In Cindy Norris and Jr. James B. Fenwick, editors, Proceedings of the 17th

ACM conference on Object-oriented programming, systems, languages, and applica-

tions (OOPSLA-02), volume 37, 11 of ACM SIGPLAN Notices, pages 161–173, New

York, November 4–8 2002. ACM Press.

[26] Gorel Hedin. Generating language tools with jastadd. In 3rd Summer School on Gen-

erative and Transformational Techniques in Software Engineering (GTTSE), Braga,

Portugal, 2009.

[27] Jastadd.org. Jastadd. http://jastadd.org/, March, 2010.

[28] Java. Java o!cial website. http://java.sun.com/, March, 2009.

[29] A. Kellens, K. Gybels, J. Brichau, and K. Mens. A model-driven pointcut lan-

guage for more robust pointcuts. Proceedings of Software engineering Properties of

Languages for Aspect Technologies (SPLAT?06), Bonn, Germany, 2006.

Page 114: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

BIBLIOGRAPHY 99

[30] A. Kellens, K. Mens, J. Brichau, and K. Gybels. Managing the evolution of aspect-

oriented software with model-based pointcuts. ECOOP 2006–Object-Oriented Pro-

gramming, pages 501–525, 2006.

[31] Jordan Kiang. Tetris midlet. http://kiang.org/jordan/software/tetrismidlet/.

[32] Gregor Kiczales, Erik Hilsdale, Jim Hugunin, Mik Kersten, Je"rey Palm, and

William Griswold. Getting started with AspectJ. Communications of the ACM,

44(10):59–65, October 2001.

[33] Gregor Kiczales, Erik Hilsdale, Jim Hugunin, Mik Kersten, Je"rey Palm, and

William G. Griswold. An overview of AspectJ. In J. Lindskov Knudsen, editor,

ECOOP 2001 — Object-Oriented Programming 15th European Conference, volume

2072 of Lecture Notes in Computer Science, pages 327–353. Springer-Verlag, Bu-

dapest, Hungary, June 2001.

[34] Gregor Kiczales, John Lamping, Anurag Menhdhekar, Chris Maeda, Cristina Lopes,

Jean-Marc Loingtier, and John Irwin. Aspect-oriented programming. In Mehmet

Aksit and Satoshi Matsuoka, editors, ECOOP ’97—Object-Oriented Programming

11th European Conference, Jyvaskyla, Finland, Proceedings, volume 1241 of Lecture

Notes in Computer Science, pages 220–242, New York, NY, June 1997. Springer-

Verlag.

[35] Gregor Kiczales and Mira Mezini. Aspect-oriented programming and modular rea-

soning. In Gruia-Catalin Roman, William G. Griswold, and Bashar Nuseibeh, ed-

itors, 27th International Conference on Software Engineering (ICSE 2005), 15-21

May 2005, St. Louis, Missouri, USA, pages 49–58. ACM, 2005.

[36] Christian Koppen and Maximilian Storzer. PCDi": Attacking the fragile pointcut

problem. In Kris Gybels, Stefan Hanenberg, Stephan Herrmann, and Jan Wloka,

editors, European Interactive Workshop on Aspects in Software (EIWAS), September

2004.

[37] Dimitri Van Landuyt, Steven Op de beeck, Eddy Truyen, and Wouter Joosen.

Domain-driven discovery of stable abstractions for pointcut interfaces. In Kevin J.

Sullivan, Ana Moreira, Christa Schwanninger, and Je" Gray, editors, Proceedings of

the 8th International Conference on Aspect-Oriented Software Development, AOSD

2009, Charlottesville, Virginia, USA, March 2-6, 2009, pages 75–86. ACM, 2009.

Page 115: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

BIBLIOGRAPHY 100

[38] Cristina Videira Lopes and Sushil Krishna Bajracharya. Assessing aspect modular-

izations using design structure matrix and net option value. LNCS Transactions on

Aspect-Oriented Software Development I, 3880:1–35, 2006.

[39] Ole Lehrmann Madsen and Birger Moller-Pedersen. Virtual classes: a powerful mech-

anism in object-oriented programming. In OOPSLA ’89: Conference proceedings on

Object-oriented programming systems, languages and applications, pages 397–406,

New York, NY, USA, 1989. ACM.

[40] Bertrand Meyer. Object-Oriented Software Construction. Prentice Hall PTR, 2nd

edition, March 2000.

[41] Mira Mezini and Klaus Ostermann. Integrating independent components with on-

demand remodularization. In Proceedings of the 17th ACM SIGPLAN conference

on object-oriented programming, systems, languages, and applications, pages 52–67,

Seattle, Washington, USA, 2002. ACM.

[42] Mira Mezini and Klaus Ostermann. Conquering aspects with caesar. In Proceedings

of the 2nd international conference on Aspect-oriented software development, pages

90–99, Boston, Massachusetts, 2003. ACM.

[43] Alberto Costa Neto. Specifying Design Rules in Aspect-Oriented Systems. PhD

thesis, Informatics Center, University of Pernambuco, March 2010.

[44] Alberto Costa Neto, Arthur Marques, Rohit Gheyi, Paulo Borba, and Fernando Cas-

tor Filho. A design rule language for aspect-oriented programming. In XIII Brazilian

Symposium on Programming Languages - SBLP’09, Gramado-RS, Brazil, August

2009. To appear.

[45] Neil Ongkingco, Pavel Avgustinov, Julian Tibble, Laurie Hendren, Oege de Moor,

and Ganesh Sittampalam. Adding open modules to AspectJ. In Proceedings of the

5th International Conference on Aspect-Oriented Software Development (AOSD),

pages 39–50, March 2006.

[46] David Parnas. On the criteria to be used in decomposing systems into modules.

Communications of the Association for Computing Machinery, 15:1053–1058, 1972.

[47] Klaus Pohl, Gunter Bockle, and Frank van der Linden. Software Product Line Engi-

neering: Foundations, Principles and Techniques. Springer, Berlin Heidelberg New

York, 2005.

Page 116: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

BIBLIOGRAPHY 101

[48] Carlos Eduardo Pontual. Caesarj+ source code.

http://cin.ufpe.br/~ceplc/caesarjp, April, 2010.

[49] Carlos Eduardo Pontual, Rodrigo Bonifacio, Henrique Rebelo, Marcio Ribeiro,

and Paulo Borba. Modularizing variabilities with CaesarJ collaboration inter-

faces. In 3rd Workshop on Assessment of Contemporary Modularization Techniques

(ACoM’09) at ACM SIGPLAN International Conference on Object-Oriented Pro-

gramming (OOPSLA’09), Orlando, USA, October 2009.

[50] Hridesh Rajan and Kevin J. Sullivan. Classpects: unifying aspect- and object-

oriented language design. In Gruia-Catalin Roman, William G. Griswold, and Bashar

Nuseibeh, editors, 27th International Conference on Software Engineering (ICSE

2005), 15-21 May 2005, St. Louis, Missouri, USA, pages 59–68. ACM, 2005.

[51] Marcio Ribeiro, Marcos Dosea, Rodrigo Bonifacio, Alberto Costa Neto, Paulo Borba,

and Sergio Soares. Analyzing class and crosscutting modularity with design structure

matrixes. In SBES ’07: Proceedings of 21 th Brazilian Symposium on Software

Engineering, pages 167–181, oct 2007.

[52] Leonardo Humberto Guimaraes Silva. Definicao de conjuntos de juncoes robustos

usando aspect-aware interfaces e aspectos anotadores. Master’s thesis, PUC/Minas,

June 2008.

[53] Sergio Soares, Eduardo Laureano, and Paulo Borba. Implementing distribution and

persistence aspects with aspectj. In OOPSLA ’02: Proceedings of the 17th ACM

SIGPLAN conference on Object-oriented programming, systems, languages, and ap-

plications, pages 174–190, New York, NY, USA, 2002. ACM.

[54] Friedrich Steimann. The paradoxical success of aspect-oriented programming. SIG-

PLAN Not., 41(10):481–497, 2006.

[55] Strategoxt.org. Stratego/xt. http://strategoxt.org/, February, 2010.

[56] Kevin Sullivan, William G. Griswold, Hridesh Rajan, Yuanyuan Song, Yuanfang

Cai, Macneil Shonle, and Nishit Tewari. Modular Aspect-Oriented design with XPIs.

ACM Transactions on Software Engineering and Methodology (TOSEM), 2009.

[57] Kevin Sullivan, William G. Griswold, Yuanyuan Song, Yuanfang Cai, Macneil

Shonle, Nishit Tewari, and Hridesh Rajan. Information hiding interfaces for aspect-

oriented design. In ESEC/FSE’05, pages 166–175, New York, NY, USA, 2005. ACM.

Page 117: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro

BIBLIOGRAPHY 102

[58] F. Van Der Linden, K. Schmid, and E. Rommes. Software product lines in action:

the best industrial practice in product line engineering. Springer-Verlag New York

Inc, 2007.

[59] Eelco Visser. A family of syntax definition formalisms. In M. G. J. van den

Brand et al., editors, ASF+SDF 1995. A Workshop on Generating Tools from Alge-

braic Specifications, pages 89–126. Technical Report P9504, Programming Research

Group, University of Amsterdam, May 1995.

Page 118: DESIGN RULES FOR INCREASING MODULARITY WITH CAESARJ · 2019. 10. 25. · Universidade Federal de Pernambuco - UFPE Centro de Inform´atica - CIn Carlos Eduardo Pontual de Lemos Castro