Microsserviços de Susan J. Fowler - para Desenvolvimento Mobile

Concluído uma atualização sobre os principais Padrões de Arquiteturas para o Desenvolvimento Mobile, a ideia é aprofundar mais nos Microsserviços. E para isso, começo a ler o recém chegado livro da Susan J. Fowler. 

Mas diferente do que o título pode nos levar a interpretar, o livro não tem exemplos de soluções e códigos prontos. Tem uma boa base na vivência da Susan, parte nos serviços da UBER, permitindo que você converta esta experiência para qualquer tecnologia.

Image

Arquitetura iOS VIPER

Nos estudos acabei achando uma Arquitetura para iOS chamada VIPER.

Onde pude ter a oportunidade de entender, está Arquitetura tem como base a Experiência de construção de LEGO transferida para o design do aplicativo iOS VIPER.

Diferente do padrão MV(X), VIPER faz outra iteração sobre a ideia de separar responsabilidades com cinco camadas.

Interator - contém lógica de negócios relacionada aos dados ( Entidades ) ou rede, como criar novas instâncias de entidades ou buscá-las no servidor. Para esses propósitos, você usará alguns serviços e gerenciadores que não são considerados parte do módulo VIPER, mas sim uma dependência externa. Apresentador - contém a lógica de negócios relacionada à IU (mas independente do UIKit ), invoca métodos no Interator . Entidades - seus objetos de dados simples, não a camada de acesso a dados, porque isso é responsabilidade do Interator . Roteador - responsável pelos trechos entre os módulos VIPER . Basicamente, o módulo VIPER pode ser uma tela ou toda a história do usuário de seu aplicativo - pense na autenticação, que pode ser uma tela ou várias outras relacionadas. Quão pequenos são os seus blocos de “LEGO”? - Você é quem decide.

Image

Se compararmos com o padrão MV(X), veremos algumas diferenças na distribuição de responsabilidades: A lógica do modelo (interação de dados) mudou para o Interator com as Entidades como estruturas de dados burras. Apenas as funções de representação da IU do Controller / Presenter / ViewModel foram movidas para o Presenter, mas não os recursos de alteração de dados.

VIPER é o primeiro padrão que aborda explicitamente a responsabilidade da navegação, que deve ser resolvida pelo Roteador. A maneira adequada de fazer o roteamento é um desafio para os aplicativos iOS, os padrões MV(X) simplesmente não resolvem esse problema.

Distribuição - distribuição de responsabilidades. Testabilidade - sem surpresas aqui, melhor distribuição - melhor testabilidade. Fácil de usar - finalmente, os dois acima têm custo de manutenção, como você já imaginou. Você tem que escrever uma grande quantidade de interface para classes com responsabilidades muito pequenas.

Me parece que adotar o VIPER você tem a liberdade e a percepção de que pode construir um tanque, mas que pode servir para atirar numa mosca. E muito dos padrões do MV(X) consiga nos atender a longo prazo e com um custo menor de manutenção.

Arquitetura iOS MVC, MVP, MVVM

Dando continuidade ao aprendizado sobre Padrões e Arquiteturas, me mantenho nos padrões mais usados para Mobile seja para Android ou iOS.

Fundamentos de MV (X) Existem muitas opções quando se trata de padrões de design de arquitetura: MVC ,MVP, MVVM

Os 3 MV's pressupõem colocar as entidades do aplicativo em uma das 3 categorias:

Modelos - responsáveis ​​pelos dados de domínio ou uma camada de acesso a dados que manipula os dados.

Visualizações - responsável pela camada de apresentação, para o ambiente iOS pense em tudo começando com o prefixo ' UI '. Como o mediador entre o Model e a View, responsável por alterar o Model , reagindo às ações do usuário realizadas na View e atualizando a View com as mudanças do Model.

MVC Tradicional por assim dizer, é um pouco diferente do MVC da Apple.

Image

Cacau MVC O Controlador é um mediador entre a Visualização e o Modelo para que eles não se conheçam. O menos reutilizável é o Controlador, já que devemos ter um lugar para toda aquela lógica de negócios complicada que não se encaixa no Modelo .

MVC da Apple

Realistic Cocoa MVC Cocoa MVC incentiva você a escrever controladores de visualização massiva , porque eles estão tão envolvidos no ciclo de vida de visualização que é difícil dizer que são separados. Embora você ainda tenha a capacidade de descarregar parte da lógica de negócios e da transformação de dados para o Modelo, você não tem muita escolha quando se trata de descarregar trabalho para a Visualização, na maioria das vezes, toda a responsabilidade da Visualização é enviar ações para o controlador . O controlador de visualização acaba sendo um delegado e uma fonte de dados de tudo, e você pode deixa-los responsável por despachar e cancelar as solicitações de rede.

Image

A View configurada diretamente com o Model , então as diretrizes do MVC são violadas, mas isso acontece o tempo todo, e geralmente as pessoas não acham que está errado. Se você seguir estritamente o MVC, deverá configurar a célula a partir do controlador e não passar o modelo para a visualização , o que aumentará ainda mais o tamanho do seu controlador .

Cocoa MVC não é abreviado como o Controlador Massive View. E podemos ter um problema que pode não ser evidente até que chegue ao Teste de Unidade . Uma vez que seu controlador de visualização está fortemente acoplado com a visualização, torna-se difícil testar porque você tem que ser muito criativo ao simular visualizações e seu ciclo de vida, ao escrever o código do controlador de visualização de tal forma que sua lógica de negócios seja separada tanto quanto possível a partir do código de layout de visualização.

Mas vamos avaliar o Cocoa MVC em termos de características definidas no início do artigo:

Distribution - a View e o Model de fato separados, mas a View e o Controller estão fortemente acoplados.

Testabilidade - devido à má distribuição, você provavelmente só testará seu modelo. Facilidade de uso - a menor quantidade de código entre outros padrões. Além disso, todos estão familiarizados com ele, portanto, é facilmente mantido, mesmo por desenvolvedores inexperientes.

Se Cocoa MVC é o padrão de sua escolha, e você não está pronto para investir mais tempo em sua arquitetura e sente que algo com custo de manutenção mais alto é um exagero para seu projeto de estimação minúsculo.

Mas podemos dizer que o Cocoa MVC é o melhor padrão arquitetônico em termos de velocidade de desenvolvimento.

MVP

No MVP a View está fortemente acoplado ao Controller, enquanto o mediador do MVP, Presenter, não tem nada a ver com o ciclo de vida do view controller, não há código de layout no Presenter , mas ele é responsável por atualizar a View com dados e estado.

Image

Se dissermos que o UIViewController é o View, em termos de MVP, as subclasses de UIViewController são, na verdade, as visualizações e não os apresentadores. Essa distinção fornece testabilidade excelente, o que tem o custo da velocidade de desenvolvimento, porque você tem que ter dados manuais e associação de eventos.

Vejamos os recursos do MVP: Distribuição - tem a maior parte das responsabilidades divididas entre o MVP no iOS, excelente testabilidade e muito código.

MVP Com Bindings e Hooters Existe outro ponto do MVP - o MVP do Controlador de Supervisão. Esta variante inclui vinculação direta da Visualização e do Modelo enquanto o Presenter (O Controlador de Supervisão) ainda lida com ações da Visualização e é capaz de alterar a Visualização .

MVVM O mais recente e o melhor dos MV(X)'s, em teoria, o Model-View-ViewModel parece muito bom. A View e o Model já são familiares para nós, mas também o Mediador, representado como o View Model.

MVVM É muito semelhante ao MVP: o MVVM trata o controlador de visualização como o View Não há um acoplamento forte entre a vista e o modelo Além disso, ele faz ligações como a versão de supervisão do MVP; entretanto, desta vez não entre a vista e o modelo , mas entre a vista e o modelo de vista . Então, qual é o modelo de visualização na realidade do iOS? É basicamente uma representação independente do UIKit de sua Visualização e seu estado. O View Model invoca mudanças no Model e se atualiza com o Model atualizado , e uma vez que temos uma ligação entre View e View

Image

Model , o primeiro é atualizado de acordo.

Bindings As vinculações vêm prontas para o desenvolvimento do OS X, mas não as temos na caixa de ferramentas do iOS. Claro que temos o KVO e as notificações, mas eles não são tão convenientes quanto as ligações. Portanto, desde que não queiramos escrevê-los nós mesmos, temos duas opções: Uma das bibliotecas de ligação baseadas em KVO, como RZDataBinding ou SwiftBond As bestas de programação reactive funcional em escala real , como ReactiveCocoa , RxSwift ou PromiseKit . Se você ouve “MVVM” - você pensa em ReactiveCocoa, e vice-versa. Embora seja possível construir o MVVM com as ligações simples, ReactiveCocoa permitirá que você obtenha a maior parte do MVVM.

Testabilidade - o View Model não sabe nada sobre a View , isso nos permite testá-la facilmente. O modo de exibição também pode ser testado, mas como é dependente do UIKit, você pode querer ignorá-lo.

Fácil de usar - O MVVM é muito atraente, pois combina os benefícios das abordagens citadas e, além disso, não requer código extra para as atualizações do View devido aos bindings do lado do View. No entanto, a testabilidade ainda está em um bom nível.

Conceitos do ciclo de Vida da Atividade Android

Para navegar entre as fases do ciclo de vida da atividade, a classe “Activity” fornece um conjunto principal de seis callbacks: onCreate(), onStart(), onResume(), onPause(), onStop() e onDestroy(). Conforme a atividade entra em um novo estado, o sistema invoca cada um desses callbacks.

À medida que o usuário começa a sair da atividade, o sistema chama métodos para eliminá-la. Em alguns casos, essa eliminação é somente parcial. A atividade ainda reside na memória, como quando o usuário alterna para outro aplicativo, e ainda pode voltar ao primeiro plano. Se o usuário retornar a essa atividade, a atividade será retomada de onde o usuário parou. Com algumas exceções, os aplicativos são impedidos de iniciar atividades quando executados em segundo plano.

A probabilidade do sistema eliminar um determinado processo, com as atividades nele, depende do estado da atividade no momento. Em Estado da atividade e ejeção da memória, há mais informações sobre o relacionamento entre o estado e a vulnerabilidade para ejeção.

Dependendo da complexidade de sua atividade, não é necessário implementar todos os métodos do ciclo de vida. No entanto, é importante compreender cada um deles e implementar somente os que garantem que o aplicativo tenha o desempenho esperado pelo usuário.

Image

Os callbacks usados para processar as transições entre os estados.

Callbacks do ciclo de vida Esta seção fornece informações conceituais e de implementação sobre os métodos de callback usados durante o ciclo de vida da atividade.

Algumas ações, como chamar setContentView(), fazem parte dos métodos do ciclo de vida da atividade em si. No entanto, o código que implementa as ações de um componente dependente deve ser colocado no próprio componente. Para fazer isso, você precisa tornar o componente dependente ciente do ciclo de vida. Veja Como gerenciar ciclos de vida com componentes que os reconhecem para saber como tornar seus componentes dependentes cientes do ciclo de vida.

onCreate() Esse callback precisa ser implementado. Ele é acionado assim que o sistema cria a atividade. Quando a atividade é criada, ela insere o estado Criado. No método onCreate(), você executa a lógica básica de inicialização do aplicativo. Isso deve acontecer somente uma vez durante todo o período que a atividade durar. Por exemplo, sua implementação de onCreate() pode vincular dados a listas, associar a atividade a um ViewModel e instanciar algumas variáveis com escopo de classe. Esse método recebe o parâmetro savedInstanceState, um objeto Bundle que contém o estado anteriormente salvo da atividade. Se a atividade nunca existiu, o valor do objeto Bundle será nulo.

Caso você tenha um componente ciente do ciclo de vida conectado ao ciclo de vida da sua atividade, ele receberá o evento ON_CREATE. O método anotado com @OnLifecycleEvent será chamado para que seu componente ciente do ciclo de vida possa executar qualquer código de configuração necessário para o estado criado.

onStart() Quando a atividade insere o estado "Iniciado", o sistema invoca esse callback. A chamada onStart() torna a atividade visível ao usuário, à medida que o aplicativo prepara a atividade para inserir o primeiro plano e se tornar interativa. Por exemplo, é nesse método que o aplicativo inicializa o código que mantém a IU.

Quando a atividade é movida para o estado "Iniciado", qualquer componente ciente do ciclo de vida que esteja ligado ao ciclo de vida da atividade receberá o evento ON_START.

O método onStart() faz a conclusão muito rapidamente e, como no caso do estado "Criado", a atividade não reside no estado "Iniciado". Quando a finalização é feita pelo callback, a atividade insere o estado Retomado e o sistema invoca o método onResume().

onResume() Quando a atividade insere o estado "Retomado", ela vem para o primeiro plano e o sistema invoca o callback onResume(). É nesse estado que o aplicativo interage com o usuário. O app permanece nesse estado até que algo afete o foco do app. Esse evento pode ser, por exemplo, receber uma chamada telefônica, navegar pelo usuário para outra atividade ou desativar a tela do dispositivo.

Quando a atividade é movida para o estado "Retomado", qualquer componente ciente do ciclo de vida ligado ao ciclo de vida da atividade receberá o evento ON_RESUME. É nesse momento que os componentes do ciclo de vida podem ativar qualquer funcionalidade que precise operar enquanto o componente estiver visível e em primeiro plano, como o início da visualização da câmera.

Quando ocorre um evento de interrupção, a atividade insere o estado Pausado e o sistema invoca o callback onPause().

Caso a atividade retorne do estado "Pausado" para o estado "Retomado", o sistema chamará novamente o método onResume(). Dessa forma, implemente o onResume() para inicializar os componentes liberados durante onPause() e execute outras inicializações que devem ocorrer sempre que a atividade entrar no estado "Retomado".

Independentemente de qual evento de construção você escolher para executar uma operação de inicialização, certifique-se de usar o evento de ciclo de vida correspondente para liberar o recurso. Se você inicializar algo após o evento ON_START, libere ou finalize esse item após o evento ON_STOP. Caso você inicialize após o evento ON_RESUME, faça a liberação após o evento ON_PAUSE.

onPause() O sistema chama esse método como a primeira indicação de que o usuário está deixando sua atividade, embora nem sempre signifique que a atividade esteja sendo destruída. Isso indica que a atividade não está mais em primeiro plano, embora ainda possa estar visível se o usuário estiver no modo de várias janelas. Use o método onPause() para pausar ou ajustar operações que não devem continuar (ou que precisem continuar com moderação) enquanto a Activity estiver no modo "Pausado" e aquelas que você espera retomar em breve. Há vários motivos pelos quais uma atividade pode entrar nesse estado. Por exemplo:

Algum evento interromper a execução do aplicativo, conforme descrito na seção onResume(). Esse é o caso mais comum. No Android 7.0 (API de nível 24) ou mais recentes, diversos aplicativos operam no modo de várias janelas. Como só um dos aplicativos (janelas) tem foco a qualquer momento, o sistema pausa todos os outros aplicativos. Uma nova atividade semitransparente (como uma caixa de diálogo) é aberta. Enquanto a atividade estiver parcialmente visível, mas não for a atividade em foco, ela permanecerá pausada. Quando a atividade é movida para o estado pausado, qualquer componente ciente do ciclo de vida ligado ao ciclo de vida da atividade receberá o evento ON_PAUSE. É nesse momento que os componentes do ciclo de vida podem interromper qualquer funcionalidade que não precise operar enquanto o componente não estiver em primeiro plano, como na pausa de uma visualização da câmera.

Também é possível usar o método onPause() para liberar recursos do sistema, tratamento de sensores (como GPS) ou quaisquer recursos que possam afetar a duração da bateria enquanto a atividade estiver pausada e o usuário não precisar deles. No entanto, como mencionado acima, na seção onResume(), uma atividade pausada ainda poderá ser completamente visível no modo de várias janelas. Assim, considere usar onStop() em vez de onPause() para liberar ou ajustar completamente operações e recursos relacionados à IU para melhorar o suporte do modo de várias janelas.

A conclusão do método onPause() não significa que a atividade saia do estado "Pausado". Na verdade, a atividade permanece nesse estado até que ela seja retomada ou fique completamente invisível para o usuário. Se a atividade for retomada, o sistema invocará mais uma vez o callback onResume(). Caso a atividade retorne do estado "Pausado" para o estado "Retomado", o sistema manterá a instância Activity residente na memória, chamando novamente a instância quando o sistema invocar onResume(). Nesse cenário, não é necessário reiniciar componentes criados durante qualquer método de callback que leve ao estado "Retomado". Se a atividade ficar completamente invisível, o sistema chamará onStop(). A próxima seção discutirá o callback onStop().

onStop() Quando a atividade não estiver mais visível ao usuário, ela inserirá o estado Interrompido e o sistema invocará o callback onStop(). Isso pode ocorrer, por exemplo, quando uma atividade recém-iniciada preenche toda a tela. O sistema também poderá chamar onStop() quando a atividade parar de operar e estiver prestes a ser concluída.

Quando a atividade é movida para o estado interrompido, qualquer componente ciente do ciclo de vida ligado ao ciclo de vida da atividade receberá o evento ON_STOP. É nesse momento que os componentes do ciclo de vida podem interromper qualquer funcionalidade que não precise operar enquanto o componente não estiver visível na tela.

No método onStop(), o aplicativo liberará ou ajustará recursos desnecessários enquanto o aplicativo não estiver visível ao usuário. Por exemplo, o aplicativo poderá pausar animações ou alternar de atualizações de local mais específicas para as menos detalhadas. O uso de onStop() em vez de onPause() garante que o trabalho relacionado à IU continue, mesmo quando o usuário estiver visualizando a atividade no modo de várias janelas.

Use onStop() também para realizar operações de desligamento de uso intensivo da CPU. Por exemplo, se você não encontrar um momento mais oportuno para salvar informações em um banco de dados, poderá fazer isso durante onStop().

Fonte(s): Google Android Developers

Ciclo de vida da atividade Android

Pode parecer estranho, mas a forma que eu posto conteúdo não segue a ordem lógica do aprendizado, aviso caso não esteja acostumado com meus posts ;)

A ideia aqui e falar um pouco sobre o ciclo de vida da atividade do Android. Nada que você não encontre igual na documentação do Android.

Conforme o usuário navega pelo aplicativo, sai dele e retorna a ele, as instâncias Activity no aplicativo transitam entre diferentes estados no ciclo de vida.

A classe Activity fornece uma quantidade de callbacks que permite rastrear essas atividades.

Dentro dos métodos de callback do ciclo de vida, você pode declarar como a atividade deve se comportar quando o usuário sai e retorna dela.

Image

Por exemplo, se estiver construindo um reprodutor de vídeos de transmissão em sequência, você pode pausar o vídeo e encerrar a conexão da rede quando o usuário alternar para outro aplicativo. Quando o usuário retornar, será possível reconectar a rede e permitir que ele reinicie o vídeo de onde parou. Ou seja, cada callback permite que você realize o trabalho específico adequado a determinada mudança de estado.

Fazer o trabalho certo no momento apropriado e gerenciar as transições da maneira correta faz com que seu aplicativo seja mais robusto e tenha melhor desempenho.

Por exemplo, uma boa implementação dos callbacks de ciclo de vida pode ajudar a garantir que seu aplicativo evite os problemas a seguir:

  • Falhas se o usuário receber uma chamada telefônica ou mudar para outro aplicativo enquanto estiver usando seu aplicativo.
  • Consumo de recursos importantes do sistema quando o usuário não estiver usando ativamente o aplicativo.
  • Perda do progresso do usuário se ele sair do aplicativo e retornar mais tarde. *Falhas ou perda do progresso do usuário quando a orientação da tela mudar entre paisagem e retrato.

A ideia é entender o que acontece internamente quando operam e o que você deve implementar durante a execução deles.

Fonte(s): Google Android Developers