• Nenhum resultado encontrado

2.3 Abordagens de implementação

2.3.3 Delta-Oriented Programming

A abordagem de Delta-Oriented Programming (DOP) foi proposta em 2010 [10] com a finalidade de flexibilizar as restrições encontradas em Feature-Oriented Programming (FOP), uma abordagem de engenharia de software baseada no princípio de desenvolvi- mento gradual. A principal restrição em FOP é a não remoção de código-fonte de uma implementação. Dessa forma, DOP acaba se tornando uma abordagem mais expressiva e flexível para o desenvolvimento de LPS, se comparada a FOP, sendo DOP uma abordagem totalmente voltada para a implementação de LPS.

Em DOP, o desenvolvimento de uma LPS é dividida em módulo core e um conjunto de módulos deltas:

Módulo core - corresponde a uma implementação de um produto válido, conforme as definições das features. Sendo assim, esse produto deve conter, pelo menos, as

features obrigatórias e um conjunto mínimo de features alternativas, se for o caso;

Módulos deltas - especificam quais alterações devem ser aplicadas ao módulo core, afim de implementar novos produtos por meio da adição, alteração ou remoção de classes, variáveis e métodos.

Em DOP, a geração de produtos só é possível caso a implementação esteja bem- formada, ou seja, se o módulocore e os módulos deltas associados as features estiverem com uma configuração válida. Dessa forma, as alterações codificadas nos módulos deltas são aplicadas simultaneamente ao módulocore. Para que não haja nenhum conflito durante a geração de produtos, é necessário que as alterações presentes nos módulos deltas estejam organizadas de forma ordenada.

A ideia geral dessa abordagem não se restringe a uma linguagem de programação específica. Assim, a técnica mais utilizada para implementação de LPS nessa abordagem é o DeltaJ [10, 6, 15].

DeltaJ

O DeltaJ é uma implementação de Delta-Oriented Programming para o gerenciamento de linhas de produtos, que usa uma linguagem semelhante ao Java, de modo que as classes sejam organizadas em módulos deltas. A primeira versão recebeu o nome de DeltaJava e foi usada para se referir a uma linguagem para o Core DOP, uma primeira formulação original de DOP [15]. Posteriormente, as implementações prototípicas de DOP foram disponibilizadas com o nome genérico DeltaJ. Atualmente, o DeltaJ 1.5 é a versão mais recente e suporta a integração completa com o Java 1.5.

De maneira geral, essa versão fornece alguns recursos que, conforme os autores [15], foram criados para ir além da noção de Delta-Oriented Programming. Entre eles, o apri- moramento da sintaxe na declaração de linhas de produtos, de modo que não houvesse uma distinção sintática entre módulo core e os módulos deltas. Outro recurso foi a possi- bilidade de chamada do método original(), que pode ser usado para acessar o corpo de um método original quando um determinado método é modificado. No Código 2.3, é apresentado um exemplo do arquivo de declaração da KWIC-PL.

Código 2.3: Exemplo de uma declaração de linhas de produtos em DeltaJ 1.5.

1 SPL Kwic {

2 Features = {KWIC, Base, Input, DBLP, FileIn, Output, Screen,

FileOut}

3 Deltas = {dBase, dFileOut, dScreen, dDblp, dFileIn}

4 Constraints {

5 KWIC & Base & Input & Output;

6 Output & (Screen ^ FileOut);

7 Input & (DBLP ^ FileIn);

8 }

9 Partitions {

10 {dBase} when (Base);

11 {dDblp} when (DBLP);

12 {dFileIn} when (FileIn);

13 {dFileOut} when (FileOut);

14 {dScreen} when (Screen);

15 }

16 Products {

17 Prod1 = {KWIC, Base, Input, FileIn, Output, FileOut};

18 Prod2 = {KWIC, Base, Input, DBLP, Output, FileOut};

19 Prod3 = {KWIC, Base, Input, FileIn, Output, Screen};

20 Prod4 = {KWIC, Base, Input, DBLP, Output, Screen};

21 }

22 }

A especificação de uma linha de produtos em DeltaJ 1.5 é realizada através de uma Domain Specific Language (DSL), conforme o exemplo acima. Ela permite uma especificação de cada definição necessária para a geração de produtos.

de produtos — conforme exibido na linha 2. Ela é indispensável para que as demais especificações funcionem corretamente. Em seguida, na linha 3, os nomes de todos os Deltas que compõem a linha de produtos são especificados. É importante destacar que o DeltaJ permite alterar o diretório onde os deltas são criados logo após a declaração — para isso, basta acessar a opção de configuração na IDE — de modo que seja possível criar e customizar diretórios para esses assets.

Já as Constraints, entre as linhas 4 e 8, equivalem ao Feature-Model da linha de produtos. Dessa forma, todas as restrições de features são representadas através de fórmula proposicional com o uso de operadores, como and (AND ou * ou &), or (OR ou + ou |), exclusive (XOR ou ˆ), not (! ou - ou ˜) e implies (IMPLIES ou =>). Essa representação no Código 2.3 equivale as restrições do FM da Figura 2.2. Em seguida, encontra-se os Partitions, conforme o código as linhas 9 e 15, que consistem no conjunto de cláusulas when que associam os Deltas aos nomes das Features, ou seja, a definição determina quais combinações de features um ou mais deltas serão aplicados durante o processo de construção de um determinado produto. Essa especificação é equivalente ao CK.

O último bloco (Products, entre as linhas 16 e 21) define quais serão os conjuntos de produtos da LPS. Um produto começa com o nome do próprio produto seguido por uma atribuição e o conjunto defeatures que devem ser implementadas para esse produto. Cada uma dessas definições trabalham em conjunto para que os produtos possam ser gerados. Dessa forma, para garantir que um produto seja gerado de forma correta, deve-se garantir que todas as definições estejam alinhadas com os propósitos de cada produto.

Exemplo de código-fonte

O exemplo no Código 2.4 está associado a feature DBLP cuja implementação foi feita através do DeltaJ.

Código 2.4: Exemplo de delta da KWIC-PL.

1 delta dDblp {

2 adds {

3 package kwic;

4 public class DBLPStorageManager {

5 ...

6 }

7 }

8 modifies kwic.Main {

10 return new DBLPStorageManager();

11 }

12 }

13 }

O código-fonte das linhas 2 a 8 introduz a classe DBLPStorageManager, que nesse contexto só existirá caso a feature DBLP esteja selecionada para o processo de geração do produto. Já as linhas 10 e 11 especificam uma modificação no método getInput da classe Main — nesse exemplo em questão, o novo conteúdo desse método será apenas o trecho de código correspondente na linha 12.