Hackathon Superweapon: F # e Fabulous

 

Por Larry O’Brien10 de janeiro de 2019

Traduzido por Adriano D’lucca

Recentemente, participei do Hack for the Sea , um fim de semana dedicado à aplicação de tecnologia à conservação marinha. Um dos nossos desafios locais foi um “aplicativo móvel multiplataforma para relatar detritos marinhos”. Uma oportunidade perfeita para explorar o   projeto Fabulous , que traz a arquitetura Elmish Model-View-Update (MVU) para Xamarin e F #.

Hackathons são grandes desafios curtos e intensos que (esperançosamente) transformam um conceito em, se não um protótipo completo, pelo menos uma iteração inicial. A camaradagem, o curto prazo e a pizza gratuita fazem dos hackathons um lugar ideal para explorar novas tecnologias.

F # tornou-se uma linguagem de programação preferida para o trabalho de produção. Ele tem uma combinação de sintaxe concisa para escrever novos códigos e tipos fortes para trabalhar com códigos mais antigos ou desconhecidos. No entanto, serveria para o caos controlado de um hackathon?

Arquitetura MVU

A arquitetura MVU é uma arquitetura cada vez mais popular que combina “interface do usuário no código”, com uma separação simples de usar entre:

  • Uma view função que descreve a interface do usuário apropriada ao estado atual do aplicativo.
  • Uma update função que modifica esse estado.

O MVU não é específico para qualquer idioma, mas se encaixa bem com a mentalidade de programação funcional. Espera-se que ambos view e update recebam todas as informações de que precisam de seus argumentos, em vez de ler e manter dados de instância.

A arquitetura MVU e a sintaxe concisa do F # permitem criar rapidamente um aplicativo de geração de relatórios muito semelhante a muitos aplicativos LOB (Line of Business). O aplicativo tem uma combinação de páginas de entrada de dados e dados gerados por dispositivo (informações de localização e hora padrão, fotos etc.).

Criando a interface do usuário Xamarin.Forms no código

Criando uma interface do usuário Xamarin.Forms no código é muito simples. Defina cada elemento complexo ou página em uma função local. Um simples como header apenas contém um rótulo estático. Um mais complexo locationPage pode ter uma mensagem dependendo do valor (ou não) de model.Report.Location. Como você pode ver, usar a poderosa capacidade FlexLayout  do Xamarin.Forms define uma interface de usuário que se estabelece corretamente em qualquer tamanho de dispositivo:

 

F # é um pouco parecido com o Python (muitas vezes, ao escrever Python, eu acidentalmente digito um F # -ism!). Uma coisa possivelmente surpreendente para as pessoas que ouviram falar de “linguagens funcionais fortemente tipificadas” é a falta de declarações de tipo explícitas. Embora os desenvolvedores possam   adicionar declarações explícitas, você depende principalmente do compilador para inferir corretamente o tipo e usar o IntelliSense para fornecer a assinatura precisa. Outras coisas que valem a pena destacar:

  • Em F # “tudo é uma expressão”. As funções e valores são declarados usando let;
  • O |> operador é semelhante a um tubo Unix ou PowerShell. Ele passa o valor do lado esquerdo para o lado direito como um argumento;
  • A sintaxe match … with … correspondência de padrões que gera um erro do compilador se você perder um caso;
  • A função bind que é algo como o operador condicional nulo.

Usando o F # para escrever uma função

Após aprender o básico do F # ele torna-se muito legível e conciso. Como as funções locais são triviais para escrever, você acaba refatorando o código clichê em funções locais. Por exemplo, esse “painel de progresso” usa ícones diferentes para indicar se o usuário inseriu ou não um tipo específico de dados (por exemplo, “what_some.png” vs “what_none.png”). Em vez de escrever um monte de blocos if…then… quase idênticos , é natural em F # escrever uma função como essa imageFor que verifica se os dados têm um campo específico (o caso Some ). Em seguida, retorna os resultados da verificação e o nome do ícone específico para carregar:

 

Atualizando para Atualizar

Para ser honesto, adoro a arquitetura Model-View-Controller. No entanto, o MVU tem algumas vantagens claras, particularmente nas primeiras iterações de um projeto. Além disso, ele tem o potencial para “depuração de viagem no tempo”, na qual você pode “executar o programa para trás e para frente”, em vez de apenas congelar em um ponto de interrupção.

A chave para o MVU é o método update, que tem uma assinatura Msg -> Model -> Model * Cmd<Msg> (que seria expressa em C # como Func<Msg,Model,Tuple<Model,Cmd<Msg>>). Isso mostra o padrão funcional comum de “Take a request ( Msg) e um argumento representando o estado ( Model). Aja sobre isso e, em seguida, retorne uma nova versão do estado com uma nova solicitação para lidar com a próxima etapa na resposta à entrada. ”

Por exemplo, quando o GPS recebe uma leitura, o manipulador cria um LocationFound Msg com um valor do tipo Xamarin.Essentials.Location. Em resposta, o método update tem este trecho:

 

Relatórios

Um novo report (os dados que são finalmente carregados no Azure) é criado copiando o oldReport com o novo valor Location. Crio então um novo model que contém meu novo report e o valor MapRegion usado no método view, como discutido anteriormente.

E é isso! O manipulador LocationFound é, na verdade, o mais longo da função update. Se uma mensagem exigir manuseio complexo, o manuseio deve ser feito em uma função separada. Isso é particularmente bom para o processamento assíncrono, como você pode ver no snippet abaixo, que armazena a foto em um blob do Azure e os dados no armazenamento da tabela:

Ao contrário do manipulador síncrono  LocationFound, essa função faz algum trabalho assíncrono e dispara um novo Cmd com um Msg que seja uma mensagem Error ou uma mensagem SubmissionResult. Em vez de uma função que tenta fazer todos os negócios de coordenar solicitações de rede assíncrona, exibir os resultados ou erros, etc., a arquitetura da MVU facilita a criação de funções de tarefa única, claras e discretas. Em uma situação de rápida iteração, como uma hackathon, isso é uma explosão: “OK, o que vem depois?”… Digite algumas linhas… execute… mude… execute… “OK, o que vem a seguir?”

Aplicações de escala

Existe um trade-off. Uma função update que precisa manipular muitos tipos Msg cujos níveis de abstração podem variar (por exemplo, SubmitReport vs. TakePhoto). É muito chocante estar pregando as “muitas funções pequenas” funcionais e ter uma função de várias centenas de linhas update. Eu recomendo assistir a palestra de Zaid Ajaj “ Scaling Elmish Applications ” para uma boa discussão do assunto.

Empacotando

No final, fiz meu último commit alguns minutos antes da meia-noite de sábado, tendo criado do zero uma aplicação móvel de entrada de dados multiplataforma, dois wrappers para controles personalizados e uma pilha de latas de refrigerante para serem recicladas : as latas de alumínio são eficientemente recicladas em comparação com as garrafas plásticas, apesar de sua proporção relativamente baixa de embalagem / conteúdo). Você pode ver o resultado provisório (e a prova de que o design UX não é meu forte!) No meu repositório do Github .

O ambiente de pressão de uma hackathon exige ferramentas que sejam de alta produtividade e divertidas: exatamente como descreveria F # e Fabulous !

Fonte: blog.xamarin.com/hackathon-superweapon-f-and-fabulous/

RelatedPost

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *