• Nenhum resultado encontrado

(Theme3) <<theme>> Theme1 AClass + aRoutine( ): void <<theme>> Theme2 AClass + aRoutine( ): void

(a) Diagrama de temas.

<<theme>> Theme3

AClass

+ aRoutine( ): void

public void aRoutine( ){

... // implementation from Theme1 ... // implementation from Theme2 }

(b) Diagrama de classes do tema resultante.

Figura 3.13: Exemplo de composição no qual uma rotina completa possui correspondência no outro tema.

3.3.7 Classes correspondentes, uma classe herda de C1 enquanto

a outra classe herda de C2 que é subclasse de C1

Um desenvolvedor tipicamente implementa um tema ignorando temporariamente outros temas relacionados, para que o módulo atinja inconsciência (obliviousness) (Filman e Friedman, 2000). Em alguns casos, uma classe de um tema herda de uma determinada classe C1 que é suficiente para seus propósitos. Em outro tema, a mesma classe herda de uma subclasse C2 da antiga superclasse C1 porque precisa de algumas características que a subclasse C2 fornece mas que a superclasse C2 não fornece. Quando os dois temas são compostos, é razoável assumir que o desenvolvedor deseje que a classe implementada herde da superclasse mais específica (C2). Assim, se uma classe de um tema corresponder a uma classe de outro tema, e uma das classes herdar de uma classe C1 enquanto a outra classe herda de uma classe C2 que, por sua vez, é subclasse de C1, a classe resultante herda de C2. A semântica de composição para este cenário é demonstrada na Figura 3.16.

+ (Theme3)

<<theme>> Theme1

AClass

+ {abstract} aRoutine( ): void

<<theme>> Theme2

AClass

+ aRoutine( ): void

(a) Diagrama de temas.

<<theme>> Theme3

AClass

+ aRoutine( ): void

public void aRoutine( ){

... // implementation from Theme2 }

(b) Diagrama de classes do tema resultante.

Figura 3.14: Exemplo de composição no qual uma rotina abstrata possui correspondência no outro tema.

3.4 Semântica da Redefinição de Elementos Internos a

Temas

Em alguns casos, antes de efetuar uma composição entre dois temas deseja-se tornar corres-pondentes alguns elementos que não são correscorres-pondentes por default conforme a semântica de composição. Os conflitos de correspondência mais comuns são elementos (classes, rotinas ou atributos) com o mesmo nome / assinatura em diferentes temas mas que não devem ser compostos, e elementos com nomes / assinaturas diferentes mas que devem ser compostos. Em tais casos, é necessário redefinir elementos de um dos temas para que a composição ocorra como desejado.

Na abordagem de implementação definida aqui para o DSOT, o operador de redefinição é o {}, que recebe um tema e algumas informações internas a aquele tema como argumentos. O operador

{} retorna um tema que corresponde exatamente ao tema passado como argumento, exceto pelas

+ (Theme3) <<theme>> Theme1 AClass + aRoutine( ): void <<theme>> Theme2 AClass

+ {incomplete} aRoutine( ): void

public void aRoutine( ){

... //1st implementation piece from Theme2 proceed;

... // 2nd implementation piece from Theme2 }

(a) Diagrama de temas.

<<theme>> Theme3

AClass

+ aRoutine( ): void

public void aRoutine( ){

... //1st implementation piece from Theme2 ... // implementation piece from Theme1 ... // 2nd implementation piece from Theme2 }

(b) Diagrama de classes do tema resultante.

Figura 3.15: Exemplo de composição no qual rotina incompleta possui correspondência no outro tema. + (Theme1Redef) <<theme>> Theme1 C1 <<theme>> <<abstract>> C2

(a) Diagrama de temas.

<<theme>> Theme1Redef

C2

(b) Diagrama de classes do tema re-sultante.

Theme1Redef := Theme1{ C1 => C2;

};

(c) Fórmula de composição.

+ (Theme3) <<theme>> Theme1 AClass <<theme>> Theme2 C2 AClass C1 C2 extends C1

(a) Diagrama de temas.

<<theme>> Theme3

AClass C2

C2 extends C1

(b) Diagrama de classes do tema resultante.

Figura 3.16: Exemplo de composição no qual uma superclasse de um tema é subclasse de outra superclasse no outro tema.

Quando um módulo é redefinido, toda a implementação interna àquele tema que utiliza o mó-dulo diretamente é atualizada para utilizar o mómó-dulo com a nova definição. Por exemplo, se o identificador de uma classe for alterado, todas as classes que declararem internamente variáveis daquela classe sofrerão atualização do tipo das variáveis.

Em uma especificação de composição, quando algumas redefinições são combinadas com uma composição, o conjunto de redefinições é chamado de listagem de exceções, pois elas estabelecem exceções à regra geral de que apenas módulos homônimos internos a temas sujeitos à composição podem se compor em um módulo só.

As subseções a seguir mostram como funciona a semântica da redefinição para vários cenários possíveis.

3.4.1 Alteração do identificador de uma classe, de um atributo, de

uma rotina ou de um parâmetro de rotina

Uma classe, atributo, rotina ou parâmetro pode ter seu identificador alterado por meio de uma redefinição. A semântica de redefinição para este cenário é demonstrada na Figura 3.17.

3.4.2 Alteração da ordem dos parâmetros de uma rotina

A ordem dos parâmetros de rotina pode ser alterada por meio de uma redefinição. A semântica de redefinição para este cenário é demonstrada na Figura 3.18.

<<theme>> Theme1

AClass

+ aRoutine( a: int, b: String ): void

<<theme>>

<<abstract>>

AClass

+ {abstract}aRoutine( b: String, a: int ): void

+ (Theme1Redef)

(a) Diagrama de temas.

<<theme>> Theme1Redef

AClass

+ aRoutine( b: String, a: int ): void

(b) Diagrama de classes do tema resultante.

Theme1Redef := Theme1{

AClass.aRoutine( int a, String b ) => aRoutine( String b, int a ); };

(c) Fórmula de composição.

Figura 3.18: Exemplo de redefinição no qual a ordem dos parâmetros de uma rotina é alterada.

3.4.3 Adição de parâmetros a uma rotina

Parâmetros podem ser adicionados a uma rotina por meio de uma redefinição. A restrição neste caso é que, se houver algum código naquele tema que chama a rotina a ser redefinida, tal código deve ser atualizado ao mesmo tempo que a ocorrência da redefinição. No estudo de caso descrito no Capítulo 4, contudo, não apareceram as condições que impõem a necessidade de satisfazer a restrição mencionada. A semântica de redefinição para este cenário é demonstrada na Figura 3.19.

<<theme>> Theme1

AClass + aRoutine( a: int ): void

<<theme>>

<<abstract>>

AClass

+ {abstract}aRoutine( b: String, a: int ): void

+ (Theme1Redef)

(a) Diagrama de temas.

<<theme>> Theme1Redef

AClass

+ aRoutine( b: String, a: int ): void

(b) Diagrama de classes do tema resultante.

Theme1Redef := Theme1{

AClass.aRoutine( int a ) => aRoutine( String b, int a ); };

(c) Fórmula de composição.

Figura 3.19: Exemplo de redefinição no qual parâmetros são adicionados a uma rotina.

3.5 Considerações Finais

O estudo de caso que ilustra como os mecanismos fornecidos pelo DSOT são utilizados no contexto de um projeto real é apresentado no Capítulo 4.

4