UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ CAMPUS PONTA GROSSA CURSO SUPERIOR DE TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS Grupo de Pesquisa em Engenharia de Software – GPES Linha de Pesquisa: Engenharia de Software Projeto: Framemk – Um framework para análise, elaboração e otimização de preço de venda. Elaborado por: Rodolfo Adamshuk Silva [email protected] Relatório do GPES Relatório referente ao estudo sobre o padrão de projeto Interpreter. Realizado do dia 15 de abril de 2009 a 27 de abril de 2009. Padrão Interpreter O Padrão interpreter, como os padrões State e Strategy, distribui uma operação ao longo de uma coleção de classes. Em tais padrões, o efeito de chamar a operação depende da classe do objeto que recebe a chamada. Tanto no State como no Strategy, o receptor de uma chamada de operação é um único objeto. O Interpreter utiliza a mesma idéia e a aplica a uma composição – em especial, a uma composição rica, ou com várias maneiras de formar grupos [1]. Este padrão descreve como definir uma gramática para linguagens simples, representar e interpretar sentenças. O propósito deste padrão é que dada uma linguagem, define uma representação para a sua gramática juntamente com um interpretador que usa representação para interpretar as sentenças da linguagem [2]. O padrão Interpreter é semelhante ao padrão Composite, o qual define uma interface comum para itens individuais e grupos de itens. O Composite não exige várias e interessantes maneiras de formar grupos, embora permita isso. No Interpreter a idéia de que há vários tipos de composição é essencial [1] e pode ser utilizado para representar e resolver problemas recorrentes que possam ser expressos sob a forma de uma linguagem formal simples. O padrão usa classes para representar cada regra de uma gramática (expressão regular) [3]. A maneira como uma classe compõe outros componentes define o modo como uma classe Interpreter irá implementar ou interpretar uma operação distribuída. Cada classe composta em uma instância de Interpreter modela uma regra de como objetos executáveis de acordo com um conjunto de regras de composição que nós definimos, como por exemplo, quando estamos modelando o domínio de uma expressão, temos as classes “Variavel” e “Soma”, e na implementação definimos que a classe “Soma” vai realizar a soma de duas variáveis. Um objeto Interpreter conduz a execução, ou a avaliação de uma coleção de regras, permitindo construir avaliadores de expressões e linguagens de comando [1]. Aplicabilidade do Interpreter A aplicabilidade do padrão é definida quando a gramática a ser interpretada é simples. Para gramáticas complexas a hierarquia de classes se 1 UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ CAMPUS PONTA GROSSA CURSO SUPERIOR DE TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS Grupo de Pesquisa em Engenharia de Software – GPES Linha de Pesquisa: Engenharia de Software Projeto: Framemk – Um framework para análise, elaboração e otimização de preço de venda. Elaborado por: Rodolfo Adamshuk Silva [email protected] torna difícil de gerenciar. Neste caso, geradores de parsers são uma alternativa melhor. Também é uma questão chave na hora de decidir utilizar este padrão é quando a eficiência não é uma questão crítica, pois um código intermediário permite maior eficiência, por exemplo, expressões regulares podem ser traduzidas para máquinas de estado finito. Nestes casos, o tradutor pode ser criado através de um Interpreter [3]. Estrutura A estrutura do padrão Interpreter está baseada em uma classe com a expressão abstrata e a partir dela a geração de classes de expressões terminais e de expressões não terminas. A estrutura do padrão Interpreter pode ser visualizada na Figura 1. Figura 1 – Estrutura do padrão Interpreter. Fonte: Farias (2008). A classe AbstractExpression define um método abstrato Interpret que será comum a todos os nós numa árvore sintática. A classe TerminalExpression implementa um método Interpret associado a símbolos terminais da gramática. Uma instância é requerida para todos os símbolos terminais de uma sentença. A classe NonTerminalExpression é requerida para cada regra R::= R1R2...Rn na gramática. Também implementa o método Interpret para os símbolos não terminais da gramática e mantém variáveis do tipo AbstractExpression para cada símbolo R. A classe Context contém informações que são globais ao interpretador. A classe Client constrói (ou recebe) uma árvore sintática abstrata representando uma sentença particular na linguagem definida pela gramática. Esta árvore sintática é montada através de instâncias das classes 2 UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ CAMPUS PONTA GROSSA CURSO SUPERIOR DE TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS Grupo de Pesquisa em Engenharia de Software – GPES Linha de Pesquisa: Engenharia de Software Projeto: Framemk – Um framework para análise, elaboração e otimização de preço de venda. Elaborado por: Rodolfo Adamshuk Silva [email protected] NonTerminalExpression e TerminalExpression. Esta classe é a que chama o método Interpret [3]. A seqüência funcional do padrão Interpreter começa quando o cliente constrói uma sentença como uma árvore sintática abstrata com instâncias de NonTerminalExpression e TerminalExpression, então inicializa o contexto e chama o método Interpret. Cada nó NonTerminalExpression define seu Interpret em termos dos Interpret de cada subexpressão. O método Interpret de cada TerminalExpression define o caso base da recursão. O método Interpret de cada nó usa o contexto para armazenar e acessar o estado do interpretador [3]. A Figura 2 mostra o diagrama de seqüência do funcionamento geral do padrão Interpreter. Figura 2 – Diagrama de seqüência do Interpreter Vantagens As vantagens de utilizar o padrão e que há uma grande facilidade de mudar e estender gramática, pois o padrão usa uma classe para representar cada regra da gramática. Implementar a gramática também é fácil, os “nodos” da árvore são implementados de uma maneira similar. Acrescentando novas formas de interpretar expressões torna mais fácil resolver uma expressão de uma nova maneira [2]. Referências [1] METSKER, Steven John. Padrões de projeto em Java. Bookman, 2004. [2] FARIAS, Kleinner. Padrão de Projeto Interpreter. Disponível em: <wiki.les.inf.puc-rio.br/uploads/c/cc/Interpreter_20082.ppt>. Acesso em: 11 abr. 2009. 3 UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ CAMPUS PONTA GROSSA CURSO SUPERIOR DE TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS Grupo de Pesquisa em Engenharia de Software – GPES Linha de Pesquisa: Engenharia de Software Projeto: Framemk – Um framework para análise, elaboração e otimização de preço de venda. Elaborado por: Rodolfo Adamshuk Silva [email protected] [3] NETTO, Manoel Teixeira de Abreu. Padrão de Projeto Interpreter: Projeto de Sistemas de Software. Disponível em: <wiki.les.inf.pucrio.br/uploads/3/36/Interpreter.pdf>. Acesso em: 12 maio 2009. 4