PROGRAMA INSTITUCIONAL DE INICIAÇÃO CIENTÍFICA
RELATÓRIO FINAL DE ATIVIDADES
(SETEMBRO/2008 A AGOSTO/2009)
Unificação dos subframeworks de validação semântica e
sintática de fórmulas para criação de um protótipo de cálculo
de fórmulas
Rodolfo Adamshuk Silva
Dr(ª). Simone Nasser Matos
Modalidade: PIBIC/ UTFPR
CAMPUS Ponta Grossa, Setembro 2009
SUMÁRIO
1
TÍTULO ................................................................................................................................... 3
2
RESUMO ................................................................................................................................ 3
3
INTRODUÇÃO ........................................................................................................................ 3
4
MATERIAL E MÉTODOS ......................................................................................................... 3
4.1
REVISÃO BIBLIOGRÁFICA DO TEMA ............................................................................. 4
4.1.1
Composição do preço de venda ............................................................................ 4
4.1.2
Padrões de projeto ................................................................................................ 5
4.1.3
F-UML .................................................................................................................... 8
4.2
COMPREENSÃO E APLICABILIDADE DE PROJETO JEE ................................................ 10
4.2.1
Definição.............................................................................................................. 10
4.2.2
Aplicabilidade ...................................................................................................... 11
4.2.3
Estrutura .............................................................................................................. 11
4.3
CRIAÇÃO DO SUBFRAMEWORK DE VALIDAÇÃO SEMÂNTICA................................... 12
4.3.1
Estudo Analítico de Trabalhos Relacionados ...................................................... 12
4.3.2
Aplicação da Abordagem Dirigida por Responsabilidades .................................. 14
4.3.3
Desenvolvimento das classes .............................................................................. 19
4.4
UNIFICAÇÃO DOS AVALIADORES SINTÁTICO E SEMÂNTICO..................................... 21
4.4.1
Analisador sintático ............................................................................................. 21
4.4.2
Avaliador Semântico............................................................................................ 23
4.4.3
Unificação ............................................................................................................ 25
5
RESULTADOS E DISCUSSÃO ................................................................................................. 26
6
CONCLUSÕES ....................................................................................................................... 28
7
REFERENCIAS BIBLIOGRAFICAS ........................................................................................... 28
APÊNDICE A............................................................................................................................. 30
1
TÍTULO
FRAMEMK: Um framework para análise, elaboração e otimização de preço de venda.
2
RESUMO
Este trabalho descreve a criação de um subframework para a validação semântica de
fórmulas, além de detalhar sua unificação com o de validação sintática de fórmulas.
Para a criação do validador semântico utilizou-se a abordagem dirigida por
responsabilidades. O subframework foi desenvolvido para ser utilizado em plataforma
web e é por isso foi desenvolvido utilizando o framework Struts.
Palavras-chave: Framework, aplicativo web, validação de fórmulas.
3
INTRODUÇÃO
Para calcular o preço dos produtos colocados à venda deve-se refletir sobre um
ponto fundamental: Pode-se calcular o preço de venda a partir de custos internos sem
preocupar-se com a concorrência? Obviamente a resposta a esta pergunta é não.
Cada vez mais, os clientes estão pesquisando preços e procurando qualidade,
tanto dos produtos quanto do atendimento. Assim, os preços calculados através de
fórmulas servirão apenas como um referencial para comparação com os de mercado.
Isso não significa dizer que não se deve calculá-los, ao contrário, esse cálculo dará um
parâmetro para se avaliar a estrutura de custos (SEBRAE, 2009).
Pensando nisso, este trabalho propôs a criação do subframework para Análise
Sintática e Semântica de Fórmulas, sendo executado em ambiente web e desenvolvido
uma linguagem de programação que permita a portabilidade. Neste trabalho serão
descritas todas as atividades realizadas durante o período do projeto, explicando cada
fase do projeto de pesquisa e apresentando os resultados atingidos.
4
MATERIAL E MÉTODOS
Durante o desenvolvimento do projeto, houve a necessidade de realizar uma
série de atividades que foram programadas para que se obtivesse um resultado
satisfatório. Neste tópico serão abordadas as atividades realizadas neste período de
desenvolvimento do projeto.
4.1
REVISÃO BIBLIOGRÁFICA DO TEMA
A revisão bibliográfica do tema consistiu-se em realizar uma pesquisa sobre os
assuntos abordados no projeto.
4.1.1
Composição do preço de venda
Uma empresa quando vai realizar a composição do custo de um produto deve se
preocupar com os insumos utilizados para sua fabricação ou para a obtenção do serviço.
Segundo Leão (2008) os insumos utilizados na formação do custo são: Mão-de-obra
que está sempre presente na maioria dos serviços e sempre nos produtos; Veículos que
são utilizados para a realização do transporte; Equipamentos e ferramentas utilizados
pela mão-de-obra para a realização do produto. Os equipamentos precisam de
manutenção e as ferramentas não; Materiais de consumo ou matérias-primas que são
mais relevantes nos produtos; Outros são os que não se encaixam em nenhum insumo
anterior; Administração é o gerenciamento que a empresa deve ter em seu negócio.
Para Leão (2008) o preço de venda de um serviço ou produto é representado pela
expressão “Preço = custo + lucro + impostos + comissões”. O lucro representa a parte
do benefício que a empresa espera pelo serviço prestado ou pela fabricação do produto,
incluindo os impostos sobre este lucro, caso existam. É determinado pela empresa
prestadora do serviço ou fabricante do produto. Uma margem de lucro líquido para a
empresa de 10% do custo do serviço ou do produto representa um benefício ideal para a
empresa.
Conforme a legislação vigente, os impostos que incidem sobre o preço de venda
de um serviço ou produto são: ISS – Imposto Sobre Serviço, alíquota máxima de 5%,
podendo ou não incidir sobre os materiais de consumo. Não incide nos produtos; PIS –
Programa de Integração Social; COFINS – Contribuição para a seguridade social; ICMS
– Imposto sobre Circulação de Mercadorias e alguns Serviços; IPI – Impostos Sobre
Produtos Industrializados; IRPJ – Imposto de Renda Pessoa Jurídica; CSLL –
Contribuição Social Sobre o Lucro Líquido. Se a empresa paga comissões sobre a venda
de serviços ou produtos, o percentual dessas comissões deve se somado aos impostos no
cálculo dos impostos nos serviços e nos produtos.
4.1.2
Padrões de projeto
Quando está se trabalhando com desenvolvimento de um projeto, seja ele qual
for, é de grande ajuda ter-se um referencial para seguir. Encontrar métodos eficazes
comuns para atingirem objetivos e para resolver problemas é um ponto de grande
importância quando se esta na criação de um projeto.
Segundo Metsker (2004) Christopher Alexander foi um dos primeiros escritores
a encapsular as melhores práticas de um ofício por meio da documentação de seus
padrões. Seu trabalho está relacionado à arquitetura de edifícios, não de software. No
início dos anos 1990, alguns desenvolvedores tomaram conhecimento do trabalho sobre
padrões desenvolvido por Alexander.
Desta forma, os desenvolvedores perceberam que existem problemas em
software que ocorrem repetidamente e que poderiam ser resolvidos, em certa medida, da
mesma maneira. Também perceberam que seria possível projetar software em termos de
padrões, criando soluções específicas baseadas nesses padrões. Segundo Metsker
(2004), um padrão de projeto é um padrão – uma maneira de alcançar um objetivo – que
utiliza classes e seus métodos em uma linguagem orientada a objetos. Um
desenvolvedor começa a pensar em padrões de projeto depois de aprender uma
linguagem orientada a objetos e após certo tempo programando nessa linguagem. Então,
começa-se a observar que o código de outros programadores é mais simples que o
desenvolvido, porém possui as mesmas funcionalidades.
Desenvolver softwares utilizando padrões de projeto possui, dentre outras, duas
principais vantagens (SHALLOWAY & TROTT, 2004):
−
Reutilizar soluções – Reutilizando projetos já estabelecidos, obtém-se um início
direcionado para o problema que está sendo tratado. A partir de um problema
encontrado e que já foi resolvido por outra pessoa se pode beneficiar e aprender
com a experiência dos outros. Reutilizando projetos prontos não se faz necessário
reinventar soluções para problemas recorrentes.
−
Estabelecer terminologia comum – A comunicação e o trabalho em equipe
requerem uma base de vocabulário e um ponto de vista comum do problema. Os
padrões de projeto fornecem um ponto comum de referência durante a fase de
análise e elaboração de um projeto de software.
Porém, os padrões de projeto fornecem uma perspectiva de mais alto nível
acerca dos problemas e do processo de projeto e orientação a objetos, o que poupa de ter
que desenvolver os detalhes precocemente.
Shalloway & Trott (2004) dizem que a maioria dos padrões de projeto também
torna o software mais passível de modificação. A razão para tal é que eles são as
soluções comprovadas pelo tempo; portanto, evoluíram em estruturas que podem tratar
mudanças mais prontamente do que as que, muitas vezes vêm primeiro à mente como
uma solução. Atualmente há várias maneiras de descrever padrões de projeto. Porém, os
itens listados na Tabela 1 devem ser incluídos em qualquer descrição.
Tabela 1 – Características principais dos padrões
Item
Descrição
Nome
Todos os padrões têm um nome único que os identifica.
Intenção
O propósito do padrão.
Problema
O problema que o padrão está tentando resolver.
Solução
Como o padrão provê uma solução para o problema no contexto em
que ele aparece.
Participantes e
As entidades envolvidas no padrão.
colaboradores
Conseqüências
As conseqüências de utilizar o padrão. Investiga as forças que nele
interagem.
Implementação
Como o padrão pode ser implementado. As implementações são
apenas manifestações concretas do padrão e não devem ser
interpretadas como o próprio padrão.
Referência
O lugar para onde olhar no texto da Gangue dos Quatro a fim de
Gangue dos
obter mais informações
Quatro
Fonte: Shalloway, Trott (2004).
Embora muitas pessoas estivessem trabalhando em padrões de projeto no início
da década de 1990, o livro que teve maior influência foi Design Patterns: Elements of
Reusable Object Oriented Software, escrito por Gamma, Helm, Johnson e Vlissides. Em
reconhecimento pelo seu importante trabalho, esses quatro autores passaram a ser
normalmente conhecidos como Gangue dos Quatro. Os tipos de padrão estão divididos
por afinidade. Os principais tipos de padrões de projetos segundo Macoratti (2009) são:
Padrões de Criação (Creational)
Abstract Factory - Um método Factory é um método que fabrica objetos de um
tipo particular. Um objeto Factory é um objeto que encapsula métodos Factory.
Builder - Separa a construção de um objeto complexo da sua representação de
forma que o mesmo processo de construção possa criar diferentes representações.
Factory Method - É uma interface para instanciação de objetos que mantém
isoladas as classes concretas usadas na requisição da criação destes objetos.
Prototype - O padrão Prototype fornece outra maneira de se construir objetos de
tipos arbitrários.
Singleton. - Garante que para uma classe específica só possa existir uma única
instância, a qual é acessível de forma global e uniforme.
Padrões de Estrutura (Structural)
Adapter - Permite que dois objetos se comuniquem mesmo que tenham
interfaces incompatíveis.
Bridge - Desacopla a interface da implementação e promove o ocultamento de
detalhes de implementação dos clientes.
Composite - lida com uma estrutura de elementos agrupada hierarquicamente
(não como meras coleções).
Decorator - Atribui responsabilidades adicionais a um objeto dinamicamente. O
Decorator fornece uma alternativa flexível a subclasses para a extensão da
funcionalidade.
Facade - Interface unificada para um subsistema tornando o subsistema mais
fácil de usar.
Flyweight - Usa compartilhamento para dar suporte a vários objetos de forma
eficiente.
Proxy - Fornece um objeto representante ou procurador de outro objeto para
controlar o acesso ao mesmo.
Padrões de Comportamento (Behavioral)
Chain of Responsability - Evita dependência do remetente (cliente) de uma
requisição ao seu destinatário, dando a oportunidade de mais objetos tratarem a
requisição.
Command - Associa uma ação a diferentes objetos através de uma interface
conhecida.
Interpreter - Usado para ajudar uma aplicação a entender uma declaração de
linguagem natural e executar a funcionalidade da declaração.
Iterator - Provê uma forma de se percorrer os elementos de uma coleção sem
violar o seu encapsulamento.
Mediator - Cria um objeto que age como um mediador controlando a interação
entre um conjunto de objetos.
Memento - Torna possível salvar o estado de um objeto de modo que o mesmo
possa ser restaurado.
Observer - Define uma relação de dependência 1:N de forma que quando um
certo objeto (assunto) tem seu estado modificado os demais (observadores) são
notificados. Além disso, possibilita baixo acoplamento entre os objetos observadores e o
assunto.
State - Permite objeto alterar seu comportamento quando o estado interno muda.
Strategy - Permite que uma família de algoritmos seja utilizada de modo
independente e seletivo.
Template Method - Define o esqueleto de um algoritmo em uma operação
adiando a definição de alguns passos para a subclasse.
Visitor - Define operações independentes a serem realizadas sobre elementos de
uma estrutura.
4.1.3
F-UML
“É uma extensão da linguagem UML cujo objetivo é atender a restrições da
modelagem de framework. Por esse motivo, é composta por um pequeno conjunto de
extensões que captura a semântica das variações de um framework orientado a objetos”
(FONTOURA et al. 2002). A notação gráfica da F-UML para os diagramas de caso de
uso e de classe estão ilustrados na Tabela 2, adaptado de Bouassida et al. (2003).
Tabela 2 - F-UML para diagrama de caso de uso e de classes
Notação
Objetivo
Diagrama de caso de uso
Representa um caso de uso base (frozen spot) do framework. Ou seja,
um aspecto comum entre as aplicações concretas do domínio.
Tabela 2 - F-UML para diagrama de caso de uso e de classes (cont.)
Representa um ator base do framework. Ou seja, um ator comum entre
as aplicações concretas do domínio.
Representa um caso de uso específico ou flexível (hot spot) do
framework. Ou seja, um aspecto diferente entre as aplicações concretas
do domínio.
Representa um ator específico do framework. Ou seja, um ator
diferente entre as aplicações concretas do domínio.
Mostra que é possível adicionar uma herança entre casos de uso em
uma aplicação reusando o framework. Isso o torna mais adaptável.
Diagrama de classe
Ilustra o framework base.
Mostra um framework de caixa preta o qual possibilita o reuso das
funcionalidades aplicadas por meio da composição ou da definição de
interfaces para os componentes.
Ilustra que uma classe com todas as suas classes herdadas são do tipo
caixa branca, o qual possibilita o reuso e a extensão das
funcionalidades desenvolvidas por meio da herança de classes e da
implementação de métodos.
Elucida a utilização de um método virtual. Um método virtual é quando
se tem um método na classe pai e cria o mesmo método na classe filha,
mas com algumas diferenças.
Apresenta um método com uma assinatura indefinida.
Mostra que a classe pode ser adaptada por meio da adição ou remoção
dos atributos ou métodos, os quais podem ser definidos estendendo as
funcionalidades da classe.
Representa que o framework pode ser adaptável através da adição de
novas classes, ou seja, novas subclasses podem ser adicionadas pelo
relacionamento de generalização ou realização.
Segundo Fontoura et al. (2002) além dos estereótipos ilustrados na Tabela 2,
como {incomplete}, pode-se encontrar na F-UML os seguintes:
−
{app-class}: utilizado quando a classe existe somente durante a instanciação do
framework.
−
{variable}: especifica que o método pode ser implementado durante a instanciação
do framework.
4.2
−
{static}: representa um hot spot que não requer instanciação em tempo de execução.
−
{dynamic}: representa um hot spot que requer instanciação em tempo de execução.
COMPREENSÃO E APLICABILIDADE DE PROJETO JEE
Dentre os padrões de projetos estudados, o que foi utilizado e visto mais
profundamente foi o padrão Interpreter.
4.2.1
Definição
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. Segundo Metsker (2004) 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.
Este padrão descreve como definir uma gramática para linguagens simples,
representar e interpretar sentenças. Para Faria (2009) 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. 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. Conforme Metsker
(2004) no Interpreter a idéia de que há vários tipos de composição é essencial 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).
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 define, como por
exemplo, quando se esta modelando o domínio de uma expressão, tem-se as classes
“Variavel” e “Soma”, e na implementação se define 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” (METSKER, 2004).
4.2.2
Aplicabilidade
A aplicabilidade do padrão é definida quando a gramática a ser interpretada é
simples. Para gramáticas complexas a hierarquia de classes se torna difícil de gerenciar.
Neste caso, geradores de parsers são uma alternativa melhor.
Para Abreu Netto (2009) 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.
4.2.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 está ilustrada 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. Para
Abreu Netto (2009) 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 NonTerminalExpression e
TerminalExpression. Esta classe é a que chama o método Interpret.
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” (ABREU NETTO, 2009). O método Interpret de cada nó usa o
contexto para armazenar e acessar o estado do interpretador. A Figura 2 mostra o
diagrama de seqüência do funcionamento geral do padrão Interpreter.
Figura 2 – Diagrama de seqüência do Interpreter
4.3
CRIAÇÃO DO SUBFRAMEWORK DE VALIDAÇÃO SEMÂNTICA
Ressalta-se neste tópico que esta atividade não constava no plano de trabalho.
Esta atividade pertencia a outro aluno que abandonou o projeto. Houve a necessidade de
desenvolver esta tarefa, pois as atividades propostas para o plano aqui descrito possuíam
dependências com as que deveriam ser realizadas por este aluno.
4.3.1
Estudo Analítico de Trabalhos Relacionados
Para a realização deste estudo, levantou-se na literatura as abordagens que
contemplavam um processo de definição arquitetural para o desenvolvimento de
frameworks e subframeworks. Dentre elas, destacam-se as seguintes: Johnson (1993),
Taligent (1994), Landin e Niklasson (1995), Pree (1999), Fayad et al. (1999), Mattson
(2000), Butler e Xu (2001), Braga (2002), e por fim, Matos e Fernandes (2008).
Após o estudo das abordagens, realizou-se uma análise qualitativa entre elas,
considerando-se os seguintes critérios:
−
Criação de subsistemas (SU), subframeworks (SF) e componentes (C) – Possibilita
a definição de uma arquitetura que facilita o entendimento do funcionamento do
sistema, bem como seu reúso;
−
Aplicação de padrões de projeto e metapadrões – Permite aumentar a reusabilidade
na fase de projeto;
−
Análise arquitetural – É um processo iterativo que permite que sejam feitos
refinamentos no modelo arquitetural, que inicialmente foi escolhido de forma a
contribuir para a criação de uma arquitetura que contemple algumas características
julgadas interessantes, tais como: integridade, reusabilidade e flexibilidade. Para
Butler e Xu (2001), esse processo é denominado de refatoração arquitetural;
−
Estilo Arquitetural – Reduz o esforço para compreender o sistema desenvolvido por
outra pessoa e, portanto, diminui a quantidade de informações a serem assimiladas
num novo projeto, permitindo desta forma facilitar o reúso em um novo (Bass et al.,
2003);
−
Reúso Arquitetural – Traz benefícios que incluem redução de custo de construção e
do tempo de produção;
−
Definição dos Hot Spots nos subframeworks – Representam os pontos que são
específicos para uma aplicação-exemplo e constituem a parte central do projeto de
frameworks (Pree, 1999).
Na Tabela 3, relacionam-se as abordagens citadas e os critérios. As linhas onde
aparecem o “X” significa a presença do critério, caso contrário, a sua ausência.
Observou-se que todas as abordagens contemplam a utilização de padrões de projeto e
metapadrões durante a definição da arquitetura de framework. Com relação a Criação de
Subsistemas, Subframework e Componentes verificou-se que somente a abordagem de
Matos e Fernandes (2008) abrange mais detalhadamente seu processo de identificação e
construção. Além disso, essa abordagem explica como a definição dos hot spots deve
ser feita durante a construção dos subframeworks na fase inicial do seu processo de
construção. Isso, de acordo com Tang et al. (2004), pode contribuir para a confecção de
um sistema com um maior grau de flexibilidade e portabilidade, impactando sob os seus
aspectos de desempenho, custo e escalabilidade.
Tabela 3 - Critérios contemplados pelas abordagens da literatura.
Constatou-se também que o critério de Análise Arquitetural é contemplado na
maioria das abordagens e é considerado um fator importante no processo de definição
da arquitetura do framework. Menos da metade das abordagens não contempla a
definição de um estilo arquitetural e que, segundo Paris (2004), a sua escolha implica
em um aumento de flexibilidade do sistema, sendo assim um critério importante na
definição da arquitetura. Por fim, o Reúso Arquitetural é contemplado por mais da
metade das abordagens possibilitando o reúso de requisitos, projeto, métodos e de
componentes de software.
Após a análise das abordagens, verificou-se que a de Matos e Fernandes (2008)
era a ideal para ser aplicada no desenvolvimento do subframework de análise sintática e
semântica de fórmulas, pois traz o processo detalhado para sua construção. Além disso,
contempla também os benefícios trazidos pelas outras abordagens, dentre eles, podemse citar os seguintes, entre outros: estilo arquitetural, aplicação de padrões de projeto e
metapadrões.
4.3.2
Aplicação da Abordagem Dirigida por Responsabilidades
Para aplicação da abordagem dirigida por responsabilidades, selecionaram-se
métodos no domínio de formação de preço de venda, tais como os seguintes: ABC
(Cogan1999; Silvestre, 2002), Custo Pleno (Martins, 2003) e Sebrae (SEBRAE, 2008).
Esses métodos representam as aplicações-exemplo para o desenvolvimento de
framework e todos possuem uma fórmula de preço de venda a ser calculada.
Depois de realizada a análise de cada método descrita em Crazuskiet al. (2008),
do subsistema Cálculo do Preço de Venda, e a partir de cada Modelo de Requisitos e de
Classes gerado para cada aplicação-exemplo analisada, pode-se levantar os
subframeworks executando os passos descritos a seguir (Matos e Fernandes 2006).
PASSO 1 – Identificar os Frozen e Hot Spots a Partir dos Requisitos dos Subsistemas
A entrada para esse passo é o Modelo de Requisitos gerado para cada
perspectiva (Wirfs-Brock e McKean 2003; Crazuskiet al. 2008) de cada aplicaçãoexemplo. O modelo de requisitos possui um diagrama de caso de uso UML, bem como
sua descrição textual, separados por perspectiva. Para criar esse modelo foi necessário
realizar um estudo sobre o domínio de cada aplicação-exemplo. O cálculo do preço de
venda de produtos ou serviços deve se refletir sobre os custos decorrentes da produção
do produto e também sobre a concorrência.
Cada vez mais, os clientes estão pesquisando preços e procurando qualidade,
tanto dos produtos quanto do atendimento. Assim, os preços calculados através de cada
método de formação de preço de venda servirão como um referencial para a
comparação com os preços praticados no mercado (SEBRAE 2008). Durante a análise
das aplicações-exemplo, identificaram-se vários subsistemas, dentre eles todas as
aplicações-exemplo possuíam o de Cálculo do Preço de Venda, que deve realizar o
processamento da fórmula do preço de venda. Baseando-se no Modelo de Requisitos
para cada método e identificam-se os frozen e hot spots. O processo de indentifação
destes pontos está descrito em Matos e Fernandes (2008). Logo após a classificação dos
requisitos do framework, constrói-se o diagrama de caso de uso no formato F-UML
(Fontoura et al., 2000) para o subsistema que estava sendo analisado, neste caso, para o
Cálculo do Preço de Venda ilustrado na Figura 3.
Figura 3 - Diagrama de Caso de Uso UML-F.
O caso de uso Verificar token e Exponenciar são hot spots e os outros são frozen
spots. O Verificar token foi classificado como hot spot, porque cada aplicação-exemplo
analisada possuía diferentes tipos de token em sua fórmula e o Exponenciar somente
aparecia na aplicação-exemplo ABC. Desta forma, a abordagem utilizada permite a
identificação dos frozen e hot spots em fase inicial do processo de construção dos
subframeworks.
PASSO 2 – Elaborar o diagrama de classes que satisfazem os requisitos do framework
A entrada para esta fase é o Modelo de Classes, composto de um conjunto de
classes e seus relacionamentos, de cada aplicação-exemplo e o(s) diagrama(s) de casos
de uso UML-F gerados no Passo 1. Como nos diagramas de casos de uso UML-F já
foram definidos de forma antecipada quais casos de uso são frozen spots e quais são hot
spots, analisa-se neste momento para cada caso de uso do framework as possíveis
classes, a partir do Modelo de Classes de cada aplicação-exemplo, que venham a
atendê-los. Depois cria-se o diagrama de classes para cada requisito, levando-se em
conta os casos de uso identificados como frozen e hot spots. A integração desses
diagramas representa o Modelo de Classes para o Subsistema que está sendo analisado
no momento.
Antes de explicar este passo, ressalta-se que utilizou-se o estilo arquitetural em
camadas (BASS et al., 2003), o qual atendeu os requisitos de flexibilidade,
manutenibilidade e reusabilidade, importantes para seu desenvolvimento. Optou-se por
este estilo porque o framework de formação de preço de venda é um software do tipo
cliente-servidor para web implementado na plataforma JEE.
Considerando o diagrama UML-F, ilustrado na Figura 4, verifica-se que possui
os seguintes requisitos: Verificar sintaxe, Verificar semântica, Verificar token que
engloba Somar, Subtrair e Exponenciar, entre outros. Esses requisitos foram satisfeitos
pelas
seguintes
classes
ExpressaoAlgebrica,
do
Variavel,
Modelo
Soma,
de
Classe
Subtracao,
das
aplicações-exemplo:
Multiplicacao,
Divisao,
Exponenciacao, entre outras. O processo de indentifação foi baseado em Matos e
Fernandes (2008). Por isso, foram reusadas das aplicações-exemplo. Parte do diagrama
de classes para o caso de uso Verificar semântica está ilustrado na Figura 4. A
ExpressaoAlgebrica é uma classe abstrata, a classe que representa a expressão terminal
é a Variavel e as classes Soma, Subtracao, Multiplicacao, Divisao, Exponenciacao
representam as expressões não terminais.
Figura 4 - Parte do diagrama de classe para o requisito Verificar Semântica
Repete-se este processo até que todos os requisitos para o subsistema analisado
possuam seu(s) diagrama(s) de classes. No final desse passo, para cada requisito
analisado tem-se um diagrama de classes correspondente. A integração desses
diagramas representa o Modelo de Classes para o Subsistema Cálculo do Preço de
Venda que é base para o Passo 4.
PASSO 3 – Identificar os possíveis subframeworks
Como no Passo 1 foram levantados os requisitos do framework, neste passo
identificam-se quais deles podem ser usados em outras aplicações, verificando os
possíveis hot spots que a ele estão associados. Assim, um subframework pode ser
utilizado como possível framework em outro contexto.
Neste trabalho, por exemplo, os requisitos Verificarsemântica e Verificarsintaxe
podem ser utilizados separadamente em outros contextos como na utilização de
compiladores e na validação de linguagem natural, respectivamente. Por isso, foram
considerados como subframeworks distintos.
PASSO 4 – Criar o diagrama de classes UML-F para os subframeworks
Considerando que todos os subframeworks tenham sido identificados no Passo 3,
cria-se um pacote para cada um deles, que deve conter um ou mais diagramas de
classes. No caso do subframework Verificar semântica, obteve-se o pacote
validacaoSemantica ilustrado na Figura 5. Na Figura 5, o pacote validacaoSemantica é o
responsável pelo cálculo das variáveis,
o estrutura contém as estruturas de dados
utilizadas para a transformação de uma fórmula infixa para a pósfixa, além de realizar
uma pesquisa no banco de dados.
Figura 5 - SubframeworkVerificarsemântica.
O pacote persistencia possui as classes que realizam a conexão e manipulação do
banco de dados. Por exemplo, ao se utilizar o cálculo do preço de venda do método do
SEBRAE, tem-se o seguinte:
Custo da mercadoria = Valor da Mercadoria + IPI + Frete - Valor de crédito a
título de ICMS no Frete + Substituição Tributária - Valor de crédito a título de ICMS Desconto
Inicialmente, executa-se a validação sintática da fórmula e logo após sua
validação semântica. Na semântica, a classe Posfixa utilizando a classe Pilha transforma
a fórmula em pósfixa. Em seguida a classe Arvore, utilizando a classe Nodo, monta uma
árvore semântica e então realiza o acesso ao banco de dados para a procura dos valores
das variáveis. Se alguma destas variáveis não possuir valor no banco de dados, a
fórmula não é semanticamente válida. Em seguida, realizam-se os cálculos nas classes
não terminais para que o resultado seja fornecido ao usuário. Utilizando os seguintes
valores
como
exemplo:
ValordaMercadoria
ValordecreditoatitulodeICMSnoFrete
=
0,5;
= 10;
IPI = 5;
Frete = 1;
SubstituicaoTributaria
=
7;
ValordecreditoatitulodeICMS = 8 e Desconto = 0,2. O resultado fornecido pela
execução do componente do subframework é ilustrado na Figura 6. Na primeira linha,
pode-se ver a expressão sintaticamente correta e na forma pósfixa; na segunda linha, o
resultado.
Figura 6 - Componente de análise semântica – Fórmula de Preço de venda do método
Sebrae (2008)
Neste passo também reusam-se as classes obtidas no Passo 2 que venham a
satisfazer o objetivo do subframework. O diagrama de classes da Figura 5 deixa
explícito quais classes são hot spots para o projetista, pois apresentam o estereótipo
<<Hot spot>>.
PASSO 5 – Voltar ao passo 1, considerando neste momento um outro subsistema.
Ressalte-se que os passos descritos acima foram repetidos para todos os três
subsistemas sob análise. Com isso, pôde-se identificar os subframeworks para o
framework no domínio de formação de preço de venda.
4.3.3
Desenvolvimento das classes
As classes criadas para o desenvolvimento do avaliador semântico podem ser
vistas na Figura 2. Nessa seção descreve-se o código fonte de cada classe. A primeira
classe a ser mostrada foi a ExpAlgebrica. Esta classe abstrata representa a classe
AbstractExpression do padrão Interpreter. O Código 1 mostra a implementação desta
classe.
public abstract class ExpAlgebrica {
// Representa a classe AbstractExpression
public abstract double interpret(Contexto ctx);
}
Código 1 – Classe ExpAlgebrica
A próxima classe são as que representam a classe NonTerminalExpression do
padrão Interpreter. O Código 2 mostra a implementação da classe Somar. As classes
Dividir, Multiplicar, Exponenciar e Subtrair encontram-se no Anexo A.
public class Somar extends ExpAlgebrica {
//Representa a classe NonTerminalExpression
Vector <ExpAlgebrica> operando = new Vector();
public Somar(ExpAlgebrica exp1, ExpAlgebrica exp2){
operando.add(exp1);
operando.add(exp2);
}
public double interpret(Contexto ctx) {
return operando.elementAt(0).interpret(ctx)+operando.elementAt(1).interpret(ctx);}}
Código 2 – Classe Somar
A classe Variavel é a que representa a classe TerminalExpression do padrão
Interpreter. Esta classe será instanciada toda vez que na fórmula for encontrada uma
variável ou uma constante. O Código 3 mostra a implementação desta classe.
public class Variavel extends ExpAlgebrica {
//Representa a classe TerminalExpression
private String nome;
public Variavel(String nome){
this.nome=nome;
}
public double interpret (Contexto ctx){
return ctx.lookup(nome);
}
public String getNome() {
return nome;
}}
Código 3 – Classe Variavel
A classe Contexto representa a classe Context do padrão Interpreter. O Código 8
mostra a implementação desta classe.
public class Contexto {
private Map terminalExpressions = new HashMap();
public double lookup (String nome){
return ((Double) terminalExpressions.get(nome)).doubleValue();
}
public void assign (Variavel exp, double val){
terminalExpressions.put(exp.getNome(), new Double(val));
}
}
Código 4 – Classe Contexto
A classe Cliente representa a classe Client do padrão Interpreter. O Código 5
mostra a implementação desta classe.
public class Cliente {
static Contexto contexto = new Contexto();
static ExpAlgebrica expressa;
public static ExpAlgebrica preOrdem(Nodo raiz) {
if (raiz != null) {
if ((raiz.getDado().toString().equals("+"))) {
expressa = new Somar(preOrdem(raiz.getDir()), preOrdem(raiz.getEsq()));
return expressa;
}
if ((raiz.getDado().toString().equals("-"))) {
expressa = new Subtrair(preOrdem(raiz.getDir()), preOrdem(raiz.getEsq()));
return expressa; }
if ((raiz.getDado().toString().equals("*"))) {
expressa = new Multiplicar(preOrdem(raiz.getDir()),preOrdem(raiz.getEsq()));
return expressa; }
if ((raiz.getDado().toString().equals("^"))) {
expressa = new Exponenciar(preOrdem(raiz.getDir()),preOrdem(raiz.getEsq()));
return expressa;}
if ((raiz.getDado().toString().equals("/"))) {
expressa = new Dividir(preOrdem(raiz.getDir()), preOrdem(raiz.getEsq()));
return expressa;
} else {
ExpAlgebrica x = new Variavel(raiz.getDado());
contexto.assign((Variavel) x, raiz.getValor());
return x;
}}
return null;}
public static void main(String args[]) {
String expressao;
Arvore arvore = new Arvore();
PosFixa posfixa = new PosFixa();
try {
File f = new File("C:\\Users\\Rodolfo\\Desktop\\exp.txt");
BufferedReader in = new BufferedReader(new FileReader(f));
expressao =in.readLine();
arvore.inserir(posfixa.convertePosfixa(expressao));
preOrdem(arvore.getRaiz());
double result =expressa.interpret(contexto);
System.out.println("Resultado = " +result);
} catch (Exception e) {
e.printStackTrace(); }}}
Código 5 – Classe Cliente
4.4
4.4.1
UNIFICAÇÃO DOS AVALIADORES SINTÁTICO E SEMÂNTICO
Analisador sintático
Consiste em analisar uma determinada sentença utilizando-se de duas etapas:
Análise léxica e Análise sintática.
A Análise Léxica, ou scanner, consiste em separar e identificar os componentes
de uma determinada linguagem, eliminando alguns elementos não relevantes, como:
espaços em branco, marcas de formatação de texto, comentários, entre outros.
Após a realização da Análise Léxica, o resultado é um conjunto de tokens, ou
lexemas, que correspondem ao código fonte original, porém representado por um
conjunto de símbolos. Um exemplo é ilustrado no Código 6 (RICARTE, 2003):
1 int a, b, valor;
2 a = 10; b = 20;
3 valor = a * (b + 20);
Código 6 – Código-Fonte exemplo.
Aplicando a Análise Léxica no Código 6 obtém-se um conjunto de tokens
visualizado na Tabela 4 (RICARTE, 2003).
Tabela 4 – Tokens resultantes da Análise Léxica.
N token
Valor token
N token
Valor token
1
Int
14
20
2
A
15
;
3
,
16
Valor
4
B
17
=
5
,
18
A
6
Valor
19
*
7
;
20
(
8
A
21
B
9
=
22
+
10
10
23
20
11
;
24
)
12
B
25
;
13
=
Para que o compilador consiga realizar a Análise Léxica, ele precisa saber quais
são os tokens válidos da linguagem, assim como suas palavras chaves e regras para
formatação de identificadores. Através desses dados, pode-se identificar a qual tipo
esses tokens pertencem, por exemplo, se é do tipo inteiro, identificador, variável,
operador, entre outros, de acordo com a linguagem analisada. Os erros encontrados
nesta etapa da compilação podem ser, por exemplo: um caractere não presente na
gramática da linguagem.
A Análise Sintática, ou parsing, é a fase responsável por verificar se um
agrupamento de tokens, obtidos pela Análise Léxica, é válido para a linguagem
analisada. Para que essa tarefa seja realizada é utilizada a gramática que define uma
sintaxe válida a ser analisada. Um exemplo de gramática válida para uma expressão
aritmética é ilustrada no Código 7 (RICARTE, 2003).
1
2
3
4
5
6
EE+T
ET
TTxF
TF
F (E)
F id
Código 7 – Gramática para o reconhecimento de expressões.
Considerando o Código 7, a primeira regra (linha 1) determina que a soma de
uma expressão (E) e um termo (T) é também uma expressão. Pela segunda regra (linha
2), um único termo é também uma expressão. Pela terceira regra (linha 3), o produto de
um termo e um fator (F) é um termo válido. A quarta regra (linha 4), estabelece que um
único fator seja também um termo válido. Pela quinta regra (linha 5), uma expressão
entre parênteses ((E)) é um fator. Finalmente, a sexta regra (linha 6), estabelece que um
identificador (id) seja um fator.
Os erros que podem ser detectados nesta etapa da compilação são, por exemplo:
operador esperado, parêntese aberto e não fechado, seqüência inválida de caracteres. A
Figura 7 ilustra um subframework para validação sintática de fórmulas. As classes que
estão no SubframeworkBase representam os frozen spots e as que estão no
SubframeworkAplicação são os hot spots (HORNUNG, 2008).
Figura 7 - Subframework para análise sintática.
4.4.2
Avaliador Semântico
Segundo Kashyap & Sheth (1992) a semântica é o estudo científico das relações
entre símbolos e sinais e o que eles representam ou significam. A semântica em relação
a uma fórmula é a partir da fórmula dada, ou seja, calcular o resultado desta fórmula.
Um item a ser avaliado na validação semântica da fórmula é a verificação da existência
de valores para todas as variáveis, pois caso uma variável não possua valor a fórmula
não pode ser resolvida e não se pode chegar a um resultado. Outro ponto que deve ser
tratado é impedir a divisão por 0.
O Analisador semântico tem como objetivo verificar se as palavras possuem
algum sentido dentro de um contexto, dando para cada palavra o seu real valor. Após a
realização da Análise Semântica, o resultado é um valor que possui um sentido dentro
do contexto que o analisador está inserido. Um exemplo desta etapa é ilustrada no
Código 8:
Custo da mercadoria = Valor da Mercadoria + IPI + frete - Valor de crédito a título de ICMS no Frete +
Substituição Tributária - Valor de crédito a título de ICMS – Desconto
Código 8 – Fórmula a ser validada.
Para a aplicação da Análise Semântica no Código 8 há a necessidade da
utilização dos valores de cada variável visualizadas na Tabela 5.
Tabela 5 – Tokens resultantes da Análise Léxica.
Variável
Valor
ValordaMercadoria
10
IPI
5
Frete
1
ValordecreditoatitulodeICMSnoFrete
0,5
SubstituicaoTributaria
7
ValordecreditoatitulodeICMS
8
Desconto
0,2
Para que o compilador consiga realizar a Análise Léxica, ele precisa saber quais
são os valores das variáveis. Através de uma pesquisa em banco de dados, pode-se
recuperar o valor de cada variável, para então, realizar as operações. Neste caso, após a
realização da análise semântica chega-se ao valor de 14,3. Os erros encontrados nesta
etapa da compilação podem ser, por exemplo: uma variável sem valor no banco de
dados.
No caso do subframework Verificar semântica, obteve-se o diagrama ilustrado
na Figura 8 e do Verificar sintaxe foi ilustrado na Figura 7. O pacote
validacaoSemantica é o responsável pelo cálculo das variáveis, o de estrutura contém as
estruturas de dados utilizadas para a transformação de uma fórmula infixa para a
pósfixa, além de realizar uma pesquisa no banco de dados e assim conseguir o valor
semântico de cada variável.
Figura 8 - Subframework Verificar semântica
4.4.3
Unificação
A unificação foi realizada em dois passos que serão descritos. O primeiro foi
acoplar ao avaliador semântico o avaliador sintático. Para isso, realizou-se uma cópia
dos pacotes do projeto do avaliador semântico e então colado e refatorado para a pasta
WEB-INF/classes. Após fazer este acoplamento, a árvore do projeto possui todos os
pacotes necessários para a realização da análise semântica, como mostra a Figura 9.
Figura 9 - Árvore do Subframework
O segundo passo consiste em criar uma instância da classe motor do analisador
semântico para que este seja executado caso a análise sintática seja concluída com
sucesso. Para isso, realizou-se uma mudança no arquivo “sucesso.jsp” do analisador
semântico. Nesta página continha uma mensagem de sucesso, que pode ser visto no
Código 9.
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-88591"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
A Fórmula foi informada corretamente!!!
</body>
</html>
Código 9 – Código do arquivo sucesso.jsp antes da modificação.
Na nova página realizou-se primeiramente a instanciação da classe motor do
aplicativo de validação semântica que é a classe Cliente. Após isso, escreve-se na tela a
mensagem “O resultado é:”, e então se faz uma chamada ao método validar para então
obter o resultado da fórmula. O Código 10 mostra como ficou o “arquivo sucesso.jsp”
após a modificação.
<html>
<head>
<title>Concluído</title>
</head>
<body>
<% try{
validacaoSemantica.Cliente cliente = new validacaoSemantica.Cliente();
out.println("<h2>O resultado é:</h2>");
out.println("<h2>"+cliente.validar()+"</h2><br><br>");
}catch (Exception e) {
out.println("<center><h1>"+e.getMessage()+"</h1></center>");
} %>
</body>
</html>
Código 10 – Código do arquivo sucesso.jsp após a modificação.
Com isso finaliza-se a unificação dos subframeworks de analise sintática e
análise semântica.
5
RESULTADOS E DISCUSSÃO
O objetivo principal para a criação do subframework proposto foi a necessidade
de criar um sistema que realizasse a Análise Sintática e Semântica de Fórmulas, sendo
executado em ambiente web e desenvolvido uma linguagem de programação que
permita a portabilidade. O subfrawework difere tanto do compilador Lex quanto do
Yacc, pois suas rotinas foram desenvolvidas em java, linguagem que permite a
portabilidade e a criação de aplicativos web.
O analisador léxico e sintático foi desenvolvido usando JFlex (versão 1.4.1) e
CUP (versão 0.10j). O JFlex é um gerador de Analisadores Léxicos para Java e
implementado em Java. O seu objetivo é gerar uma rotina em Java, ou seja, uma classe
que contenha as especificações léxicas válidas para a linguagem. Essa classe é gerada a
partir de um arquivo, criado pelo usuário, que contém as especificações léxicas válidas
para a linguagem que se deseja criar. O CUP (Constructor of Useful Parsers) é um
gerador de Analisadores Sintáticos LALR (LookAhead Left-Right) para Java. O seu
objetivo, assim como o JFlex, é gerar uma rotina em Java a partir de um arquivo que
contenha a gramática para o qual o analisador sintático será utilizado.
O subframework proposto também difere de alguns softwares tais como: Axiom,
Yacas, Maxima, Eigenmath, entre outros, pois além de ser um aplicativo para web,
aperfeiçoa a interpretação das mensagens retornadas ao usuário. Isso foi um requisito
considerado importante na criação do subframework, pois os aplicativos analisados
apresentam mensagens incompletas, dificultando a sua interpretação e posterior
correção por parte do usuário. Além disso, os aplicativos não podem ser reusados em
uma nova aplicação que necessita de análise sintática, pois são ferramentas específicas.
Outro ponto a ser levado em consideração é que ao usar o subframework em outro
contexto as classes com frozen e hot spots já estão identificados, facilitando o trabalho
do desenvolvedor ao reusá-lo.
Para o analisador semântico, utilizou-se como referência o padrão Interpreter. A
aplicabilidade do padrão é definida quando a gramática a ser interpretada é simples,
como é o caso do analisador semântico. 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 como é o caso da classe Variavel e de expressões não terminas
como o caso da classe Soma ambas vistas na Figura 6.
Este subframework difere aos outros geradores de parse que possuem validação
semântica como o JavaCC (Java Compiler-Compiler), pois está interligado a um banco
de dados, deixando a semântica dinâmica, uma vez que uma variável poderá ter um
significado diferente dependendo do contexto, além de ser um aplicativo web. Após o
desenvolvimento do avaliador semântico, este foi acoplado ao módulo sintático,
permitindo desta forma a unificação dos dois subframeworks.
A Figura 10 ilustra a interface do subframework em que se pode observar um
campo usado para inserir a fórmula, para então acionar o botão “Validar Fórmula”.
Figura 10 - Interface do Subframework.
A Figura 11 mostra o resultado da validação da fórmula inserida na Figura 10.
Nela pode-se observar que a resposta de sucesso é transmitida através do resultado da
fórmula.
Figura 11 – Sucesso na validação da fórmula.
6
CONCLUSÕES
Neste trabalho apresentou-se a utilização da abordagem dirigida por
responsabilidades durante a criação do subframework de análise semântica a partir dos
casos de uso definidos como hot spots e obtidos na etapa de análise do processo de
desenvolvimento de framework.
Após o desenvolvimento do analisador semântico, foi realizada a unificação dos
subframeworks de análise sintática e semântica.
Como resultado do processo proposto, criou-se um subframework que pode ser
utilizado em outra aplicação, pois suas classes frozen e hot spots já estão identificadas.
Contudo, alguns testes no subframework estão sendo feito para identificar sua aplicação
em em outros domínios.
7
REFERENCIAS BIBLIOGRAFICAS
ABREU NETTO, M. T. Padrão de Projeto Interpreter: Projeto de Sistemas de Software. Disponível
em: <wiki.les.inf.puc-rio.br/uploads/3/36/Interpreter.pdf>. Acesso em: 12 maio 2009.
Bass, L., Clements, P., Kazman, R. Software Architecture in Practice, Addison Wesley, 2003.
BAWA, J. Computador E Saúde. São Paulo: Summus, 1997. 232 p.
Bouassida, N.; Ben-Abdallah, H.; Gargouri, F.; Ben-Hamadou, A. F-UML: a design language for
frameworks and its formal specification, International conference on Software Engineering and
Formal Methods (SEFM’2003), Australia, Brisbane, 26-29 September, 2003.
BRAGA, R. T. V.; Masiero, P. C. A process for framework construction based on a pattern
language. In: Annual International CSAC, 26., 2002. Proceedings… Oxford: IEEE, 2002. p. 615-620.
BUTLER, G., XU, L., Cascaded Refactoring for Framework Evolution, In: Proc. SSR’01, May,
Toronto, Ontario, Canada. ACM 1-58113-358-8/01/0005, p. 51-57, 2001.
COGAN, S. Custos e preços: formação e análise. São Paulo: Pioneira, 1999.
CRAZUSKI, A., FEITOSA, L. B., CORDEIRO, T, L. Identificação dos pontos de estabilidade e de
flexibilidade dos métodos para o estabelecimento de preço de venda. 135f. 2008. Trabalho de
Conclusão de Curso – Universidade Tecnológica Federal do Paraná, Ponta Grossa.
FARIAS,
K.
Padrão
de
Projeto
Interpreter.
Disponível
rio.br/uploads/c/cc/Interpreter_20082.ppt>. Acesso em: 11 abr. 2009.
em:
<wiki.les.inf.puc-
FAYAD, M., SCHMIDT, D., JOHNSON, R., Building Application Frameworks – Object-Oriented
Foundations of Framework Design, Wiley, p.688, 1999.
FONTOURA, M.; PREE, W.; RUMPE, B. UML-F: A Modeling Language for Object-Oriented
Frameworks,
2002.
Disponível
em:
<www.almaden.ibm.com/cs/people/fontoura/papers/ecoop2000.pdf>. Acesso em: 03/03/2009
HORNUNG, R.; MATOS, S. N.; FERNANDES, C. T. Aplicando o processo dirigido por
responsabilidades para a criação de um subframework para validação de sintática de fórmulas.
In: 5nd CONTECSI, 5., 2005, São Paulo. Proceedings… FEA/USP, 2008.
JOHNSON, R. E, How to design frameworks, In: Object-Oriented Programming Systems, Languages
and Applications Conference – OOPSLA, Washington Proceedings, 1993.
KASHYAP, V., SHETH, A. (1992) So Far (Schematically) yet So Near (Semantically).
LANDIN, N., NIKLASSON, A., Development of Object-Oriented Frameworks, Department of
Communication System.Lund Institute of Technology, Lund University. Lund, Sweden, 1995.
LEÃO, N. S. Formação de preços de serviços e produtos. São Paulo: Nobel, 2008.
MACORATTI, J. C. Padrões de Projeto - Design
<http://www.macoratti.net/vb_pd1.htm>. Acesso em: 25 jun. 2009.
Patterns.
Disponível
em:
MARTINS, E. Contabilidade de Custo. 6ª ed., São Paulo: Atlas, 2003. p.220.
MATOS, S. N.; FERNANDES, C. T. Using responsibilities for early identification of hot spot reused
in framework modeling. In: IEEE International Workshop on Security, Trust, and Privacy for
Software Applications. 3.. Proceedings… Turku: IEEE Computer Society Press, 2008.
MATTSSON, M. Evolution and composition of object-oriented frameworks. 224f. 2000. PhD Thesis–
University of Karlskrona/Ronneby, Sweden.
METSKER, S. J. Padrões de projeto em Java. Bookman, 2004.
OLIVEIRA NETTO, A. A. IHC – Interação Humano Computador: Modelagem e Gerencia de
Interfaces. Florianópolis: Visualbooks, 2004. 120 p.
PREE, W. Hot-spot-driven development. In: Fayad, M.; Johnson, R.; Schmidt, D. Building application
frameworks: object-oriented foundations of framework design. NY: John Wiley and Sons, 1999. p.
379-393.
PARIS, M., Reuse-based Layering: a Strategy for Architectural Framework for Learning
Technologies, In: IEEE Conferece on Advanced Learning Technologies (ICALT’04), 2004.
RICARTE, I. L. M. Programação de Sistemas: Uma Introdução. São Paulo, 2003. 188 páginas. Apostila
de Programação de Sistemas – Universidade Estadual de Campinas.
SEBRAE.
Cálculo
do
Preço
de
Venda.
Disponível
em:
<http://www.sebraesp.com.br/principal/abrindo%20seu%20neg%C3%B3cio/produtos%20sebrae/artig
os/listadeartigos/preco_venda.aspx> Acesso em 29 de junho de 2009.
SHALLOWAY, A.; TROTT, J. R. Explicando Padrões de Projeto: Uma nova perspectiva em projeto
orientado a objeto. Bookman, 2004.
SHNEIDERMAN, B.; PLAISANT, C. Designing the User Interface: Strategies for Effective HumanComputer Interaction. Addison-Wesley, Fourth edition, 2004. 136 p.
SILVESTRE, W. C. Sistema de custos ABC: uma visão avançada para tecnologia de informação e
avaliação de desempenho. São Paulo: Atlas, 2002.
TALIGENT, Building object-oriented frameworks, Taligent Inc.white paper, 1994.
TANG, A., HAN, J., CHEN, P., A Comparative Analysis of Architecture Frameworks, In:
Proceedings of the 11th Asia-Pacific Software Engineering Conference (APSEC´04), 2004.
WIRFS-BROCK, R., MCKEAN, A, Object Design: Roles, Responsabilities, and Collaborations,
Addison Wesley, 2003.
APÊNDICE A
Os códigos da classe para dividir, potenciação, subtrair e multiplicar estão
listados a seguir.
public class Divide extends ExpAlgebrica {
Vector <ExpAlgebrica> operando = new Vector();
public Somar(ExpAlgebrica exp1, ExpAlgebrica exp2){
operand.add(exp1);
operand.add(exp2);
}
public double interpret(Contexto ctx) {
return perand.elementAt(0).interpret(ctx)/operand.elementAt(1).interpret(ctx);
}
}
public class Potencia extends ExpAlgebrica {
Vector <ExpAlgebrica> operando = new Vector();
public Somar(ExpAlgebrica exp1, ExpAlgebrica exp2){
operando.add(exp1);
operando.add(exp2);
}
public double interpret(Contexto ctx) {
return
Math.pow(operando.elementAt(0).interpret(ctx),
operando.elementAt(1).interpret(ctx));
}
}
public class Subtrai extends ExpAlgebrica {
Vector <ExpAlgebrica> operando = new Vector();
public Somar(ExpAlgebrica exp1, ExpAlgebrica exp2){
operando.add(exp1);
operando.add(exp2);
}
public double interpret(Contexto ctx) {
return operando.elementAt(0).interpret(ctx)-operando.elementAt(1).interpret(ctx);
}
}
public class Multiplica extends ExpAlgebrica {
Vector <ExpAlgebrica> operando = new Vector();
public Somar(ExpAlgebrica exp1, ExpAlgebrica exp2){
operando.add(exp1);
operando.add(exp2);
}
public double interpret(Contexto ctx) {
return operando.elementAt(0).interpret(ctx)*operando.elementAt(1).interpret(ctx);
}
}
O artigo publicado durante a pesquisa está referenciado a seguir.
SILVA, R., MALAQUIAS, F. H., BORGES, H. B., MATOS, S. N., ISHIKAWA, E. C. M. Aplicando
Coleção Welie e Utilizando Arquivo de Texto para o Desenvolvimento e Atualização de um Sítio
Interativo para Web. In: VI CONGED, 2008, Curitiba.