![Page 1: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/1.jpg)
Projeto de API
Gilmar P. S. Leitão @gilmatryx
![Page 2: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/2.jpg)
¡ Aprendendo § Definições e conceitos
¡ Programando § Iniciando um projeto de API § Princípios de projeto § Projeto de classes
¡ Integrando
![Page 3: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/3.jpg)
¡ APRENDENDO
![Page 4: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/4.jpg)
¡ Web (SOAP, REST, etc) ¡ SO (Unix, Windows, etc) ¡ Linguagens de Programação (C++, Java, etc) ¡ Protocolos (Java – RMI à IIOP)
![Page 5: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/5.jpg)
É uma coleção de: § Funções, Classes, Tipos de Dados § Eventos, Protocolos, Arquivos, etc.
Onde temos um sistema Que se comunica Com outro Através dessas Coleções
![Page 6: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/6.jpg)
É uma coleção de: • Funções, Classes, Tipos de Dados • Eventos, Protocolos, Arquivos, etc.
Onde temos um sistema Que se comunica Com outro Através dessas Coleções
Biblioteca, Componente, Framework, Sistema Operacional, Recurso na Web, Etc.
![Page 7: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/7.jpg)
¡ Application Programming Interface
![Page 8: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/8.jpg)
![Page 9: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/9.jpg)
Se você programa, então você provavelmente trabalha com módulos ou pelo menos deveria. Bons programas são modulares e cada módulo deve ter uma API. Pensar em termos de API melhora a qualidade do código.
![Page 10: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/10.jpg)
Uma API pode ser um dos maiores tesouros de uma empresa. Clientes investem ao integrar uma API.
"A key lesson here is that API is not just a documented class. And, APIs don't just happen; they are a big investment." Erich Gamma.
![Page 11: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/11.jpg)
¡ Clientes investem: comprando, escrevendo e aprendendo
¡ APIs promovem a reutilização e reduz custos ¡ O custo em parar de usar uma API pode ser proibitivo ¡ APIs públicas de sucesso captam clientes
![Page 12: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/12.jpg)
APIs também podem ser um dos maiores débitos de uma empresa. Podem resultar em intermináveis chamadas ao suporte.
”Public APIs like diamonds, are forever. You have one chance to get it right So give it your best." Joshua Bloch.
![Page 13: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/13.jpg)
Intuitiva
![Page 14: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/14.jpg)
¡ Fácil de aprender ¡ Fácil de usar, mesmo sem documentação ¡ Difícil de usar incorretamente ¡ Fácil de estender ¡ Fácil de ler e manter o código que a usa ¡ Focada em um propósito ¡ Poderosa o bastante para atender os requisitos ¡ Apropriada e direcionada a um público ¡ Bem documentada (exemplar)
![Page 15: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/15.jpg)
¡ PROGRAMANDO
![Page 16: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/16.jpg)
¡ Iniciando um projeto de API ¡ Princípios de projeto ¡ Projeto de classes
![Page 17: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/17.jpg)
1) Liste os requisitos 2) Valide-‐os escrevendo casos de uso 3) Escreva código para cada caso de uso
Faça tudo sob a perspectiva do usuário da API
Envolva mais pessoas o quanto possível nesse processo
![Page 18: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/18.jpg)
¡ Escreva-‐os em não mais do que uma página § Quanto menor melhor (estamos começando) § Fácil de compartilhar e modificar
¡ Valide-‐os em caso de uso R: Deveríamos ter um programa para gerar boletos do Bradesco e salvar o código de barras no banco de dados para controlar a cobrança. Caso de Uso: Gerar boleto para banco Bradesco Caso: Obter código de barras do boleto gerado C: Salvar boleto gerado em PDF
![Page 19: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/19.jpg)
¡ Codifique o mais cedo possível ¡ Comece sem realmente implementar Caso de Uso: Gerar boleto para banco Bradesco
✓ Perspectiva do usuário public static void main.. { Boleto boleto = new Boleto(Banco.Bradesco); }
✓ Perspectiva Implementação
class Boleto{ private String codigoDeBarras; ... }
![Page 20: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/20.jpg)
Melhor do que começar a implementar cedo é começar com TDD mesmo para rascunho ¡ Ajuda manter visível apenas o que interessa ¡ Gera exemplos de uso sempre atualizados ¡ Direciona o design ¡ Evita implementar casos que seriam descartados
¡ Evita surpresas desagradáveis
![Page 21: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/21.jpg)
Além de usar TDD no desenvolvimento da API escreva testes para o código que utiliza a API de fato Muitas dependências, métodos complicados e outros mal cheiros podem ser identificados e levar o design à uma nova direção
![Page 22: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/22.jpg)
Golden Rule of API Design ”It’s not enough to write tests for an API you develop; you have to write unit tests for code that uses your API. When you follow this rule, you learn firsthand the hurdles that your users will have to overcome when they try to test their code independently.” Michael Feathers, (97 Things Every Programmer Should Know)
![Page 23: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/23.jpg)
Caso de Uso: Gerar boleto para banco Bradesco public void deveGerarBoletoBradescoCorretamenteNaMinhaAplicacao(){
Boleto boletoEsperado = mock(Boleto.class); BoletoViewer boletoViewer = mock(BoletoViewer .class); when(boletoViewer .getBoleto()).thenReturn(boletoEsperado); MeuGeradorDeBoleto geradorDeBoleto = new MeuGeradorDeBoleto(boletoViewer ); Boleto boletoGerado = geradorDeBoleto.gereBoletoCom(dadosDoMeuUsuario);
assertThat(boletoGerado, equalTo(boletoEsperado));
}
![Page 24: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/24.jpg)
Codifique cedo e frequentemente ¡ Comece antes de fato implementar (TDD) ¡ Escreva testes de código que usa API ¡ Escreva exemplos na medida que progride
§ Lembre-‐se uma API boa é exemplar § Exemplos bons tornam API fácil de entender § Exemplos ruins disseminam o mal uso, geram bugs, perguntas em fóruns e + problemas
![Page 25: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/25.jpg)
Seja realista e mantenha o foco no propósito
¡ Muitos dos projetos de APIs são restritivos § Não tente agradar a todos
§ Tente desagradar a todos igualmente
![Page 26: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/26.jpg)
Tente pensar antecipadamente, mas..
¡ Espere por cometer erros § Em poucos anos de uso da API eles surgirão
§ Espere por evoluir a API
![Page 27: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/27.jpg)
¡ Iniciando um projeto de API ¡ Princípios de projeto ¡ Projeto de classes
![Page 28: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/28.jpg)
API deve fazer o que se propõe a fazer e deve fazer bem ¡ Siga o princípio de responsabilidade única ¡ Tente manter tudo o mais simples possível ¡ A funcionalidade deve ser fácil de explicar
§ Se está difícil nomear, algo pode estar errado § Bons nomes guiam o desenvolvimento § Estar suscetível a divisão ou fusão de módulos
![Page 29: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/29.jpg)
API deve ser o mais simples possível, mas não simplória ¡ Deve satisfazer os requisitos ¡ Os conceitos extraídos são o mais importante ¡ Procure uma boa proporção de poder/massa ¡ A massa conceitual é mais importante que a estrutural
![Page 30: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/30.jpg)
API deve ser tão pequena quanto possível, mas não a menor Na dúvida, deixe de fora ¡ Funcionalidades, classes, métodos, etc ¡ Sempre pode-‐se adicionar, mas não remover ¡ Quanto mais coisa, mais difícil de se aprender ¡ Quanto mais coisa, mais pode dar errado
![Page 31: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/31.jpg)
Nomes são especiais porque eles compõem o vocabulário da API Escolha nomes pronunciáveis e memoráveis ¡ Bons nomes surgem do domínio do problema
§ São familiares, intuitivos e com significado ¡ Bons nomes são auto explicativos
§ Evite abreviações
![Page 32: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/32.jpg)
Não me faça pensar O código deve ser lido como uma prosa
Caso de Uso: Gerar boleto para banco Bradesco
Boleto boleto = Cobranca.gere() .para(Banco.Bradesco) .com(vencimentoAtual) .com(valorAtual) .boleto();
! Código que usa objetos da API jrimum.org/bopepo
![Page 33: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/33.jpg)
Seja Consistente ¡ Mesma palavra = significa mesma coisa ¡ Busque simetria e consistência
§ Faça a mesma coisa do mesmo jeito § Por toda API, plataforma, ambiente, etc § Inconsistência aparece por que você mudou de ideia com o tempo
§ Faça revisões de código para manter tudo alinhado com o time
![Page 34: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/34.jpg)
Coisas similares devem se parecer com coisas similares Caso de Uso: Gerar boleto para banco Bradesco BoletoViewer boleto = new BoletoViewer(dados) .comTemplate(arquivoPersonalizado) .gerePdf(); Caso de Uso: Gerar guia de arrecadação e recebimento banco BB GuiaViewer guia = new GuiaViewer(dados) .comTemplate(arquivoPersonalizado) .gerePdf();
![Page 35: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/35.jpg)
Minimize o acesso a tudo ¡ Tudo deve ter o mínimo privilégio de acesso
§ Promove o ocultamento de informação § Classes e membros devem ter acesso privado sempre que possível
§ Classes públicas não devem ter membros públicos, com exceção de constantes
![Page 36: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/36.jpg)
A implementação é um detalhe ¡ Detalhes de implementação tem impacto
§ Confundem usuários § Dificultam o entendimento
¡ Saiba identificá-‐los § Parâmetros para otimização, formato de dados (file, connection, etc), dependência de outras APIs
¡ Não deixe vazarem pela API § Exceções, formatos de dados, etc
![Page 37: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/37.jpg)
Documente cedo, frequentemente e sempre ¡ Documente todo parâmetro, método, construtor, classe, interface e exceção
¡ Mantenha sempre atualizada ¡ “O que?” e “Como?” devem estão sempre presentes
¡ “Porque” também explicando decisões tomadas, padrões adotados, etc
![Page 38: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/38.jpg)
Documente para cada situação específica ¡ Documentação de referência
§ Javadoc e similares ¡ Tutorias
§ Como começar rapidamente e fazer algo de valor § O que posso fazer em 2 minutos § Como gerar um boleto personalizado
¡ Guia do programador § Introdução, glossário, conceitos, padrões, etc
![Page 39: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/39.jpg)
Sua API deve ser sinérgica em relação a Plataforma ¡ Faça o que é usual e convencionado
§ Siga as convenções de nomes § Imite os bons padrões das APIs da linguagem
¡ Conheça bem a plataforma e a linguagem § Funcionalidades amigáveis devem ser utilizadas: generics, varargs, enums, default arguments
¡ Também conheça armadilhas e ciladas § Finalizers, permgen, garbage collector, etc
![Page 40: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/40.jpg)
Lembre-‐se que decisões no projeto poderão afetar a performance ¡ Decisões ruins podem limitar a performance § Fazendo um tipo mutável ou imutável § Usando uma implementação no lugar de uma interface
§ Oferecendo um construtor no lugar de um factory method
![Page 41: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/41.jpg)
Lembre-‐se que decisões no projeto poderão afetar a performance ¡ Decisões ruins podem limitar a performance § Fazendo um tipo mutável ou imutável § Usando uma implementação no lugar de uma interface
§ Oferecendo um construtor no lugar de um factory method
![Page 42: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/42.jpg)
¡ Iniciando um projeto de API ¡ Princípios de projeto ¡ Projeto de classes
![Page 43: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/43.jpg)
Quando criar um tipo? ¡ Quando existir um comportamento específico e que um tipo existente não suporte
¡ Quando é um conceito chave no domínio Ex: CEP, CPF, CodigoDeBarras, Pagador, Boleto, ..
![Page 44: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/44.jpg)
Tipos de domínio são melhores do que strings ”String é uma estrutura de dados rigorosa e exige muita duplicação de processo em qualquer lugar para o qual seja passada. É um veículo perfeito para ocultar informações" “The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information.”
Alan Perlis.
![Page 45: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/45.jpg)
Transforme objetos de domínio em Objetos de Valor (Tiny Types or Value Object DDD) ¡ Projete-‐os imutáveis a menos que tenha uma boa razão para o contrário
Ex: CEP, CPF, CodigoDeBarras, Boleto, ..
![Page 46: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/46.jpg)
Minimize a Mutabilidade ¡ Classes devem ser imutáveis, a não ser que haja uma boa razão para fazer o contrário § Vantagens: simples, thread-‐safe, reutilizável § Desvantagens: determina um objeto para cada valor
¡ Se mutável, manter o espaço de estados pequeno e bem definido § Deixe claro quando é legal chamar qual método.
Bom: LocalDate, Duration, Instant Ruim: Date, Calendar
![Page 47: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/47.jpg)
Subclasse somente onde faz sentido ¡ Extensão implica em substituição (Liskov)
§ Estenda somente quando o relacionamento "é um" existe § Do contrário, use composição
¡ Classes públicas não devem estender outras classes públicas apenas por facilidades de implementação
Bom: Set extends Collection Ruim: Properties extends Hashtable Stack extends Vector
![Page 48: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/48.jpg)
Projete e documente para herança senão a proíba ¡ Herança viola o princípio de encapsulamento
§ A subclasse é suscetível aos detalhes da implementação da superclasse
¡ Se você permitir a extensão, documente a auto-‐utilização § Como os métodos utilizam um outro?
¡ Política conservativa: todas as classes concretas são final
Bom: AbstractSet, AbstractMap Ruim: Muitas classes concretas em libs J2SE
![Page 49: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/49.jpg)
¡ Integrando
![Page 50: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/50.jpg)
Um servidor de integração contínua é tão dispensável quanto um sistema de controle de versões ¡ Integração contínua
§ Garante que o código continua funcionando após cada alteração
§ Proporciona aos participantes do projeto a visibilidade do estado atual do projeto
✔✖
![Page 51: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/51.jpg)
![Page 52: Projeto de API - TDC 2014 - Floripa - Trilha Arquitetura - 18/05/2014](https://reader034.vdocuments.pub/reader034/viewer/2022051515/558e6a421a28abf4658b4689/html5/thumbnails/52.jpg)