.NET

13 abr, 2016

Xamarin.Forms – Arquitetando uma aplicação para dispositivo móvel

Publicidade

No artigo de hoje vou apresentar os conceitos das principais práticas e recursos usados para criar uma arquitetura em aplicações para dispositivos móveis usando o Xamarin.Forms.

Se você realmente quer ter sucesso no desenvolvimento de aplicações para dispositivos móveis, o Xamarin.Forms é a ferramenta que pode lhe ajudar a atingir esse objetivo. Embora isso seja verdade, a ferramenta não faz milagres, e você, como desenvolvedor, tem que estar ciente do seu papel e de suas responsabilidades. Não adianta nada ter a melhor ferramenta do mundo se você não sabe usá-la ou a usa de forma incorreta.

Um princípio fundamental que deve ser adotado na criação de aplicativos multiplataforma é criar uma arquitetura que se presta a uma maximização do compartilhamento de código entre as plataformas.

Para poder fazer isso, você já deve ter experiência e conhecimento dos conceitos chaves da Programação Orientada a Objetos (POO), dos conceitos relacionados com a separação de responsabilidades em camadas e ter conhecimento dos padrões de projetos usados na construção de um aplicativo bem arquitetado.

Vejamos a seguir um resumo de cada uma desses tópicos.

Conceitos chaves da Programação Orientada a Objetos – POO

1. Encapsulamento

A aplicação do encapsulamento garante que as classes e até mesmo as camadas da arquitetura só exponham uma API mínima que executa as suas funções necessárias, e esconde os detalhes de implementação.

A nível de classe, isto significa que os objetos se comportam como “caixas pretas” e que o código não precisa saber como ele vai realizar as suas tarefas.

A nível de arquitetura, significa implementar padrões como Facade, que incentivam uma API simplificada que orquestra interações mais complexas em nome do código nas camadas mais abstratas. Isto significa que o código da UI, por exemplo, só deve ser responsável por exibir telas e aceitar a entrada do usuário; e nunca interagir com a base de dados diretamente. Da mesma forma o código de acesso a dados só deve ler e escrever para o banco de dados, e nunca interagir diretamente com botões ou etiquetas da UI.

2. Separação de responsabilidades

Ao projetar e desenvolver um software procure sempre aplicar a separação de responsabilidades que é o processo de dividir sua aplicação em unidades específicas de funcionalidades de tal forma que cada unidade atenda somente às necessidades de sua responsabilidade, tendo o mínimo de sobreposição possível com outras unidades em termos de funcionalidade; ou seja, nenhum elemento do sistema deve compartilhar as responsabilidades de outro ou abranger responsabilidades não relacionadas.

Isto é alcançado estabelecendo limites, onde um limite é qualquer restrição, lógica ou física, que delimita um determinado conjunto de responsabilidades.

Certifique-se de que cada componente, tanto a nível de arquitetura como a nível de classe, tenha um objetivo claro e bem definido. Cada componente deve executar apenas suas tarefas definidas e expor essa funcionalidade através de uma API que seja acessível para as outras classes que precisam usá-lo.

3. Polimorfismo

Polimorfismo significa muitas formas e na orientação a objetos você pode enviar uma mesma mensagem para diferentes objetos e fazê-los responder da maneira correta. Você pode enviar a mensagem mover para cada objeto semelhante a um veículo e cada um vai se comportar de maneira diferente para atender a sua solicitação.

Quando uma mesma mensagem pode ser processada de diferentes formas, temos um exemplo de polimorfismo.

Programar para uma interface ou classe abstrata que suporta múltiplas implementações significa que o código do núcleo pode ser escrito e compartilhado entre plataformas, enquanto ainda interage com recursos específicos da plataforma.

4. Padrões de Projetos

Padrões de projeto podem ser vistos como uma solução que já foi testada para um problema. Desta forma, um padrão de projeto geralmente descreve uma solução ou uma instância da solução que foi utilizada para resolver um problema específico. Padrões de projetos são soluções para problemas que alguém um dia teve e resolveu aplicando um modelo que foi documentado e que você pode adaptar integralmente ou de acordo com necessidade de sua solução.

Aplicando padrões de projeto, você ganha tempo e torna sua aplicação mais fácil de manter, testar e usar.

As aplicações desses princípios têm como resultado natural aplicações modeladas com base no mundo real ou entidades abstratas com camadas lógicas distintas.

A separação de código em camadas faz com que as aplicações sejam mais fáceis de entender, testar e manter.

Recomenda-se ainda que o código em cada camada seja fisicamente separado, tanto em diretórios ou até mesmo projetos separados para aplicações muito grandes, bem como logicamente separadas (utilizando namespaces).

E por falar em camadas vamos ver quais os principais tipos de camadas usados em aplicações móveis.

Tipos de camadas mais usadas em aplicações

A seguir, vou dar um resumo dos tipos de camadas mais usados na arquitetura de aplicações:

Camada de dados

A persistência de dados não volátil; provavelmente deve ser usado um banco de dados SQLite, mas poderia ser implementada com arquivos XML ou qualquer outro mecanismo adequado.

Camada de acesso aos dados  – Data Access Layer (DAL)

Envolve a camada de dados que realiza as operações de acesso aos dados como criar, ler, atualizar, excluir (CRUD), sem expor detalhes de implementação para o chamador. Por exemplo, a DAL pode conter instruções SQL para consultar ou atualizar os dados, mas o código de referência não precisa saber disso.

Camada de negócios – Businness Logic Layer (BLL)

Ás vezes chamada de camada de lógica de negócios ou BLL, contém definições de entidade de negócio (o modelo) e lógica de negócios.

Camada de acesso a serviço – Service Access Layer

Usada para acessar serviços na nuvem a partir de complexos web services (REST, JSON, WCF) ou de uma simples recuperação de dados e imagens a partir de servidores remotos. Encapsula o comportamento de rede e fornece uma API simples para ser consumida pelas camadas de aplicação e interface do usuário.

Camada de aplicação – Application Layer

Representa o código que é normalmente específico de cada plataforma (geralmente não compartilhado entre as plataformas) ou código que é específico para o aplicativo (que geralmente não são reutilizáveis). Um bom teste para saber se você deve colocar o código na camada de aplicação ou na camada de interface do usuário é:

  •  Determinar se a classe tem quaisquer controles reais de exibição;
  •  Verificar se ele poderia ser compartilhado entre várias telas ou dispositivos (ex. IPhone e iPad).
Camada de interface com o usuário – User Interface (UI) Layer

É a camada de revestimento do usuário. Contém telas, widgets e os controladores que os gerem.

Uma aplicação pode não necessariamente conter todas as camadas – por exemplo, a camada de acesso ao serviço não existiria em um aplicativo que não acessa recursos de rede. Em uma aplicação muito simples podemos mesclar a camada de dados com a camada de acesso a dados, visto que as operações são extremamente básicas.

Padrões de projetos mais comuns usados em aplicações para celulares

Padrões são uma forma consagrada para capturar soluções recorrentes para problemas comuns. Existem alguns padrões fundamentais que são úteis para entender na construção de aplicações móveis:

1. Model, View, Controller (MVC)

O padrão MVC é usado mais frequentemente na construção de interfaces de usuário e prevê a separação entre a própria definição de uma tela de interface do usuário (View), o código que trata da interação (Controller), e os dados usados para preencher o Modelo. O Modelo é uma peça completamente opcional e, portanto, o núcleo para compreender esse padrão reside na View e no Controlador.

2. Facade

“Fornecer uma interface unificada para um conjunto de interfaces em um subsistema. Facade define uma interface de nível mais alto que torna o subsistema mais fácil de ser usado.”

Fornece um ponto de entrada simplificado para o trabalho complexo. Por exemplo, em um aplicativo de rastreamento de tarefas, você pode ter uma classeTaskManager com métodos como GetAllTasks(), getTask (taskID), SaveTask (tarefa) etc. A classe TaskManager fornece uma fachada para o funcionamento interno para salvar/recuperar os objetos de tarefas.

3. Singleton

O padrão Singleton prevê uma maneira em que apenas uma única instância de um determinado objeto pode existir. Por exemplo, quando se utiliza o SQLite em aplicações móveis, você só quer ter somente uma instância do banco de dados. Usar o padrão Singleton é uma maneira simples de garantir isso.

4. Model View ViewModel (MVVM)

O padrão Model View ViewModel (MVVM) é uma especialização do padrão de projeto Presentation Model (PM) que foi introduzido em 2004 por Martin Fowler.

Um dos objetivos principais do padrão Presentation Model (PM) é separar e abstrair a View – a interface visual do usuário (UI) – da lógica de apresentação para fazer a interface do usuário testável. Além disso, podemos também querer criar uma lógica de apresentação reutilizável para interfaces diferentes e diferentes tecnologias de interface do usuário, reduzir o acoplamento entre a interface do usuário e outros códigos e permitindo que os designers de interface possam trabalhar de forma mais independente.

Dessa forma o padrão MVVM é uma interpretação especializada do padrão PM concebidos para satisfazer os requisitos de aplicações móveis.

Estruturalmente, uma aplicação que usa o padrão MVVM consiste basicamente em três componentes principais: o Modelo, a Visão(View) e a ViewModel.

A aplicação desses conceitos na prática irá fazer com que suas aplicações estejam aderentes aos quesitos fundamentais para garantir que a manutenção, a testabilidade e a utilização da aplicação seja feita com eficiência.

Sem a aplicação desses conceitos você pode até criar projetos que funcionem, mas serão projetos confusos de difícil manutenção e extensão e fadados ao fracasso, principalmente em um ambiente complexo como é o ambiente de desenvolvimento para os dispositivos móveis.