• Nenhum resultado encontrado

UMA ABORDAGEM PARA CRIAR REFATORAÇÕES PARA O KDM

4.3 Exemplo de uso da abordagem de criação das refato rações

4.3.1 Criar Refatoração Push Down Attribute

Nesta seção, a refatoração Push Down Attribute é criada seguindo os passos descritos neste capítulo. Essa refatoração é utilizada para remover a generalização de atributos, ou seja, um atributo é apenas utilizado em algumas subclasses, assim, não é interessante manter o atributo na superclasse, uma vez que cada subclasse pode definir um comportamento para o atributo (FOWLER, 1999).

4.3.1.1 Identificar Elementos Estruturais

O primeiro passo da abordagem consiste na identificação do elemento estrutural a ser refatorado. Pelo nome da refatoração é possível identificar que o elemento estrutural a ser refatorado é um atributo (do inglês - attribute). Dessa forma, utilizando o artefato de mapeamento entre KDM e POO (ver Tabela 3) é possível identificar que um atributo em KDM é representado

pela metaclasseStorableUnit.

4.3.1.2 Identificar Operações

No segundo passo da abordagem, o engenheiro de modernização deve identificar as ope- rações atômicas que compõem a refatoração a ser criada. Na Figura 27, duas instâncias simplifica- das do KDM são ilustradas, a parte superior ilustra a instância antes da realização da refatoração Push Down Attribute e a parte inferior representa o resultado da refatoração. Como observado, o primeiro passo da refatoração Push Down Attribute é selecionar um específicoStorableUnit (ver Figura 27  ). Em seguida, deve-se selecionar as subclasses que realmente utilizam esse StorableUnit para move-lo (ver Figura 27 À). Posteriormente, o {StorableUnitSelecionado} é movido para as sub-ClassUnitSelecionadas, como ilustrado na parte inferior da Figura 27 Õ. É visto que a instância daClassUnit em que havia o {StorableUnitSelecionado} não possui mais sua instância (ver Figura 27 Ã). Observando a Figura 27 é possível concluir que a refato- ração Push Down Attribute pode ser criada por meio da combinação das seguintes operações atômicas: (i)add e (ii) delete.

Figura 27 – Instância simplificada do KDM antes e depois da refatoração Push Down Attribute.

name = model : Package isAbstract = false name = ClassA : ClassUnit name = name Type = String : StorableUnit isAbstract = false name = ClassB : ClassUnit isAbstract = false name = ClassC : ClassUnit to = ClassA [ClassUnit] from = ClassB [ClassUnit]

: Extends

to = ClassA [ClassUnit] from = ClassC [ClassUnit]

: Extends name = model : Package isAbstract = false name = ClassA : ClassUnit isAbstract = false name = ClassB : ClassUnit isAbstract = false name = ClassC : ClassUnit to = ClassA [ClassUnit] from = ClassB [ClassUnit]

: Extends

to = ClassA [ClassUnit] from = ClassC [ClassUnit]

: Extends Antes Depois 1 2 2 name = name Type = String : StorableUnit name = name Type = String : StorableUnit 4 4 3

4.3.1.3 Implementar Operações

Após identificar as operações que compõem a refatoração a ser criada, o próximo passo consiste na implementação das operações. O terceiro passo da abordagem é apoiado por um conjunto de templates que auxilia o engenheiro de modernização a implementar as operações. As operações atômicas identificadas para implementar a refatoração Push Down Attribute foram implementadas em ATL utilizando os templates apresentados nos Códigos-fontes 4 e 6. A combinação desses templates resulta nos Códigos-fontes 20 e 21.

Código-fonte 20: ATL representando a operação atômica add.

1 r u l e c r e a t e S t o r a b l e U n i t {

2 from

3 s o u r c e : MM! C l a s s U n i t ( s o u r c e . name = “{sub-ClassUnitSelecionada}”

4 to

5 t a r g e t : MM! C l a s s U n i t (

6 codeElement s o u r c e . codeElement! i n c l u d i n g ( newElement )

7 ) ,

8 newElement : MM! S t o r a b l e U n i t (

9 name {StorableUnitSelecionado.name}

10 )

11 }

Código-fonte 21: ATL representando a operação atômica delete.

1 r u l e d e l e t e S t o r a b l e U n i t {

2 from

3 s o u r c e : MM! S t o r a b l e U n i t ( s o u r c e . name = {StorableUnitSelecionado.name} and s o u r c e . r e f I m m e d i a t e C o m p o s i t e ( ) . name = {ClassUnit.name} )

4 to

5 drop

6 }

4.3.1.4 Agrupar Operações

Após implementar as operações atômicas seguindo os templates apresentados neste capítulo, o próximo passo consiste em agrupar tais operações. Dessa forma, um template para guiar o agrupamento das operações atômicas também foi definido neste capítulo (ver Código- fonte 10). O agrupamento das operações atômicas apresentadas nos Códigos-fontes 20 e 21 resulta na refatoração apresentada no Código-fonte 22.

Código-fonte 22: ATL da refatoração Push Down Attribute.

2 c r e a t e OUT : MM r e f i n i n g IN : MM; 3 r u l e c r e a t e S t o r a b l e U n i t { 4 from 5 s o u r c e : MM! C l a s s U n i t ( s o u r c e . name = “{sub-ClassUnitSelecionada}” 6 to 7 t a r g e t : MM! C l a s s U n i t (

8 codeElement s o u r c e . codeElement! i n c l u d i n g ( newElement )

9 ) , 10 newElement : MM! S t o r a b l e U n i t ( 11 name {StorableUnitSelecionado.name} 12 ) 13 } 14 r u l e d e l e t e S t o r a b l e U n i t { 15 from

16 s o u r c e : MM! S t o r a b l e U n i t ( s o u r c e . name = {StorableUnitSelecionado.name} and s o u r c e . r e f I m m e d i a t e C o m p o s i t e ( ) . name = {ClassUnit.name} )

17 to

18 drop

19 }

4.3.1.5 Definir Restrições

Após identificar as operações que compõem a refatoração e implementar a refatoração utilizando os templates definidos na abordagem, o próximo passo consiste na definição de asserções (pré- e pós-condições) da refatoração. Para cada operação atômica identificada no segundo passo da abordagem, templates são disponibilizados para auxiliar o engenheiro de modernização a criar tais asserções. No Código-fonte 23, é apresentada a pré-condição criada para a refatoração Push Down Attribute, a qual foi criada usando uma combinação dos templates apresentados nos Códigos-fontes 11 e 14.

Código-fonte 23: Pré-condição da refatoração Push Down Attribute.

1 c o n t e x t S t o r a b l e U n i t : : preCond ( newName : S t r i n g )

2 pre : C l a s s U n i t . a l l I n s t a n c e s > s e l e c t ( e : C l a s s U n i t | a . name = “{sub- ClassUnitSelecionada}” and not S t o r a b l e U n i t . refImmediateComposite ( ) . codeElement! e x i s t ( e : S t o r a b l e U n i t | e . name = newName )

3 and C l a s s U n i t . a l l I n s t a n c e s > s e l e c t ( e : C l a s s U n i t | a . name =

{ClassUnit.name}) and S t o r a b l e U n i t . refImmediateComposite ( ) . codeElement ! e x i s t ( e : S t o r a b l e U n i t | e . name = newName )

Similarmente, no Código-fonte 24, é apresentada a pós-condição criada para a refatoração Push Down Attribute.

1 c o n t e x t S t o r a b l e U n i t : : preCond ( newName : S t r i n g )

2 post : C l a s s U n i t . a l l I n s t a n c e s > s e l e c t ( e : C l a s s U n i t | a . name = “{sub- ClassUnitSelecionada}” and S t o r a b l e U n i t . refImmediateComposite ( ) .

codeElement! e x i s t ( e : S t o r a b l e U n i t | e . name = newName ) 3 and C l a s s U n i t . a l l I n s t a n c e s > s e l e c t ( e : C l a s s U n i t | a . name =

{ClassUnit.name} ) and not S t o r a b l e U n i t . refImmediateComposite ( ) . codeElement! e x i s t ( e : S t o r a b l e U n i t | e . name = newName )

4.3.1.6 Documentar Refatoração

Para os exemplos apresentados neste capítulo, escolheu-se especificar as refatorações criadas seguindo o template apresentado na Seção 4.2.6.

1. Especificação Informal:

a) Nome: Push Down Attribute; b) Definição:

• StorableUnitSelecionado - um atributo que será movido para subclasses; • ClassUnit - uma classe na qual o {StorableUnitSelecionado} é definido; • sub-ClassUnitSelecionadas - subclasses de {ClassUnit}.

c) Objetivo: Mover um {StorableUnitSelecionado} para as {sub-ClassUnitSelecionadas}. d) Descrição (opcional): {StorableUnitSelecionado} é utilizada em apenas algumas

subclasses. e) Pré-condição:

• {StorableUnitSelecionado} não existe nas sub-ClassUnitSelecionadas; • {StorableUnitSelecionado} existe na ClassUnit.

f) Pós-condição:

• {StorableUnitSelecionado} existe nas sub-ClassUnitSelecionadas; • {StorableUnitSelecionado} não existe na ClassUnit.

g) Mecanismo: move um atributo de uma classe para todas suas subclasses; h) Algoritmo:

• para cada sub-ClassUnitSelecionadas que realmente usa o {StorableUnitSelecionado} - sub-ClassUnitSelecionadas.add({StorableUnitSelecionado})

• {ClassUnit}.delete({StorableUnitSelecionado}). 2. Especificação Formal:

a) Pré-condição: a pré-condição da refatoração Push Down Attribute é apresentada no Código-fonte 23;

b) Algoritmo: a ATL responsável por realizar a refatoração Push Down Attribute é apresentada no Código-fonte 22

c) Pós-condição: a pós-condição da refatoração Push Down Attribute é apresentada no Código-fonte 24;

4.3.2 Criar Refatoração Extract Class

A refatoração Extract Class deve ser utilizada quando uma determinada classe está fazendo o trabalho que deveria ser realizado por duas classes (FOWLER, 1999). Dessa forma, nesta seção, a refatoração Extract Class é criada seguindo todos os passos da abordagem.

4.3.2.1 Identificar Elementos Estruturais

A refatoração Extract Class basicamente consiste na criação de uma nova classe, e em sequência deve-se mover todos os atributos relevantes de uma classe para essa nova classe. Dessa forma, as construções da linguagem OO utilizadas na refatoração são: (i) classes e (ii) atributos. Utilizando o artefato apresentado na Tabela 3, é possível identificar que as metaclasses em KDM

que representam essas construções em OO sãoClassUnit e StorableUnit, respectivamente.

4.3.2.2 Identificar Operações

No segundo passo da abordagem deve-se identificar as operações atômicas que compõem a refatoração a ser criada. Na Figura 28, são apresentadas duas instâncias simplificada do KDM, uma representa a instância antes da refatoração e a outra representa a instância após a aplicação da refatoração.

Figura 28 – Instância simplificada do KDM antes e depois da refatoração Extract Class.

name = model : Package isAbstract = false name = ClassA : ClassUnit name = att1 Type = String : StorableUnit name = model : Package isAbstract = false name = ClassA : ClassUnit isAbstract = false name = ClassB : ClassUnit Antes Depois 1 name = att1 Type = String : StorableUnit name = att2 Type = String : StorableUnit 1 name = att2 Type = String : StorableUnit 2 3 3 name = att3 Type = String : StorableUnit name = att3 Type = String : StorableUnit

Fonte: Elaborada pelo autor.

O primeiro passo da refatoração Extract ClassUnit é selecionar um conjunto deStorableUnits que será adicionado em uma nova instância de metaclasseClassUnit, no exemplo ilustrado na Figura 28  , duas instâncias deStorableUnits são selecionadas, att1 e att2. Em seguida, uma instância da metaclasseClassUnit é criada e adicionada ao mesmo Package que a instân-

na Figura 28 Ã. Em seguida, todos {StorableUnitSelecionados} são adicionados nessa nova instância, como representado na Figura 28 À. Além disso, os {StorableUnitSelecionados} devem ser deletados da {ClassUnitSelecionada}. Observando a Figura 28 é possível identi- ficar que é a refatoração Extract Class pode ser criada por meio da combinação das seguintes operações atômicas: (i)add e (ii) delete.

4.3.2.3 Implementar Operações

No passo anterior identificou-se que as operações atômicasadd e delete quando combi- nadas podem compor e criar a refatoração Extract Class. Dessa forma, essas operações atômicas foram implementadas em ATL utilizando os templates apresentados nos Códigos-fontes 4 e 6. A combinação desses templates resultou nos Códigos-fontes 25, 26 e 27.

Código-fonte 25: ATL representando a operação atômica add ClassUnit da refatoração Extract ClassUnit.

1 r u l e c r e a t e C l a s s U n i t {

2 from

3 s o u r c e : MM! Package ( s o u r c e . name = “{Package}”)

4 to

5 t a r g e t : MM! Package (

6 codeElement s o u r c e . codeElement! i n c l u d i n g ( newElement )

7 ) ,

8 newElement : MM! C l a s s U n i t (

9 name “{newName}”

10 )

11 }

Código-fonte 26: ATL representando a operação atômica add StorableUnit da refatoração Extract ClassUnit. 1 r u l e c r e a t e S t o r a b l e U n i t { 2 from 3 s o u r c e : MM! C l a s s U n i t ( s o u r c e . name = “{newName}” ) 4 to 5 t a r g e t : MM! C l a s s U n i t (

6 codeElement s o u r c e . codeElement! i n c l u d i n g ( newElement )

7 ) ,

8 newElement : MM! S t o r a b l e U n i t (

9 name “storableUnitName”

10 )

Código-fonte 27: ATL representando a operação atômica delete StorableUnit da refatora- ção Extract ClassUnit.

1 r u l e d e l e t e S t o r a b l e U n i t {

2 from

3 s o u r c e : MM! S t o r a b l e U n i t ( s o u r c e . name = “{StorableUnit}Selecionado” and s o u r c e . r e f I m m e d i a t e C o m p o s i t e ( ) . name = “{ClassUnit}Selecionado” )

4 to

5 drop

6 }

4.3.2.4 Agrupar Operações

Após implementar as operações atômicas seguindo os templates apresentados neste capítulo, o próximo passo consiste em agrupar tais operações. Dessa forma, um template para guiar o agrupamento das operações atômicas também foi definido neste capítulo (ver Código- fonte 10). O agrupamento das operações atômicas apresentadas nos Códigos-fontes 25, 26 e 27 resulta na refatoração apresentada no Código-fonte 28.

Código-fonte 28: ATL da refatoração Extract ClassUnit.

1 module e x t r a c t C l a s s U n i t ;

2 c r e a t e OUT : MM r e f i n i n g IN : MM; 3 r u l e c r e a t e C l a s s U n i t {

4 from

5 s o u r c e : MM! Package ( s o u r c e . name = “{Package}” )

6 to

7 t a r g e t : MM! Package (

8 codeElement s o u r c e . codeElement! i n c l u d i n g ( newElement )

9 ) , 10 newElement : MM! C l a s s U n i t ( 11 name “{newName}” 12 ) 13 } 14 r u l e c r e a t e S t o r a b l e U n i t { 15 from 16 s o u r c e : MM! C l a s s U n i t ( s o u r c e . name = “{newName}” ) 17 to 18 t a r g e t : MM! C l a s s U n i t (

19 codeElement s o u r c e . codeElement! i n c l u d i n g ( newElement )

20 ) , 21 newElement : MM! S t o r a b l e U n i t ( 22 name “storableUnitName” 23 ) 24 } 25 r u l e d e l e t e S t o r a b l e U n i t {

26 from

27 s o u r c e : MM! S t o r a b l e U n i t ( s o u r c e . name = “{StorableUnit}Selecionado” and s o u r c e . r e f I m m e d i a t e C o m p o s i t e ( ) . name = “{ClassUnit}Selecionado” )

28 to

29 drop

30 }}

4.3.2.5 Definir Restrições

Após identificar as operações e implementar a refatoração, o próximo passo consiste na definição das pré- e pós-condições da refatoração. Os templates apresentados neste capítulo foram utilizados para criar as asserções da refatoração Extract Class. O Código-fonte 29 apresenta a pré-condição criada para a refatoração. Essa pré-condição foi criada utilizando os templates apresentados nos Códigos-fontes 11 e 14. Similarmente, o Código-fonte 30 apresenta a pós- condição criada para a refatoração Extract ClassUnit.

Código-fonte 29: Pré-condição da refatoração Extract Class.

1 c o n t e x t S t o r a b l e U n i t : : preCond ( newName : S t r i n g )

2 pre : C l a s s U n i t . a l l I n s t a n c e s > s e l e c t ( e : C l a s s U n i t | a . name = {ClassUnitSelecionada}) and S t o r a b l e U n i t . refImmediateComposite ( ) .

codeElement! e x i s t ( e : S t o r a b l e U n i t | e . name = {StorableUnitSelecionado} ) 3 and Package . a l l I n s t a n c e s > s e l e c t ( e : Package | a . name = “{Package}” and not

C l a s s U n i t . r e f I m m e d i a t e C o m p o s i t e ( ) . codeElement! e x i s t ( e : C l a s s U n i t | e . name = newName )

4 and C l a s s U n i t . a l l I n s t a n c e s > s e l e c t ( e : C l a s s U n i t | a . name = newName and not S t o r a b l e U n i t . r e f I m m ed i a t e C o mp o s i t e ( ) . codeElement! e x i s t ( e : S t o r a b l e U n i t | e . name = {StorableUnitSelecionado} . name )

Código-fonte 30: Pós-condição da refatoração Extract ClassUnit.

1 c o n t e x t S t o r a b l e U n i t : : preCond ( newName : S t r i n g )

2 post : C l a s s U n i t . a l l I n s t a n c e s > s e l e c t ( e : C l a s s U n i t | a . name = {ClassUnitSelecionada}) and not S t o r a b l e U n i t . refImmediateComposite ( ) .

codeElement! e x i s t ( e : S t o r a b l e U n i t | e . name = {StorableUnitSelecionado} . name )

3 and Package . a l l I n s t a n c e s > s e l e c t ( e : Package | a . name = “{Package}” and C l a s s U n i t . r e f I m m e d i a t e C o m p o s i t e ( ) . codeElement! e x i s t ( e : C l a s s U n i t |

e . name = newName )

4 and C l a s s U n i t . a l l I n s t a n c e s > s e l e c t ( e : C l a s s U n i t | a . name = newName and S t o r a b l e U n i t . r e f I m m e d i a t e C o m p o s i t e ( ) . codeElement! e x i s t ( e :

4.3.2.6 Documentar Refatoração

O último passo da abordagem é a especificação da refatoração criada. Esse passo é opcional e fica a critério do engenheiro de modernização realizar esse passo. Para a refatoração Extract ClassUnit escolheu-se especificar a refatoração seguindo o template apresentado na Seção 4.2.6.

1. Especificação Informal:

a) Nome: Extract ClassUnit; b) Definição:

• Package - uma instância da metaclasse Package para adicionar a nova ClassUnit; • ClassUnitSelecionada - a classe que contém os atributos e métodos que devem

ser movido para a nova classe;

• novoNome - um novo nome para a nova classe a ser criada;

• StorableUnitSelecionado - atributo selecionado para ser movido para a nova classe.

c) Objetivo: Criar uma novaClassUnit e mover o StorableUnitSelecionado para

essa nova instância.

d) Descrição (opcional):ClassUnitSelecionada está realizando o trabalho que deveria ser realizado por duas classes.

e) Pré-condição:

• {StorableUnitSelecionado} existe na {ClassUnitSelecionada}; • nova ClassUnit não existe no Package;

• {StorableUnitSelecionado} não existe na nova ClassUnit. f) Pós-condição:

• {StorableUnitSelecionado} não existe na {ClassUnitSelecionada}; • nova ClassUnit existe no Package;

• {StorableUnitSelecionado} existe na nova ClassUnit.

g) Mecanismo: Deve-se criar uma nova classe e mover os atributos selecionados; h) Algoritmo:

• addNewClassUnit({novoNome});

• adiciona essa nova instância dentro de um Package;

• para cada {StorableUnitSelecionado} - add({newClassUnit}, {StorableUnit- Selecionado});

• para cada {StorableUnitSelecionado} - delete({ClassUnitSelecionada}, {Storable- UnitSelecionado});

2. Especificação Formal:

a) Pré-condição: a pré-condição da refatoração Extract Class é apresentada no Código- fonte 29;

b) Algoritmo: a ATL responsável por realizar a refatoração Extract Class é apresentada no Código-fonte 28;

c) Pós-condição: a pós-condição da refatoração Extract Class é apresentada no Código- fonte 30;