Escolar Documentos
Profissional Documentos
Cultura Documentos
net/publication/324493041
CITATIONS READS
0 1,890
5 authors, including:
Some of the authors of this publication are also working on these related projects:
All content following this page was uploaded by Regis Pires Magalhaes on 13 April 2018.
Abstract
This chapter covers methodologies, languages, tools and artifacts carefully chosen
to motivate students to exercise best practices in software development, supported by
Software Engineering and Agile Methodologies to the construction of Software as a
Service (SaaS). Concepts related to software architecture, testing, modularity and reuse
are presented in theory and practice through analysis of a web application built for
teaching purposes using Java language and Play Framework.
Resumo
Este capítulo aborda metodologias, linguagens, ferramentas e artefatos
cuidadosamente selecionados para motivar os alunos a exercerem as melhores
práticas de desenvolvimento de software, apoiadas na Engenharia de Software e em
Metodologias Ágeis para a construção de Software como Serviço (SaaS). Conceitos
relacionados à arquitetura de software, testes, modularidade e reuso são apresentados
de forma teórica e prática através da análise de uma aplicação web construída para
fins didáticos usando a linguagem Java e o Play Framework.
1.1. Introdução
Nas seções posteriores serão detalhados alguns pontos acima citados, como
processos de desenvolvimento, testes de software, SaaS, arquitetura MVC e computação
em nuvem. Além disso, serão abordados conteúdos relativos à utilização de sistemas de
controle de versão no processo de desenvolvimento de software e também implantação
na infraestrutura de nuvem.
Figura 3. Modelo de software silo para serviços de uma livraria [Fox e Patterson 2012].
O silo forma internamente subsistemas que podem compartilhar acessos a
dados diretamente nos diferentes subsistemas. Perceba que todos os subsistemas
estão contidos em uma API externa única. Com isso, o subsistema de comentários
pode acessar informações fora do seu contexto de forma direta, como por exemplo no
subsistema de perfis de usuários.
Já a figura 4 exibe o mesmo sistema, mas agora com a versão SOA, onde todos
os subsistemas são separadas e independentes.
Figura 4. Modelo SOA para serviços de uma livraria [Fox e Patterson 2012].
Notamos agora que se o subsistema de comentários necessitar de informações de
um usuário, então ele não poderá recuperá-la diretamente na base de dados dos usuários
e para isso ele deverá usar o serviço da API. Essa é exatamente a diferença crítica
entre os dois modos. Notamos com isso que a SOA possibilita várias fatias verticais
com diversas camadas e cada uma das fatias está conectada por meio de serviços,
proporcionando bastante reusabilidade.
2 http://www.farmville.com/
3 http://aws.amazon.com/ec2/
4 http://developers.google.com/appengine/
5 http://www.windowsazure.com/
O modelo de PaaS fornece um sistema operacional, linguagens de programação
e ambientes de desenvolvimento para as aplicações, auxiliando a implementação
de softwares, já que contém ferramentas de desenvolvimento e colaboração entre
desenvolvedores. O usuário não administra ou controla a infraestrutura subjacente, mas
tem controle sobre as aplicações implantadas e, possivelmente, sobre as configurações
de aplicações hospedadas nesta infra-estrutura. Heroku6, Google App Engine7 e Aneka8
são exemplos de PaaS.
O modelo de IaaS torna mais fácil e acessível o fornecimento de recursos, tais
como servidores, rede, armazenamento e outros recursos de computação fundamentais
para construir um ambiente de aplicação sob demanda, que podem incluir sistemas
operacionais e aplicativos. Em geral, o usuário não administra ou controla a infra-
estrutura da nuvem, mas tem controle sobre os sistemas operacionais, armazenamento
e aplicativos implantados. Os recursos disponibilizados pela IaaS são geralmente
virtualizados. O Amazon Elastic Cloud Computing (EC2)9 e o Elastic Utility Computing
Architecture Linking Your Programs To Useful Systems (Eucalyptus)10 [Liu et al. 2007]
são exemplos de IaaS.
6 http://www.heroku.com/
7 https://developers.google.com/appengine/
8 http://www.manjrasoft.com/products.html
9 http://aws.amazon.com/ec2/
10 http://www.eucalyptus.com/
● SaaS naturalmente fornece um ambiente propício ao compartilhamento, edição e
manipulação coletiva dos dados.
● O software servidor é executado em um ambiente com hardware e sistema
operacional controlados e selecionados pelo desenvolvedor, evitando problemas
de compatibilidade relacionadas à instalação de software em uma grande
variedade de computadores e sistemas operacionais. Além disso, é possível
disponibilizar novas versões da aplicação apenas para um grupo restrito de
usuários que podem testá-la para descobrir potenciais problemas antes de uma
disponibilização mais ampla que afetaria a maioria dos usuários.
● O uso de um ambiente controlado para execução de SaaS possibilita a realização
de atualizações mais frequentes de software e hardware. A possibilidade de
atualizações frequentes alinha-se perfeitamente ao ciclo de vida de softwares
desenvolvidos através de metodologias ágeis. Assim, novos recursos podem ser
disponibilizados regularmente para evitar que os usuários migrem para serviços
concorrentes. Além disso, evita a pirataria ou cópia ilegal do software, já que o
usuário usa a aplicação remotamente e não tem acesso ao código que está sendo
executado.
● Possibilidade de cobrar um valor periódico ou baseado na demanda de uso do
software.
Essas vantagens explicam o motivo do rápido crescimento de SaaS e
também porque estão sendo desenvolvidas versões SaaS para softwares tradicionais.
Um exemplo disso é a versão SaaS dos populares aplicativos de escritório Word,
Excel e PowerPoint da Microsoft (Microsoft Office 365)11. No entanto, aplicações
desenvolvidas como SaaS requerem acesso à Internet, o que pode restringir seu uso
em determinadas situações. Para atenuar esse problema, algumas aplicações SaaS
têm possibilitado a alternativa de permitir sua execução offline, o que, por outro lado,
aumenta a complexidade do desenvolvimento, por exigir um certo controle sobre o
que está sendo manipulado na máquina cliente e que precisará ser posteriormente
sincronizado com a versão online, assim que isso for possível.
Vários frameworks voltados para programação Web permitem o
desenvolvimento de SaaS. Neste capítulo ilustramos os conceitos abordados através de
exemplos implementados usando o Play Framework12, que foi concebido no intuito de
facilitar o desenvolvimento através do uso de metodologias Ágeis. Isso ocorre porque
ele se alinha ao ciclo de vida ágil. Além disso, o framework permite que a codificação
seja realizada na amplamente difundida linguagem Java, tendo como pré-requisito para
criação das primeiras aplicações Web, apenas o conhecimento do Java SE (Standard
Edition) e da arquitetura Modelo-Visão-Controlador (MVC). A baixa curva de
aprendizagem torna o framework propício para ilustrar os conceitos de engenharia de
software para o desenvolvimento de SaaS. Além disso, as aplicações implementadas a
partir deste framework podem ser facilmente disponibilizadas em modelos de
Plataforma como Serviço (PaaS), como o Google App Engine13 e o Heroku14. Também
é possível disponibilizá-las no modelo de Infra-estrutura como Serviço (IaaS), usando o
serviço Amazon Elastic Cloud Computing (EC2), por exemplo.
11 http://www.office365.com/
12 http://www.playframework.org/
13 http://appengine.google.com/
14 http://www.heroku.com/
Esta seção mostrou como SaaS tem causado alterações substanciais em relação
ao desenvolvimento tradicional de software. A seção a seguir trata da arquitetura
Modelo-Visão-Controlador que é amplamente difundida em aplicações de SaaS.
1.6.1. Modelo
A camada de modelo contem a lógica da aplicação e representa especificamente as
informações que serão apresentadas em formulários da camada de visão com que a
aplicação trabalha. A maioria das aplicações usa um mecanismo de armazenamento de
dados permanente, como um banco de dados, para guardar e recuperar as informações
necessárias à camada de modelo, apresentando também as anotações JPA para a
manipulação desses mesmos dados. A Figura 6 apresenta um modelo chamado Pessoa,
que permite o acesso a dados de uma tabela de nome pessoas.
package models;
import java.util.Date;
import javax.persistence.*;
import play.data.validation.Required;
import play.db.jpa.*;
@Entity(name="pessoas")
public class Pessoa extends Model {
@Column(length=50)
@Required
public String nome;
@Column(length=10)
public String fone;
@Temporal(TemporalType.DATE)
@Column(name="dt_nasc")
public Date dtNasc;
@Override
public String toString() {
return nome + " - " + fone + " - " + dtNasc;
}
}
Figura 6. Modelo Pessoa (app/models/Pessoa.java)
Essa camada é responsável pelo acesso a banco de dados, deixando as
informações prontas, o controlador requisita essas informações levando-as para a
camada de visão, onde serão exibidas na template correta. O modelo não possui
conhecimento de quais serão as interfaces com usuário que serão utilizadas.
Recomenda-se como boa prática de programação relativa à arquitetura MVC,
que os controladores possuam pouco código e que os modelos possam ter códigos
maiores [Chelimsky et al. 2010]. A responsabilidade do controlador é somente a de
receber entradas e fazer chamadas ao modelo para obter os dados que preencherão a
visão. Assim, o controlador basicamente fica responsável apenas por instanciar algumas
classes, obter dados dos modelos e enviá-los à visão adequada. Por outro lado, os
modelos realizam manipulação, validação e filtragem de dados.
package controllers;
import play.*;
import play.data.validation.Valid;
import play.mvc.*;
import java.util.*;
import models.*;
# Routes
# Home page
GET / Application.index
GET /pessoa/{id} Application.show({id})
# Map static resources from the /app/public folder to the /public path
GET /public/ staticDir:public
# Catch all
* /{controller}/{action} {controller}.{action}
Figura 8. Arquivo conf/routes
A seguir, mostramos um exemplo de URI para exibir informações sobre a pessoa cujo
id é 1: http://localhost:9000/pessoa/1. O número 1 da URI corresponde ao {id} da
regra “GET /pessoa/{id} Application.show({id})”
Ainda sobre a figura 8, podemos notar que cada rota consiste em três blocos de
informações: O método HTTP; Padrão URI; Definição de chamada.
● O método HTTP pode ser qualquer método válido e suportado pelo protocolo
HTTP, como por exemplo: GET, POST, PUT e DELETE;
● Uma URI define o endereço de solicitação da rota, podendo ter ou não
parâmetros passados pela URL. Essas partes dinâmicas são variáveis provindas
do controlador, onde cada parte dinâmica deve ser escrita entre chaves {...}
● As definições de chamadas constituem a última parte da rota, sendo compostas
pelo nome do controlador e da ação a ser executada.
Em última instância, há o REST (Representational State Transfer) [Fielding
2000], ou em português, Transferência de Estado Representacional, que descreve uma
arquitetura de software para aplicações WEB que requisitam e manipulam recursos
WEB, usando os métodos do protocolo HTTP já citados acima. Cada recurso REST é
uma entidade acessível a partir de uma URL que oferece interação via HTTP, onde os
recursos podem ser apresentados em diferentes formatos, como HTML, RSS, XML,
PDF, etc. Dependendo exclusivamente da URL requisitada pelo cliente.
REST afirma alguns princípios chave de desenvolvimento:
● A funcionalidade da aplicação é divida em recursos.
● Cada recurso é endereçado unicamente usando URIs.
● Todos os recursos partilham uma interface uniforme para a transferência de
estado entre cliente e recurso.
Se uma aplicação segue os princípios de desenvolvimento REST, a aplicação é
denominada RESTful e passa a possuir URLs limpas, desde que a simples identificação
do recurso na URI, juntamente com o método HTTP usado na requisição, são
suficientes para determinar que ação deve ser tomada sobre o recurso. Twitter,
Facebook, Foursquare e muitos outros serviços utilizam REST. Webservices têm
ganhado cada vez mais atenção, não apenas pelo seu grande uso na criação de APIs,
mas também por causa da simplicidade de consumir e publicar um serviço RESTful
[Pautasso et al. 2008].
1.6.3. Visões
Uma visão é um componente usado para exibir dados de um modelo. Uma visão não
deveria realizar lógica de negócio ou obter dados além dos disponíveis no modelo.
Assim, múltiplas visões podem representar o mesmo modelo, sem interferir no
comportamento da aplicação. Um exemplo disso seria a existência de duas visões
para os mesmos dados: uma delas apresentando-os de forma tabular e a outra visão
mostrando uma representação gráfica dos mesmos dados.
A visão não deve fazer manipulação ou recuperação de dados, como por
exemplo interações com o Banco de Dados. Ao invés disso, deve meramente exibir
dados de um ou mais modelos. Por outro lado, a visão realiza a lógica de apresentação,
que é bem diferente de lógica de controle e de negócio. Um exemplo de lógica de
apresentação é o uso da cor vermelha para visualização de valores numéricos, caso eles
sejam negativos.
A visão é constituída por alguma tecnologia que permita a geração ou
visualização da interface com o usuário. Uma dessas tecnologias consiste no uso de
templates, associado a uma linguagem simples para manipulação e preenchimento
adequado das templates. Diversos frameworks voltados para o desenvolvimento Web,
inclusive o Play Framework, usam templates para a construção de visões.
Uma template é um arquivo texto, onde são escritos os códigos em HTML que
irão constituir o corpo da página na WEB, como também os elementos dinâmicos da
template. Esss elementos normalmente são parâmetros ou variáveis fornecidos pelo
controlador.
Exemplo de um uma visão em que é possível fazer uma listagem:
#{extends 'main.html' /}
#{set title:'Contatos - Listagem' /}
<table>
<tr>
<th>Nome</th>
<th>Telefone</th>
<th>Data de Nascimento</th>
</tr>
#{list pessoas, as:'p'}
<tr>
<td>${p.nome}</td>
<td>${p.fone}</td>
<td>${p.dtNasc}</td>
</tr>
#{/list}
</table>
Figura 9. Visão app/views/Application/index.html
Perceba que na figura 9, a lógica da aplicação não se encontra na visão,
encontramos na visão apenas o manuseio dos dados de forma a facilitar uma
visualização. No início da visão é colocado o layout em que essa visão se encontra,
é possível também colocarmos o título para a página. É importante ressaltar que as
visões devem ser implementadas de modo a possibilitar boa visualização em diferentes
dispositivos.
#{extends 'main.html' /}
#{set title:'Contatos - Visualização' /}
<p>Nome: ${p.nome}</p>
<p>Telefone: ${p.fone}</p>
<p>Data de Nascimento: ${p.dtNasc}</p>
Figura 10. Visão app/views/Application/show.html
Na figura 10, temos uma visualização simples de um contato, nesta visão temos
que o id do contato foi passado como parâmetro pela URL e então temos o objeto
Contato na variável p e então seus dados podem ser acessados como no exemplo.
1.7. Testes
A grande maioria das pessoas já teve alguma experiência com um
software que não funcionou como esperado. Softwares que não funcionam
corretamente podem levar a muitos problemas, incluindo financeiro, tempo
e reputação das empresas. Podendo, inclusive, chegar a influenciar na
integridade das pessoas [ISTQB 2011].
Figura 11. Estrutura de uma classe de teste usando o framework JUnit (http://
www.devmedia.com.br/imagens/javamagazine/mpjuiiujfig10.jpg)
É importante ressaltar que pesquisas revelam que 58% de bugs em software
resultam de problemas com infra-estrutura de testes e processos, e não de falhas de
projeto. Elas apontam também que ambientes em que os testes são completamente
automatizados ainda são raros e, inclusive, existem locais em que a totalidade dos testes
é feita de maneira manual [Fox e Patterson 2012]. Estimamos que isso ocorra pelo
simples fato de que testar é muito caro em relação ao tempo, podendo tomar mais de
50% do prazo do projeto.
Para incentivar a cultura de testes automatizados de software e garantia de
qualidade, nasceram abordagens como o TDD (Testing-Driven Development) e BDD
(Behavior-Driven Design). Em uma tradução livre, TDD seria Desenvolvimento
dirigido por testes e BDD Projeto guiado por comportamento.
O TDD é caracterizado pelos seguintes passos:
● Os testes relativos à determinadas características são escritos antes mesmo da
funcionalidade estar codificada. Neste momento os testes irão falhar.
● O código é construído de modo a fazer todos os testes executarem com sucesso,
mesmo que não seja feito da maneira mais correta e completa.
● Feito isso, objetivando transformar o código em algo mais legível, padronizado
e completo, é feita uma refatoração e os testes devem continuar executando sem
erros.
15 http://junit.org/
16 http://seleniumhq.org/
● Todo o processo é repetido com outra funcionalidade ou, simplesmente,
adicionam-se mais testes.
Para exemplificar o TDD, imaginemos a implementação de uma funcionalidade
que receba dois números e retorne a soma deles. Seguindo os passos acima, criaríamos
a classe CalculoTest e também o método de teste testExecutaCalculo, que invoca
a funcionalidade executaCalculo da classe Calculo. Passaríamos como parâmetro
os números 10 e 5 e esperaríamos que o retorno fosse 15. Passaríamos também os
parâmetros 11 e 10 para esperarmos o número 21 como resposta. Como inicialmente
este método retornaria sempre zero, então ao executarmos o teste, este falharia. O
próximo passo é implementar o código de forma que esses testes não falhem. Após isso
podemos refatorar o método executaCalculo para que fique o mais legível possível.
Os testes devem continuar funcionando e, por fim, ou adicionaríamos mais testes
com outros parâmetros, ou criaríamos uma nova funcionalidade. Vale frisar que todo
o processo é repetido até que todas as unidades de código sejam consideradas como
testadas.
Direcionando agora para o BDD podemos fazer as seguintes considerações [Fox
e Patterson 2012]:
● BDD faz perguntas sobre comportamentos antes e durante o desenvolvimento,
visando reduzir falhas na comunicação dentro do projeto.
● Requisitos são escritos como estórias de usuários. São criadas descrições
simples de como a aplicação deve ser utilizada.
● BDD se concentra no comportamento da aplicação versus a implementação da
aplicação e os testes são conduzidos utilizando TDD.
17 http://hashrocket.com/
identificador. Então, pode-se usar esse número para representar o branch onde ficará
a implementação da nova funcionalidade. No exemplo a seguir, a variável ATUAL
contém o valor numérico do identificador da funcionalidade.
Basicamente as operações funcionam como scripts contendo uma pequena
sequência de comandos GIT:
● Hack: cria o branch que terá apenas as alterações referentes a uma determinada
funcionalidade.
git checkout master
git pull origin master
git checkout -b $ATUAL master
● Sink: Sincroniza o repositório atual da funcionalidade com o repositório origin.
Com isso, antes do envio das alterações, checa-se se o código será bem aceito,
isto é, se ele não gerará erros ao ser integrado com as demais funcionalidades
existentes. Isso pode ocorrer quando algum desenvolvedor efetua alterações
antes de outro, em um mesmo trecho de código.
git checkout master
git pull origin master
git checkout $ATUAL
git rebase master $ATUAL
● Ship: Faz um merge do branch atual da funcionalidade com o master, e envia as
alterações para o repositório origin.
git checkout master
git merge --squash $ATUAL
git commit -a -v
git push origin master
Agora serão descritos os momentos ideais para cada uma dessas operações.
Inicialmente, quando uma funcionalidade é atribuída ao desenvolvedor, deve-se evitar
que as alterações necessárias para implementá-la não causem problemas ao código
anterior. Assim, executa-se o hack, fazendo um branch somente para a funcionalidade.
Para testar, sincroniza-se executando o sink. Se todos os testes passarem, a
funcionalidade foi integrada com sucesso ao código anterior da aplicação e, então, ela
pode ser integrada juntamente com o restante da aplicação, que se encontra remota.
Depois disso, faz-se um ship para que o código seja enviado.
O fluxo Hack-Sink-Ship é muito simples de ser implementado e pode simplificar
bastante o desenvolvimento em equipe. Aliando esse fluxo de trabalho a serviços de
integração contínua, pode-se monitorar e obter total controle sobre o código. Ressalta-se
ainda que a adoção desse fluxo permite que o desenvolvedor se dedique mais a outras
tarefas, como testes, por exemplo. Além disso, após a execução bem sucedida do fluxo,
pode-se realizar os testes para ter a certeza de que a aplicação funciona com a novas
contribuições dos demais membros da equipe de desenvolvimento.
A seguir, sugerimos um fluxo de trabalho mais completo, que se integra às
práticas supracitadas de uso do hack-sink-ship:
1. Inicie a funcionalidade a ser implementada.
2. Faça um hack, criando um branch para sua funcionalidade.
3. Escreva os testes.
4. Valide a implementação com os testes escritos.
5. Repita os passos 3 e 4 até que a funcionalidade esteja completa.
6. Faça um sink, sincronizando com alguma eventual alteração feita no origin,
posterior a sua versão do sistema.
7. Envie suas alterações através da execução do ship.
Portanto, vimos que a utilização desse fluxo de trabalho para o desenvolvimento
ágil de uma forma geral pode ser bem empregado, facilitando a forma de enviar
alterações, assim como a sincronização das mesmas. Essa é apenas uma proposta que
achamos conveniente utilizar, podendo ocorrer variações da mesma.
1.10. Conclusão
A forma como o mercado de software desenvolveu-se e a presença de sistemas
computacionais em quase todos os dispositivos de nosso cotidiano, desde alguns dos
mais simples aparelhos celulares até o mais complexo controlador de tráfego aéreo,
fez com que a indústria de desenvolvimento de software focasse cada vez mais na
qualidade e eficiência de seus produtos. Uma das maneiras de se garantir a qualidade
de um produto de software é a utilização da Engenharia de Software. Contudo, além da
qualidade, os clientes buscam rapidez na entrega dos produtos e a evolução da internet
como um meio de serviço leva os desenvolvedores ao uso de Metodologias Ágeis para a
construção de software robusto e com garantias de boa qualidade.
Diante da necessidade de um desenvolvimento de software mais dinâmico e
eficiente, este capítulo apresentou uma proposta de uso da arquitetura MVC e do
modelo de Software como Serviço (SaaS), uma vez que ambos viabilizam agilidade no
desenvolvimento e melhor interação do usuário com o sistema. O grande crescimento
da Internet e os custos cada vez mais baixos de serviços de computação em nuvem
viabilizam um enorme crescimento do número de aplicações que seguem o modelo de
SaaS. Apenas o uso de metodologias não garante a qualidade do produto final. Manter a
cultura dos testes de software é tão importante quanto o correto uso da Engenharia de
Software durante a construção da aplicação para garantir que o dinamismo das
exigências dos usuários sejam satisfatoriamente atendidas.
O capítulo abordou algumas das principais técnicas da Engenharia de Software
vinculadas ao desenvolvimento ágil como um incentivo aos novos desenvolvedores a
perpetuarem as melhores práticas de desenvolvimento de software, garantindo sempre
eficiência na entrega e qualidade no produto final.
Referências
Armbrust, M., Fox, A., Griffith, R., Joseph, A. D., Katz, R., Konwinski, A., Lee, G.,
Patterson, D., Rabkin, A., Stoica, I., and Zaharia, M. (2010). “A view of cloud
computing”. Commun. ACM, 53(4):50–58.
Beck, K., et al. (2001). "Manifesto for Agile Software Development". Agile Alliance.
http://agilemanifesto.org/. Acessado em 18 de agosto de 2012.
Brantner, M., Florescu, D., Graf, D., Kossmann, D., and Kraska, T. (2008). “Building a
database on s3”. In Proceedings of the 2008 ACM SIGMOD international conference
on Management of data - SIGMOD ’08, page 251, New York. ACM Press.
Chelimsky, D., Astels, D., Helmkamp, B., North, D., Dennis, Z., and Hellesoy, A.
(2010). “The RSpec Book: Behaviour Driven Development with Rspec, Cucumber,
and Friends”. Pragmatic Bookshelf Series. Pragmatic Bookshelf.
David C., Dave A., Zach D., Aslak H., Bryan H., Dan N. (2010) “The RSpec Book:
Behaviour Driven Development with RSpec, Cucumber, and Friends”, Pragmatic
Bookshelf, 2010.
Fielding, R. (2000). “Architectural Styles and the Design of Network-based Software
Architectures”. PhD thesis, University of California, Irvine.
Fox, A., Patterson, D. (2012). “Engineering Long-Lasting Software: An Agile Approach
Using SaaS and Cloud Computing”, Alpha Edition. Strawberry Canyon LLC, 2012.
Hoelzle, U. and Barroso, L. A. (2009). “The Datacenter as a Computer: An Introduction
to the Design of Warehouse-Scale Machines”. Morgan and Claypool Publishers, 1st
edition.
ISTQB. (2011). Certified Tester Foundation Level Syllabus, version 2011.
Liu, C. (1996). “Smalltalk, objects, and design”. Prentice-Hall, Inc., Upper Saddle
River, NJ, USA.
Liu, S., Liang, Y., and Brooks, M. (2007). Eucalyptus: a web service-enabled e-
infrastructure. In CASCON ’07: Proceedings of the 2007 conference of the center
for advanced studies on Collaborative research, pages 1–11, New York, NY, USA.
ACM.
Paula Filho, W. P. (2006). “Engenharia de Software: fundamentos, métodos e padrões”,
3 ed. Rio de Janeiro: LTC, 2006.
Pautasso, C., Zimmermann, O., and Leymann, F. (2008). “Restful web services
vs. "big"’ web services: making the right architectural decision”. In Proceedings of
the 17th international conference on World Wide Web, WWW ’08, pages 805–814,
New York, NY, USA. ACM.
Pressman, R. S. (2005). “Software engineering: a practitioner’s approach”, 6 ed. New
York: MacGraw-Hill, 2005.
Serman, D. V. (2010). “Orientação a projetos: uma proposta de desenvolvimento de
uma arquitetura orientada a serviços”. JISTEM: Journal of Information Systems and
Technology Management, Sin mes, 619-638.
Sousa, F. R. C., Moreira, L. O. e Machado, J. C. (2009). “Computação em Nuvem:
Conceitos, Tecnologias, Aplicações e Desafios”. In: Santos Neto, P. (Org.). III
Escola Regional de Computação Ceará - Maranhão - Piauí, ERCEMAPI 2009, 1 ed.
SBC, Piauí.
Sousa, F. R. C., Moreira, L. O., Macedo, J. A. F. e Machado, J. C.
(2010). “Gerenciamento de Dados em Nuvem: Conceitos, Sistemas e Desafios”. In:
XXV Simpósio Brasileiro de Banco de Dados, 2010, Belo Horizonte. SBBD 2010.