Logo Tech Writers

Tech writers

Esse é o nosso blog para apaixonados por tecnologia! Aqui, softplayers e outros especialistas compartilham conhecimentos fundamentais para o desenvolvimento dessa comunidade.

SEJA UM TECH WRITER
Observabilidade: O que é, pilares e como implementar a observabilidade orientada ao domínio
Tech Writers Março 16, 2023

Observabilidade: O que é, pilares e como implementar a observabilidade orientada ao domínio

Recentemente estamos vendo uma grande expansão dos sistemas web, o surgimento de aplicações híbridas e aplicações que utilizam cada vez mais os softwares como serviço (SaaS). Este crescimento traz um novo desafio aos times de DevOps, infra e desenvolvimento: somente o monitoramento de redes não é mais capaz de garantir a segurança dos dados. É aí que entra a observabilidade. A observabilidade auxilia no rastreamento e identificação de problemas a partir de ferramentas de software. E hoje, vamos te ensinar a implementar a observabilidade usando o método de Observabilidade Orientada ao Domínio. Assim, você vai tornar as diversas chamadas para serviços de log e frameworks de análises em seus sistemas menos técnicas e prolixas. Confira! O que é observabilidade em TI? A observabilidade em TI (também chamada de observability) é a capacidade de monitorar, rastrear, analisar e diagnosticar um sistema, a partir do uso de ferramentas de software. Com ela, é possível criar um sistema de constante monitoramento e observação sobre um sistema com o objetivo de compreender melhor como ele se comporta, principalmente em arquiteturas cloud. Este conceito é bastante aplicado por times DevOps, infraestrutura e desenvolvimento, pois já é difundido na Engenharia de Software que ele beneficia o software e facilita a solução de problemas. Observabilidade orientada ao domínio na prática: Valores Grandes aplicações voltadas para análises de métricas de alto nível, como Mixpanel, acreditam no conceito de “Momentos de valor” (value moments), que indica quais eventos de determinado produto são importantes para se instrumentar. Estes momentos de valor variam de acordo com o produto, por exemplo, um software voltado para soluções de assinatura eletrônica, como a 1Doc, pode considerar que a assinatura de um contrato é um “momento de valor”. Porém, o momento de valor que faz sentido para o seu negócio, não necessariamente faz sentido para os usuários. Isso porque o valor do seu negócio é composto do equilíbrio entre duas forças: a intenção e a expectativa. Se a intenção é facilitar o processo de assinatura de um contrato, e a expectativa dos seus usuários é exatamente essa, você alcançou o equilíbrio. Contudo, o desencontro dessas duas forças é uma perda de oportunidade, e consequentemente, de valor. Graças às métricas de alto nível, este desencontro não é uma causa perdida. Com elas é possível recuperar e manter o valor do seu negócio de acordo com os momentos de valor identificados pelo seu time de analistas de produto. A partir daqui, seu papel como pessoa desenvolvedora passa a envolver a verificação da viabilidade técnica e a implementação da captura dessas métricas para que o “time de negócio” consiga lidar com os dados. Como implementar a observabilidade orientada ao domínio? A partir de agora vamos para a parte prática aprender a implementar a observabilidade orientada ao domínio. Para entender melhor esta implementação, vamos imaginar um pequeno sistema de gerenciamento de tarefas. Este sistema cadastra tarefas agendadas e as executa de acordo com o agendamento. Porém, devido a uma necessidade dos usuários, em certos momentos, pode ser necessário adiantar a execução de uma dessas tarefas de forma manual. Para atender a esta necessidade de “execução adiantada”, a estrutura abaixo foi feita: GerenciadorTarefas: Classe responsável pela execução de uma determinada tarefa baseada em seu próprio código ─ é a classe de “caso de uso”; RecuperadorTarefas: Classe responsável pela abstração da recuperação das tarefas do banco de dados e retorno dos objetos de domínio ─ é a classe “repositório”. Tarefa: Classe que representa uma “tarefa” no sistema ─ é a “entidade de domínio”. Veja o exemplo abaixo: public class GerenciadorTarefas { private static boolean TAREFA_PROCESSADA = true; private static boolean TAREFA_NAO_PROCESSADA = false; private RecuperadorTarefas recuperadorTarefas; public GerenciadorTarefas(RecuperadorTarefas recuperadorTarefas) { this.recuperadorTarefas = recuperadorTarefas; } public boolean executaTarefaPeloCodigo(Integer codigoTarefa) { Tarefa tarefa = recuperadorTarefas.recuperaPeloCodigo(codigoTarefa); if (tarefa == null) { return TAREFA_NAO_PROCESSADA; } try { tarefa.iniciaProcesso(); return TAREFA_PROCESSADA; } catch (TarefaInterrompidaException e) { return TAREFA_NAO_PROCESSADA; } } } O código acima pode não ser o melhor exemplo, mas expressa bem a sua lógica de domínio. Agora, vamos aplicar a observabilidade no nosso método executaTarefaPeloCodigo. Para isto, vamos imaginar duas bibliotecas em nosso projeto: Log: É uma biblioteca genérica de logs, útil para atividades de throubleshooting por parte das pessoas desenvolvedoras. Analytics: É uma biblioteca genérica de eventos que metrifica interações de um usuário a uma determinada funcionalidade. public boolean executaTarefaPeloCodigo(Integer codigoTarefa) { Tarefa tarefa = recuperadorTarefas.recuperaPeloCodigo(codigoTarefa); if (tarefa == null) { Log.warn("A tarefa %d não existe, portanto, seu processo não foi iniciado.", codigoTarefa); return TAREFA_NAO_PROCESSADA; } try { Log.info("Processo da tarefa %d foi iniciado.", codigoTarefa); Analytics.registraEvento("tarefa_iniciada", tarefa); tarefa.iniciaProcesso(); Log.info("Processo da tarefa %d foi finalizado.", codigoTarefa); Analytics.registraEvento("tarefa_finalizada", tarefa); return TAREFA_PROCESSADA; } catch (TarefaInterrompidaException e) { Log.error(e, String.format("Processo da tarefa %d foi interrompido.", codigoTarefa)); Analytics.registraEvento("tarefa_interrompida", tarefa); return TAREFA_NAO_PROCESSADA; } } Agora, além da execução da regra de negócio previamente expressa pelo código, também estamos lidando com diversas chamadas de logs e análises sobre o uso desta funcionalidade. Analisando, não do ponto de vista da instrumentação da observabilidade, mas tecnicamente, com certeza, a manutenibilidade deste código caiu. Primeiro que se essa implementação for crucial para o negócio, ela deveria ser garantida com testes unitários. Além disso, a regra de negócio, que antes era claramente expressa, agora, está ofuscada com o uso dessas bibliotecas. Cenários como este são comuns de se ver nos mais diversos sistemas e, geralmente, não parece soar muito bem um “código voltado à observabilidade” e um “código voltado ao domínio”, juntos. Então, existe solução? Vamos entender melhor a seguir. Solução para o Case de Observabilidade Pensando na legibilidade do código escrito, instintivamente, acabamos pensando na criação de pequenos métodos que abstraiam esse conteúdo confuso de dentro do executaTarefaPeloCodigo, isolando o código voltado ao domínio do código voltado às análises. Porém, neste caso, a observabilidade introduzida é um requisito do negócio, portanto, mesmo sendo um “código voltado às análises”, ele continua sendo um “código voltado ao domínio”. Entenda melhor na imagem abaixo: Ou seja, nem todo código voltado ao domínio é voltado à observabilidade e nem todo código voltado à observabilidade é voltado ao domínio, mas há, em alguns casos, uma intersecção entre estes, como no nosso case apresentado. Por fim, também recomendamos fortemente a extração das Strings “mágicas”, pois torna a leitura mais agradável e mais fácil de entender o que cada uma representa. Talvez a introdução de alguns ENUMs também seja válida para abstrair o que seria os “trackings de eventos”, como tarefa_iniciada e tarefa_finalizada, mas não vamos nos aprofundar neste assunto, pois não é o foco. public boolean executaTarefaPeloCodigo(Integer codigoTarefa) { Tarefa tarefa = recuperadorTarefas.recuperaPeloCodigo(codigoTarefa); if (tarefa == null) { metrificaQueTarefaNaoExiste(codigoTarefa); return TAREFA_NAO_PROCESSADA; } try { metrificaQueTarefaFoiIniciada(tarefa); tarefa.iniciaProcesso(); metrificaQueTarefaFoiFinalizada(tarefa); return TAREFA_PROCESSADA; } catch (TarefaInterrompidaException e) { metrificaQueTarefaFoiInterrompida(tarefa); return TAREFA_NAO_PROCESSADA; } } private void metrificaQueTarefaNaoExiste(Integer codigoTarefa) { Log.warn(MENSAGEM_TAREFA_INEXISTENTE, codigoTarefa); } private void metrificaQueTarefaFoiIniciada(Tarefa tarefa) { Log.info(MENSAGEM_TAREFA_INICIADA, tarefa.getCodigo()); Analytics.registraEvento(TAREFA_INICIADA, tarefa);} private void metrificaQueTarefaFoiFinalizada(Tarefa tarefa) { Log.info(MENSAGEM_TAREFA_FINALIZADA, codigoTarefa); Analytics.registraEvento(TAREFA_FINALIZADA, tarefa);} private void metrificaQueTarefaFoiInterrompida(Tarefa tarefa) { Log.error(e, String.format(MENSAGEM_TAREFA_INTERROMPIDA, codigoTarefa)); Analytics.registraEvento(TAREFA_INTERROMPIDA, tarefa);} Este é um bom começo, com o código de domínio voltando a ser bem escrito ─ isso, claro, se você considerar que seu “código de domínio” é apenas o método executaTarefaPeloCodigo. Observando nossa classe, não leva muito tempo para notarmos que fizemos uma troca. Se extrairmos de dentro do método original vários outros métodos de metrificação os quais não se encaixam com o objetivo principal da classe GerenciadorTarefas, estamos apenas “jogando o problema para debaixo do tapete”. Quando algo assim acontece, geralmente nos indica que uma nova classe está querendo emergir. Portanto, talvez, a mais simples solução seja a segregação dessa classe em duas: uma para lidar com as métricas e outra para o processamento das tarefas. Ou seja, nossa proposta é a criação de uma nova classe responsável especificamente pelas análises e logs da aplicação, assim como demonstrado no desenho abaixo. Esta também é uma boa solução pois a segregação das responsabilidades originais e o encapsulamento das funções de métricas em uma nova classe, somado à possível injeção de dependências introduzida, favorece o design para testabilidade do GerenciadorTarefas, que é detentor das nossas regras de domínio. Podemos reforçar ainda mais essa ideia pensando no fato de que Java é uma linguagem orientada a objetos (POO) e a testabilidade de uma classe que utiliza de métodos estáticos é reduzida caso o método modifique um estado externo a si, e, geralmente, bibliotecas de logs atendem a este requisito. Desta forma, o resultado do nosso GerenciadorTarefas seria o seguinte: public class GerenciadorTarefas { private static boolean TAREFA_PROCESSADA = true; private static boolean TAREFA_NAO_PROCESSADA = false; private RecuperadorTarefas recuperador; private MetificadorTarefas metrificador; public GerenciadorTarefas(RecuperadorTarefas recuperador, MetificadorTarefas metrificador) { this.recuperador = recuperador; this.metrificador = metrificador; } public boolean executaTarefaPeloCodigo(Integer codigoTarefa) { Tarefa tarefa = recuperador.recuperaPeloCodigo(codigoTarefa); if (tarefa == null) { metrificador.metrificaQueTarefaNaoExiste(codigoTarefa); return TAREFA_NAO_PROCESSADA; } try { metrificador.metrificaQueTarefaFoiIniciada(tarefa); tarefa.iniciaProcesso(); metrificador.metrificaQueTarefaFoiFinalizada(tarefa); return TAREFA_PROCESSADA; } catch (TarefaInterrompidaException e) { metrificador.metrificaQueTarefaFoiInterrompida(tarefa); return TAREFA_NAO_PROCESSADA; } }} O processo de segregação da classe GerenciadorTarefas e o encapsulamento das métricas é chamado de Observabilidade Orientada ao Domínio, e a nova classe gerada é o nosso tão cobiçado Domain Probe. O nome deste padrão de projetos, “Domain Probe”, remete à “Sonda de Domínio”. Este nome não poderia ser mais adequado visto que nossa classe literalmente age como uma “sonda”, em uma classe que anteriormente carecia do levantamento de métricas. Como testar a observabilidade orientada a domínio? Antes de testar a observabilidade de fato, vamos retomar a primeira versão da nossa classe, e tentar imaginar um cenário de teste. public class GerenciadorTarefas { private static boolean TAREFA_PROCESSADA = true; private static boolean TAREFA_NAO_PROCESSADA = false; private RecuperadorTarefas recuperador; public GerenciadorTarefas(RecuperadorTarefas recuperador) { this.recuperador = recuperador; } public boolean executaTarefaPeloCodigo(Integer codigoTarefa) { Tarefa tarefa = recuperador.recuperaPeloCodigo(codigoTarefa); if (tarefa == null) { return TAREFA_NAO_PROCESSADA; } try { tarefa.iniciaProcesso(); return TAREFA_PROCESSADA; } catch (TarefaInterrompidaException e) { return TAREFA_NAO_PROCESSADA; } }} Se você está acostumado a fazer este tipo de análise, vai perceber alguns cenários: Ou não existe tarefa com o código informado, retornando FALSE; Ou existe tarefa e seu processamento é concluído, retornando TRUE; Ou existe tarefa e seu processamento é interrompido, retornando FALSE; Para simplificar, vamos utilizar apenas o terceiro cenário como exemplo. Abaixo, podemos observar como seria a implementação desta classe de testes. public class GerenciadorTarefasTest { private static final Integer CODIGO_TAREFA = 1; private GerenciadorTarefas gerenciadorTarefas; private RecuperadorTarefas recuperador; @BeforeEach public void setUp() { this.recuperador = Mockito.mock(RecuperadorTarefas.class); this.gerenciadorTarefas = new GerenciadorTarefas(recuperador); } @Test public void deveRetornarFalso_casoOcorraErroDeProcessamento_quandoExistirTarefaComCodigoInformado() throws TarefaInterrompidaException { doReturn(criaTarefaComExcecaoEmbutida()).when(recuperador).recuperaPeloCodigo(eq(CODIGO_TAREFA)); Boolean foiExecutado = gerenciadorTarefas.executaTarefaPeloCodigo(CODIGO_TAREFA); assertFalse(foiExecutado); } private Tarefa criaTarefaComExcecaoEmbutida() throws TarefaInterrompidaException { Tarefa tarefa = Mockito.spy(new Tarefa(CODIGO_TAREFA)); doThrow(new TarefaInterrompidaException()).when(tarefa).iniciaProcesso(); return tarefa; } } Seguindo o padrão GWT de nomenclatura (Given - When - Then), podemos expressar nossa regra de negócio no teste. Porém, vale mencionar que aqui estamos traduzindo e “abrasileirando” a escrita da GWT (Given - When - Then), transformando em “DCQ” (Deve ─ Caso ─ Quando). Dessa forma, usamos o DCQ significa: “Deve retornar falso”, que é equivalente à “Then returns false”; “Caso ocorra erro de processamento”, que equivale à expressão “When a processing error occurs”; “Quando existir tarefa com o código informado”, que representa o mesmo que “Given an existing task with the informed code”. A partir disso, quando reimplementamos nossa observabilidade, nossa classe GerenciadorTarefas volta a ser assim: public class GerenciadorTarefas { private static boolean TAREFA_PROCESSADA = true; private static boolean TAREFA_NAO_PROCESSADA = false; private RecuperadorTarefas recuperador; private MetificadorTarefas metrificador; public GerenciadorTarefas(RecuperadorTarefas recuperador, MetificadorTarefas metrificador) { this.recuperador = recuperador; this.metrificador = metrificador; } public boolean executaTarefaPeloCodigo(Integer codigoTarefa) { Tarefa tarefa = recuperador.recuperaPeloCodigo(codigoTarefa); if (tarefa == null) { metrificador.metrificaQueTarefaNaoExiste(codigoTarefa); return TAREFA_NAO_PROCESSADA; } try { metrificador.metrificaQueTarefaFoiIniciada(tarefa); tarefa.iniciaProcesso(); metrificador.metrificaQueTarefaFoiFinalizada(tarefa); return TAREFA_PROCESSADA; } catch (TarefaInterrompidaException e) { metrificador.metrificaQueTarefaFoiInterrompida(tarefa); return TAREFA_NAO_PROCESSADA; } }} É importante lembrarmos aqui que nenhum comportamento foi alterado com o incremento da observabilidade. Portanto, o teste feito anteriormente continua cumprindo seu papel mesmo estando desatualizado. No máximo, o que ocorreria neste caso é um erro de compilação, que já serviria de aviso aos testes que esta classe agora possui uma nova dependência. Sendo um incremento da nossa regra de negócio original, nada mais justo do que incrementar os testes garantindo as invocações corretas de nosso instrumentador. Veja o exemplo a seguir: public class GerenciadorTarefasTest { private static final Integer CODIGO_TAREFA = 1; private GerenciadorTarefas gerenciadorTarefas; private RecuperadorTarefas recuperador; private MetificadorTarefas metrificador; @BeforeEach public void setUp() { this.recuperador = Mockito.mock(RecuperadorTarefas.class); this.metrificador = Mockito.mock(MetificadorTarefas.class); this.gerenciadorTarefas = new GerenciadorTarefas(recuperador, metrificador); } @Test public void deveRetornarFalso_casoOcorraErroDeProcessamento_quandoExistirTarefaComCodigoInformado() throws TarefaInterrompidaException { doReturn(criaTarefaComExcecaoEmbutida()).when(recuperador).recuperaPeloCodigo(eq(CODIGO_TAREFA)); Boolean foiExecutado = gerenciadorTarefas.executaTarefaPeloCodigo(CODIGO_TAREFA); Mockito.verify(metrificador, times(1)).metrificaQueTarefaFoiIniciada(any()); Mockito.verify(metrificador, times(1)).metrificaQueTarefaFoiInterrompida(any()); Mockito.verifyNoMoreInteractions(metrificador); assertFalse(foiExecutado); } private Tarefa criaTarefaComExcecaoEmbutida() throws TarefaInterrompidaException { Tarefa tarefa = Mockito.spy(new Tarefa(CODIGO_TAREFA)); doThrow(new TarefaInterrompidaException()).when(tarefa).iniciaProcesso(); return tarefa; } } Aproveitando a dependência de um instrumentador dentro do nosso GerenciadorTarefas, podemos ainda injetar uma classe falsa para verificar apenas o número de invocações de cada método. No teste acima, verificamos se os métodos metrificaQueTarefaFoiIniciada e metrificaQueTarefaFoiInterrompida foram invocados, e então garantimos que mais nenhuma outra interação é feita com nossa classe instrumentadora. Assim, caso uma nova métrica surja, haja refatoração ou mudança na regra de negócio, teremos testes que garantem aquilo que o negócio espera, ou esperava. Opinião do Autor Este artigo é, em grande parte, uma releitura do estudo Domain-Oriented Observability, escrito por Pete Hodgson em 2019, e também inclui a visão de diversos outros autores sobre o assunto, inclusive a opinião pessoal do autor, Felipe Luan Cipriani, tech writer convidado pelo grupo Softplan.. Quando li o artigo de referência “Domain-Oriented Observability” pela primeira vez, não me surpreendi com algo revelador, pois já conhecia o método. Porém, depois de algumas conversas com colegas próximos e mais algumas tentativas de compreender a totalidade do artigo, percebi como o subestimei. Domain Probe não aborda encapsulamento, segregação ou injeção de dependência ─ embora estes sejam todos elementos que o compõem ─, mas sim a importância das métricas, e sua relevância para o negócio. E embora o padrão de projeto Domain Probe tenha semelhanças com um Facade, ele se preocupa com a essência de todo sistema: o domínio. Por isso, ele tem seu valor. Este é um padrão de projetos essencial de se conhecer e aplicar onde quer que haja instrumentos de métricas em um domínio que não tenha sido feito ou pensado para ser fácil de ler, interpretar, ou dar manutenção. Afinal, desenvolvedores passam mais tempo lendo códigos do que escrevendo. Além disso, este é um padrão de projetos com extrema flexibilidade no quesito de granularidade. Ou seja, você pode criar desde um Domain Probe para cada classe de domínio, sendo esta abordagem mais “específica”, a até mesmo um Domain Probe “genérico”. Não existe uma abordagem errada, apenas diferentes abordagens. Outro tipo de implementação de uma Observabilidade Orientada ao Domínio é através de eventos. Neste cenário, o padrão de projetos da vez é o Observer, e sua abordagem é igualmente interessante, valendo a pena um artigo dedicado somente a ele. Por fim, agradeço a você, caro(a) leitor(a), pelo seu tempo e interesse. Recomendo que leia os artigos dos links presentes no decorrer deste artigo e, se você gostou do conteúdo, tem alguma dúvida ou deseja iniciar uma discussão sobre a temática, deixe seu comentário abaixo!

Caching: o que é e como funciona
Tech Writers Fevereiro 27, 2023

Caching: o que é e como funciona

Atualmente, quando utilizamos sistemas para gerenciar informações, necessitamos cada vez mais de dados precisos e rápidos, e com isso criamos um paradoxo entre quantidade x velocidade.  Os usuários de sistemas buscam por informações mais rápidas para otimizar melhor o tempo de seus processos. No entanto, associa-se a velocidade também à quantidade de informações e estas duas necessidades acabam conflitando.   Isso porque quanto maior a quantidade de informações requeridas, a velocidade de processamento ou disponibilidade destas informações diminuem consideravelmente.  Diante deste cenário, como poderíamos conciliar tais distintas e acopladas demandas?  O que é caching?  Caching é uma técnica de armazenamento intermediário de dados da aplicação, feitos através de hardware ou software. Ela serve para prover um acesso mais rápido a determinadas informações do que acessar diretamente a base de dados da aplicação.  Enquanto uma base de dados é focada em gerir as informações, o cache tem como direcionamento a leitura destes dados, não se preocupando com demais operações, pois esta tarefa já está sendo atribuída.  Com isso temos um acesso mais rápido e direto, ganhando em tempo e performance do acesso a estes dados.  Caching é uma importante feature para as aplicações, pois ganha em velocidade e performance na obtenção dos dados. Entretanto existe um grande “depende” nesta solução, pois, necessariamente nem todas as aplicações realmente necessitam do uso de caching. Antes de aplicarmos tal conceito devemos sempre analisar a aplicação e a real necessidade perante o uso de caching.  Devo utilizar caching na minha aplicação?  Sempre é importante fazer esse questionamento para evitar trabalho desnecessário. Veja algumas questões importantes a considerar:  Eu realmente preciso melhorar a performance da minha aplicação?  Os meus usuários estão insatisfeitos com a performance?  Seria possível alcançar a performance que desejo de outra maneira? Por exemplo, otimizando consultas, criando índices no banco e alterando estrutura dos dados.  Estas e outras questões podem nos ajudar a validar se realmente temos a necessidade de utilizar caching em nossa aplicação.  Onde posso utilizar caching?  1 - Sistemas com foco na leitura de dados  Consiste em sistemas que a quantidade de leitura dos dados é significativamente   maior do que a quantidade de escrita. Desse modo, o uso de caching pode ser uma solução para escalar tal aplicação.  2 - Tolerância do estado do dado  Sistemas que contém dados que não precisam apresentar a sua versão atual e que possam ser atualizados na base e na aplicação, além de não precisarem de atualização por determinado tempo. Nestes casos, o cache pode ser uma solução para armazenar um valor determinado.  3 - Dados que não se alteram frequentemente  Para sistemas que os dados não se atualizam com frequência, o caching pode ser utilizado armazenar por um determinado tempo e consultar sempre de acordo com a necessidade da aplicação.  Eventos de caching  Podemos classificar o cache tendo dois tipos de eventos: Hit e Miss.  Hit  O dado buscado se encontra no cache quando a aplicação efetua a consulta, obtendo uma resposta mais rápida e leve.  Miss  O dado buscado pela aplicação não se encontra no cache, fazendo com que a aplicação tenha que buscá-lo diretamente na base de dados efetuando uma chamada adicional.  Principais estratégias de caching  Existem algumas estratégias de caching que podem ser utilizadas para efetuar o processo de caching. As mais comuns são:  Cache-aside Pattern  Esta estratégia de leitura consiste na aplicação com acesso a ambas as bases: cache e database. Ela se baseia na aplicação buscando o dado no cache e retornando para a aplicação. Porém se este dado não for encontrado no cache, a aplicação vai buscar diretamente da base dados e retornar para a aplicação, e posteriormente inserir na base de cache.  Read through / Lazy Loading  Esta estratégia de leitura consiste na aplicação que não tem acesso a base de dados, apenas a base de cache. Ela solicita o dado ao cache e, caso encontre, prossegue retornando-o para a aplicação. Caso não consiga encontrar a informação, o próprio cache vai até a base, encontra o dado solicitado e o insere na base de cache, e só então retorna-o para a aplicação.  Read-Through é uma estratégia muito semelhante a Cache-aside, mas a diferença é que nesta estratégia a aplicação sempre irá buscar da base de cache.  Write through  Esta estratégia de escrita consiste no cache que consegue armazenar todos os dados da base, que sempre devem ser atuais.  Toda vez que a aplicação escreve algum dado, primeiramente ele armazena no cache e depois armazena no banco de dados. Dessa forma, o cache sempre tem a versão mais recente da informação sendo uma réplica da base de dados. Esta aplicação sempre lê apenas da base de cache.  Write through é voltada para sistemas onde a leitura não pode ser em hipótese alguma obsoleta. Entretanto, podem existir dados armazenados e não lidos já que ele acaba armazenando tudo.  Write-back (Write-behind)  Nesta estratégia de escrita, o dado não é escrito na base imediatamente, pois a aplicação segue escrevendo no cache e depois de um certo tempo sincroniza na base dados, atuando em lotes de informações a serem inseridas.  Um dos problemas desta estratégia é que se o cache tiver algum problema, os dados que ainda não foram sincronizados serão perdidos. Além disso, se houver algum tipo de operação direta no banco de dados esta operação pode não utilizar a versão atualizada dos dados.  Caching implemetation  Para aplicarmos as estratégias de cache apresentadas anteriormente, devemos escolher uma implementação de caching. Existem várias alternativas e desde que o local de armazenamento do cache seja mais rápido do que o acesso ao banco, já é de grande valor.  Quando estamos falando de cache, geralmente o seu armazenamento é feito através de “chave/valor”.  Abaixo apresentaremos 3 tipos comuns de implementação de caching.  In-Memory  In Memory caching consiste no armazenamento de dados de caching na própria memória do serviço. Este formato é o mais rápido, pois trabalha com um acesso direto, assim como uma simples variável da aplicação.  Apesar de ser o mais rápido e fácil de implementar, também traz alguns problemas. Por exemplo, por armazenar na memória do serviço se o mesmo acabar caindo, os dados de cache serão perdidos também.  Esta implementação é recomendada quando lidamos com serviços únicos ou menores, e que tenham poucos dados a serem armazenados no cache.  Remote  Nesta implementação os dados de caching são armazenados em um serviço externo, como o Redis ou Memcached, e não vinculado ao serviço de aplicação.  Neste formato, o dado se torna resiliente a queda do serviço de aplicação, pois é desacoplado do mesmo e tem seu próprio serviço.  Este modelo de implementação se faz robusto e recomendado para quando se tem dados oriundos de vários serviços distintos ou em grande.  Remote Distributed  Ambos os modelos de implementações citados acima sofrem quando o assunto é escalabilidade. A quantia de dados que podem ser armazenados em cada implementação é limitada, e isso acontece porque ambos dependem apenas de um único servidor, seja ele local ou externo.  Porém, quando necessitamos gerenciar maiores quantidades de dados, podemos usar o modelo de implementação externo e distribuído, onde distribui-se o cache entre múltiplas instâncias do servidor de cache.  Se a quantidade atual for insuficiente, então é possível adicionar novos cluster e com isso ter meios de escalar a quantidade de dados possíveis a serem armazenados, facilitando a escalabilidade deste serviço de caching.  Conclusão  Caching é um conceito fácil de compreender, sua implementação também é simples e os resultados aparecem já com pequenas aplicações, independente da estratégia e do modelo utilizado.  Mas nem sempre será o salvador de uma aplicação e necessariamente não são todas que devem utilizar desta estratégia. Porém, se este for o caso, é de grande ajuda utilizá-la.  Referências  https://kislayverma.com/software-architecture/architecture-patterns-caching-part-1/ https://blog.devgenius.io/caching-strategy-101-3bc974d2a6cd https://levelup.gitconnected.com/avoid-using-cache-in-your-application-or-do-it-right-9650214797bc https://dev-abhishek-gautam.medium.com/the-definitive-guide-to-caching-f7441f6932b7

Entenda o Hackathon: O que é e qual é a sua importância
Tech Writers Fevereiro 14, 2023

Entenda o Hackathon: O que é e qual é a sua importância

Tanto para pessoas que estão buscando desafios no mercado, quanto para empresas que precisam de alternativas fora da caixa, o Hackathon é um ótimo caminho.  O Hackathon é capaz de contribuir com soluções inovadoras, pois promove ricas discussões e muito desenvolvimento entre profissionais. Se você ainda não sabe do que se trata um Hacksthon, fique comigo até o fim deste artigo.  O que é um Hackathon?    A origem do termo Hackathon se deu pela combinação das palavras programar e maratona.  Hack (programar)    Marathon (maratona)    Os Hackathons são eventos que reúnem pessoas interessadas em trabalhar questões específicas desenvolvendo soluções de forma rápida e única.    Embora a palavra Hackathon tenha origem na palavra programar, não são eventos focados apenas em programadores (pelo menos não mais). Atualmente, contam com a contribuição de outros profissionais, principalmente os especialistas em inovação, gestores, designers, desenvolvedores e usuários.    Nos Hackathons são discutidas ideias e projetos a serem desenvolvidos, considerando sempre as opiniões, os recursos e também os conhecimentos dos profissionais participantes.    De forma sintetizada, podemos dizer que a importância desses eventos se dá por todas as suas capacidades, dentre as quais destaco três:    O incentivo da produção e do trabalho coletivo;   A integração de várias frentes no desenvolvimento do projeto;   Soluções inovadoras.    Por esses e outros motivos, um Hackathon é uma excelente forma de fomentar a inovação nas empresas.     Quem pode participar dos Hackathons?    Geralmente o evento reúne profissionais que possuem relação com tecnologia, inovação e desenvolvimento de novas soluções, mas não há restrições com relação aos participantes, já que estes eventos são propícios para grandes aprendizados.    Curiosidade sobre o Hackathon:    É bastante comum a participação interna e externa, ou seja, profissionais de dentro e de fora das empresas, sendo essa característica muito positiva para reunir conhecimento e gerar bons resultados. Aliás, os bons resultados dos Hackathons são os motivos pelos quais profissionais de áreas como o Recursos Humanos usam-os como forma de treinamento e desenvolvimento dos colaboradores de todos os setores das organizações.    O planejamento de um Hackathon    Não há um padrão no planejamento de um Hackathon. As diretrizes do planejamento ficam a critério de cada empresa ou projeto. Lembrando somente que tudo deve estar alinhado com os objetivos.    No entanto, vale ressaltar a existência de alguns pilares de planejamento. Vejamos:      Identificação do problema/dor  A identificação do problema/dor é o primeiro passo para planejar um Hackathon, pois, com isso, é possível definir o objetivo esperado do evento.   Formato do evento   Além do modelo de evento corporativo, ele também pode acontecer no formato de competição entre as equipes.   Regras e orientações    Para que o planejamento aconteça de forma correta, é importante definir as regras para participação e desenvolvimento ainda no começo.    Público, data e local   Outro ponto importante é a definição dos convidados, do momento e do local de realização do Hackathon.   Intervalos e descansos    Para que um planejamento e desenvolvimento seja efetivo, é preciso prever descansos e intervalos para toda a equipe.    Comunicação e divulgação   Fazer um bom plano para divulgar o Hackathon é fundamental para atrair os melhores profissionais do mercado e alcançar os objetivos.   Agora que você já sabe o que é um Hackathon, deixe um comentário sobre como este artigo te ajudou e compartilhe com colegas que também possam se interessar por ele. 

Teste de unidade: Como identificar a eficácia de um teste? 
Tech Writers Janeiro 17, 2023

Teste de unidade: Como identificar a eficácia de um teste? 

Um teste de unidade é um tipo de teste automatizado que verifica uma parte específica de um código de maneira rápida e isolada. O objetivo de um teste de unidade é garantir que o código esteja funcionando corretamente e que esteja fazendo o que é esperado dele. Ou seja, ele:  Verifica uma parte pequena do código;   De maneira rápida;   E de uma maneira isolada.    Os desenvolvedores realizam os testes de unidade durante o processo de desenvolvimento do código, com o objetivo de identificar possíveis problemas ou erros de maneira rápida e precisa.   Eles também são úteis para garantir que o código continue funcionando corretamente mesmo após alterações ou refatorações.  Os testes de unidade são, geralmente, realizados em conjunto com outros tipos de testes, como testes de integração e testes de sistema, para garantir que a aplicação esteja funcionando de maneira adequada.  Neste conteúdo, vamos ajudar você a entender quais parâmetros utilizar para identificar quando um teste de unidade é bom ou não.  Princípios de um teste de unidade eficaz  Mais do que verificar se o código "roda" ou não, é importante garantir que o comportamento esperado da aplicação vai ser realizado sem erros, atingindo o objetivo final do negócio.   Dessa forma, é válido reiterar que testes automatizados não avaliam somente o código, mas o comportamento esperado daquele domínio de negócio.   Hoje em dia, a importância dos testes automatizados é amplamente reconhecida nos projetos de software com objetivo de garantir escalabilidade com qualidade.   Vladimir Khorikov, em seu livro Unit Testing: Principles, Practices and Patterns, propõe que é necessário pensar além de simplesmente fazer testes, mas também dar uma atenção especial para a qualidade, de maneira que os custos envolvidos na sua concepção e manutenção sejam os menores possíveis.    Segundo o autor, essa necessidade surgiu pois a busca por uma meta de cobertura de testes de unidade nos projetos acaba gerando uma quantidade grande de testes, que em alguns casos não identificam possíveis bugs no sistema e comprometem uma parte significativa do tempo de desenvolvimento.   Dessa forma, a seguir, apresentaremos os principais indicadores ao avaliar a eficácia de um teste de unidade ou não.  4 principais indicadores de um teste de unidade eficaz  Já trabalhou em um projeto onde, a cada mudança realizada, vários testes falham e você não identifica o porquê? Já teve que lidar com testes de difícil compreensão e foi necessário um tempo considerável para analisá-los?   Esses são alguns indicativos que apontam ser necessário repensar os testes de um projeto.   A seguir, vamos apresentar os quatro principais pontos, de acordo com Vladimir Khorikov, que nos ajudam a reconhecer bons testes de unidade.   Proteção contra regressão  A regressão é um bug no software e os testes devem ter capacidade de identificá-los. Quanto maior a quantidade de código de uma aplicação, mais exposta ela está a potenciais problemas.   Para garantir essa proteção, é necessário que os testes executem o máximo de código possível, aumentando a chance de revelar uma regressão.   Além disso, é necessário priorizar códigos de domínio do negócio e aqueles mais complexos, evitando avaliar comportamentos triviais da aplicação, por exemplo, métodos que só passam valores para propriedades de objetos.    A imagem mostra um exemplo de um teste de comportamento trivial. Ele verifica um método que apenas atribui um valor string ao parâmetro Name de um objeto User. O próprio framework realiza essa atribuição.   É necessário evitar esse tipo de teste e focar naqueles mais complexos ou que sejam realmente importantes para o negócio.    Fig 1. Teste de Unidade de código considerado "trivial"   Resistência a refatoração  Refatorar significa mudar um código existente sem alterar o comportamento da aplicação. Muitas vezes, nos deparamos com projetos que tem uma alta cobertura de testes, que atendem nossos objetivos em um primeiro momento, mas a cada refatoração, a cada mínima melhoria, os testes falham.   Nesses casos, é provável que em certo momento, essas falhas vão transformar o teste em um peso, o que está bem longe do seu objetivo.   Para garantir essa resistência, é necessário evitar que o teste esteja acoplado ao código implementado. Ele deve estar focado em "o que" a aplicação deve fazer e não "como".    A seguir vamos apresentar um teste que verifica o envio de uma expressão SQL correta para retornar um usuário com determinado ID. O teste é capaz de identificar bugs, mas existem outras expressões SQL que podem trazer o mesmo resultado.   Uma mudança no código já acarreta em falhas no teste, mesmo que a aplicação retorne o mesmo usuário, ou seja, tenha o mesmo comportamento. É necessário evitar esse tipo de teste.    Fig 2. Teste acoplado ao código implementado (Fonte: Vladimir Khorikov, Unit Testing: Principles, Practices and Patterns, 2020)   Feedback rápido  O feedback rápido é uma das propriedades básicas de qualquer teste de unidade. Quanto maior a velocidade de resposta, mais tempo você tem para lidar com atividades que importam.   Testes longos também tornam a pipeline de Integração Contínua mais onerosa, já que, na maioria dos casos, há uma etapa para executar os testes do projeto. A consequência disso é atraso no deploy da aplicação e aumento nos custos.   Não há um valor exato de tempo considerado bom ou ruim. Se o tempo de execução dos testes está tornando oneroso seu desenvolvimento, é um indício de testes mal construídos.   Ser de fácil manutenção  A manutenção é um elemento que deve sempre ser considerado, se queremos garantir a escalabilidade de nossas aplicações. Testes fáceis de se manter apresentam duas características:    Ser fácil de ler: garantir a legibilidade do código para os desenvolvedores e especialistas no negócio é importante para um entendimento mais rápido do objetivo do teste e redução no custo de manutenção. Testes com menos linhas tendem a ser mais fáceis de serem compreendidos;    Ser fácil de executar: é necessário criar uma infraestrutura para os testes, de forma que suas dependências (por exemplo, base de dados e APIs externas) se mantenham operacionais.    Como vimos, é importante não só saber escrever testes como também fatorá-los de maneira a melhorar a qualidade e dar mais segurança às nossas aplicações.   De qualquer maneira, é necessário avaliá-los a partir dessas quatro características. Isso garante o desenvolvimento de testes que sejam de baixo custo, fácil de se manter e que cumpram seu papel dentro da aplicação.    Este artigo foi escrito baseado no capítulo 4 do livro “Unit Testing: Principles, Practices and Patterns”. Eu sugiro a leitura de todo o material para aqueles que querem se aprofundar sobre esse tema.    *Agradecimento especial ao Valter Rodrigues, do Squad Hades, pelos apontamentos e revisão do texto*.  

Você realmente sabe como a Gestão do Conhecimento impacta no seu negócio?
Tech Writers Novembro 07, 2022

Você realmente sabe como a Gestão do Conhecimento impacta no seu negócio?

A gestão do conhecimento tem se tornado uma ferramenta essencial para empresas que desejam se manter competitivas e em crescimento. Isso porque, a aceleração tecnológica, típica da atualidade, exige constante aprendizado para que o mercado de trabalho seja acompanhado.  O principal papel dessa gestão é promover os canais certos para transferir o conhecimento relevante para clientes, colaboradores, parceiros e fornecedores do seu negócio.  Nesse artigo, vamos explorar esse tema discutindo a aplicabilidade de ferramentas e estratégias da gestão do conhecimento na operação do seu negócio – seja no setor público ou no setor privado.  Gestão do conhecimento: processos e ferramentas de capacitação multicanal Estamos vivenciando um momento único como seres humanos, no qual temos muito mais informações disponíveis do que nossa capacidade de absorver tudo que temos acesso. A revolução nos modelos de aprendizagem foi potencializada pela evolução tecnológica e, aqui estamos: perdidos em um oceano de conhecimento disponível, mas muito mal consumido. É importante que os setores de gestão das empresas percebam, cada vez mais, a importância de garantir e manter suas equipes bem treinadas e prontas para os desafios neste novo cenário. Ele é veloz, incerto, complexo, e nos exige uma grande capacidade de adaptação contínua. Dentro dos conceitos da Gestão do Conhecimento, nos deparamos com algumas iniciativas que podem nos apoiar nos desafios impostos por este momento. Além disso, essas iniciativas conseguem eliminar barreiras geográficas e democratizar o acesso ao conhecimento, garantindo a capilaridade do mesmo em qualquer nível da operação dos negócios. Podemos citar algumas dessas práticas, que juntas, formam uma combinação muito interessante: trilhas de aprendizagem; simulações práticas; implementação de plataformas de Ensino à Distância - EAD (ou LMS - Learning Machine System); gamificação; repositórios de conhecimento; comunidades de prática; imersões usando novas tecnologias; e o sempre “queridinho”, programa de certificação.  Pesquisas recentes mostram que até 40% das pessoas que não recebem um bom programa de capacitação tendem a se desligar da empresa no primeiro ano. Por isso, é importante sempre se questionar:  como está o seu onboarding? A Empresa está realmente preparada para receber novos funcionários e novos clientes?  Estamos todos à mercê de um turnover alto, causado não só pela rápida mudança decorrente da pandemia, mas também pela ausência de uma estratégia sólida de repasse e internalização do conhecimento dentro das empresas. Portanto, o foco é gerar conhecimento e implementar tecnologias capazes de concretizar a qualificação dos times, desenvolvendo a educação corporativa e consolidando uma cultura organizacional baseada no conhecimento. E, falando em formas de aplicar uma boa gestão do conhecimento, nós temos um artigo interessante sobre plataformas LMS para vocês: clique aqui para ler!  Outra dica para processos de gestão de conhecimento que funciona bem aqui na Softplan, é a utilização da ferramenta Eva People. Ela tem foco na automação da comunicação para a jornada de Onboarding. Hoje usamos essa ferramenta não só para os colaboradores da Softplan na Unidade de Setor Público, mas também nas novas capacitações para nossos clientes. Clique aqui para conhecer! Mapeamento e reformulação de processos estratégicos e operacionais Apesar de promoverem a produtividade e o monitoramento da operação do negócio, os processos têm um papel muitas vezes subestimado. No entanto, eles são essenciais. Afinal de contas, representam uma forma estruturada de registrar o conhecimento, o “know-how” que, de fato, faz o seu serviço ou produto chegar aos seus clientes ou usuários. Capturar o passo a passo de cada atividade, visando a documentação da forma mais produtiva de se realizar um trabalho, é uma tarefa árdua de explicitação do que chamamos de conhecimento tácito.  Por este motivo, o mapeamento de processos é uma técnica útil para capturar as melhores práticas e atividades críticas do seu negócio. Certamente, por meio dele, você alcança o alinhamento entre as equipes, o futuro entendimento para novos colaboradores e o padrão de qualidade e assertividade dos procedimentos.  Aliás, todo esse conteúdo é essencial à uma boa estratégia de onboarding, como já mencionamos acima, mas também um repositório fértil para ações de reciclagem de conhecimento. Tal conhecimento será representado, por vezes, na forma de fluxogramas, que descrevem graficamente um processo existente ou um novo processo proposto.  Mas a elaboração de procedimentos, manuais, roteiros, listas de tarefas, instruções de trabalho e até mesmo vídeos demonstrativos disponíveis em um sistema LMS (para ensino à distância) podem proporcionar um detalhamento maior da atuação de cada área do negócio. É importante ressaltar que os processos operacionais/estratégicos e o fluxo de conhecimento de uma empresa não podem ser separados. Isso porque, uma vez que os conhecimentos constituem entradas do processo, eles são utilizados durante o processamento e são gerados como saídas dos processos.  O fluxo de conhecimentos é, portanto, inerente ao processo. Leia mais a respeito no artigo de YOO, SUH e KIM, de 2007: “Knowledge flow‐based business process redesign”: https://www.emeraldinsight.com/doi/pdfplus/10.1108/13673270710752144 Base de conhecimento especializado no seu negócio Seu Suporte vive abarrotado de dúvidas? Seu time de serviços percebe que os usuários, mesmo depois de capacitados, seguem muito dependentes? O cliente reclama de funcionalidades porque não as conhece? Se você respondeu sim para estas perguntas, você já tem o entendimento de que é necessário disponibilizar informação de qualidade aos seus usuários, clientes, consumidores.  Uma base de conhecimento devidamente estruturada e populada irá desafogar o seu time de atendimento, relacionamento e times técnicos, eliminando perguntas rotineiras e repetitivas de sua fila de demandas.  Seus clientes também vão demonstrar maior satisfação quanto às diferentes possibilidades de canais de atendimento, uma vez que poderão solucionar suas dúvidas com maior autonomia e velocidade.  Além do efeito positivo na percepção do cliente, a base de conhecimento permite também que seus colaboradores foquem em atividades mais complexas ou estratégicas, uma vez que as dúvidas simples são resolvidas em outro canal. Vale destacar que o grande desafio não é apenas estruturar uma base de conhecimento e escolher a melhor plataforma para seu consumo. Mas, sim, manter este conteúdo atualizado - coerente, com qualidade e relevância para os seus clientes. Conecte a manutenção da sua base de conhecimento ao ciclo de novidades dos seus produtos e serviços. O processo precisa estar na raiz!  Na Softplan super fazemos uso da base de conhecimento para o segmento da Justiça. Conheça o SAJ Ajuda, implantado através do software Zendesk, atendendo a clientes do Brasil e Colômbia. Link: https://sajajuda.softplan.com.br/hc/pt-br   Comunidades de prática e o poder do networking Uma comunidade de prática tem como objetivo reunir um grupo de indivíduos que se reúnem periodicamente em torno de um interesse comum no aprendizado e na aplicação do conhecimento adquirido. Neste contexto, este aprendizado coletivo é berço de melhorias em processos e sistemas, de inovações no modelo de negócios, e, especialmente, de uma visão muito mais ampla de todo o contexto em que um produto ou serviço será desenvolvido e comercializado.        Ressaltando que este conceito preza pela participação voluntária. Por isso, é importante que as empresas proporcionem um ambiente favorável à discussão de novas ideias de forma natural, segura, respeitosa e sem julgamentos prévios. Além disso, é preciso um planejamento mínimo de tempo para se dedicarem às inovações.  Identifique o período mais produtivo dentro do seu time e reserve as agendas para o espaço aberto. Quem tiver uma pauta, avisa aos demais e aí todos participam. Nada obrigatório, porém estimulado!  Essa troca de conhecimento acontece naturalmente entre grupos ou colegas de trabalho com determinadas afinidades, seja no intervalo do cafezinho ou no almoço, seja nos corredores ou em momentos de diversão destas pessoas. Quem nunca saiu do “happy hour” como ideia que não tinha sequer imaginado?  Os participantes dessas comunidades se beneficiam de recursos de comunicação rápida e informal como WhatsApp, e-mails, fóruns de discussão e plataformas como o Slack.  Mas, cuidado para não se perder no histórico. Todo canal de compartilhamento e colaboração é bem-vindo. No entanto, é crucial que as pessoas consigam localizar a informação facilmente depois do debate. Uma organização mínima dos temas é fundamental para que a ideia não se perca.  A troca que ocorre nas comunidades de prática permite a expansão do conhecimento organizacional. Nelas, ele deixa de ser apenas individual e passa a cristalizar-se na rede de conhecimento da organização, compreendendo toda sua dinamicidade e volatilidade.  Uma observação importante:  as comunidades de prática também acontecem em plataformas externas, sem conexão direta com as empresas. Busque no Linkedin os grupos de conteúdo. Dessa forma, você vai descobrir uma série de possibilidades de contatos e conhecimentos!  Banco de ideias para o funil de inovação Trata-se da associação de um repositório a um processo estruturado para captar, avaliar e acompanhar as novas ideias geradas nos diferentes grupos de trabalho ou até em iniciativas individuais dos colaboradores, especialmente para implementações em novos produtos ou serviços.  É a evolução do conceito de “caixinhas de sugestões” para coletar e selecionar de forma sistemática ações para melhorar operações, sugestões de novos processos e produtos, aplicações de novos controles e serviços, atuação mediante a concorrência, além de relatos de experiências que podem promover uma revolução no modelo de negócio.  Associe a coleta de ideias aos processos de desenvolvimento das mesmas, tais como: Brainstorming, Design Thinking e Prototipagem. O que importa é incentivar! Essa prática pode ser utilizada pelos colaboradores conforme a estratégia mais adequada para a empresa, muitas vezes associada à solução de problemas específicos em cada ciclo de ideação e vinculada a ações de gamificação e reconhecimento para as melhores ideias. Uma boa forma de estimular é fazer rodadas lançando desafios, puxando temas específicos, e permitindo que pessoas de diferentes times possam atuar neste processo, ainda que não seja um tema diretamente ligado à sua atuação.  Essa também é uma excelente forma de identificar talentos e promover a evolução de carreira dos colaboradores.  Ah, e sim, seus clientes também podem participar! Trazê-lo para essas discussões pode levantar propostas ainda não imaginadas. Quando o cliente é englobado nos processos, aumenta-se também, a chance de fidelização.  Aqui, uma dica com ferramentas para coletar ideias: https://aprendeai.com/criatividade/ferramentas-de-criatividade-e-geracao-de-ideias/ Gamificação para atrair os jogadores escondidos na sua operação A atual geração de colaboradores em sua empresa ou nos times dos seus clientes cresceu sob influência de diversos tipos de jogos durante a sua infância e adolescência.  A atual importância do mercado de “games” revela o potencial dos elementos de jogos na revolução tecnológica e também na disseminação do conhecimento. Gamificar a aprendizagem é transformar o processo de capacitação em uma jornada com senso de pertencimento e com estímulos claramente definidos. Dessa forma, é possível proporcionar, por meio dos elementos de jogo, novas estratégias para criação, coleta, disseminação e absorção de novos conhecimentos. Essa técnica pode tornar as pessoas capazes de desenvolverem habilidades e competências voltadas para o objetivo do seu negócio e atendimento dos seus clientes. Alguns games foram desenvolvidos para promover os processos de Inteligência Organizacional (IO) e Gestão do Conhecimento (GC) nas organizações. O jogo “The Corporate Machine”, por exemplo, visa a dominação do mercado que sua empresa ocupa. Ou seja, ensinar sobre estratégia de forma lúdica.  Observa-se que a gamificação como processo é, de fato, um importante aliado para o desenvolvimento do processo de Inteligência Organizacional, bem como para a Construção e Gestão do Conhecimento no âmbito das organizações.  Conheça aqui o jogo “The Corporate Machine”: https://g.co/kgs/R3Ng58  Sim, a gestão por indicadores é parte da Gestão do Conhecimento Quem nunca ouviu a máxima: o que não se mede não se gerencia?  Lembre-se que medir envolve conhecer os processos, suas métricas e os resultados esperados. Um vasto conhecimento é gerado a partir dos indicadores de desempenho de processos, uma vez que eles: Disponibilizam dados para que o gestor atue em cada etapa do processo, identifique gaps e promova melhorias; Permitem melhor compreensão do cenário e maior previsibilidade para ações futuras; Proporcionam maior exatidão na tomada de decisão pelo gestor, seja de forma preventiva ou reativa para solucionar problemas; Permitem a criação de “dashboards” contendo todas as informações disponíveis em tempo real para ações com o devido timing; Evidenciam os resultados alcançados, fundamentados em fatos e de forma objetiva; Alimentam sistemas de inteligência artificial e machine learning. Portanto, os indicadores são parte do fluxo de conhecimento, uma vez que permitem o entendimento do contexto de processos, produtos e serviços, bem como impulsionam ações rumo às melhorias e inovações necessárias em seu negócio. Além disso, os processos de disseminação do conhecimento também possuem indicadores próprios que retroalimentam os processos de gestão, não só para monitorar resultados, mas para seguir evoluindo nas ações estratégicas.  Na Softplan usamos a ferramenta Appus Skills para realizarmos o diagnóstico de conhecimento técnico e mapeamos as lacunas a serem trabalhadas em nossas capacitações. Recomendo a leitura do blog da Appus, nossa parceira: https://www.appus.com/blog/people-analytics/o-que-e-people-analytics/  Ah, o conhecimento! Algumas empresas de diferentes segmentos já adotaram em suas estruturas uma área ou um cargo referente à Gestão do Conhecimento. Esta área ou este profissional tem como desafio o processo de estruturação, ampliação e manutenção do Capital Intelectual da empresa.  Diversas estratégias, plataformas e procedimentos, tais como os citados neste post, podem promover uma mudança cultural profunda quanto ao valor do conhecimento dentro do seu negócio. Reflita sobre tudo que mencionamos e responda: o que seria da sua empresa sem a disseminação e evolução do conhecimento que ela exige?  Para refletir, lembre-se que:  Você não perde o conhecimento que possui quando o compartilha. Ele se multiplica! Cada um tem sua forma de “aprender com mais facilidade”, e está tudo bem! Porém, ao refletir sobre suas soluções de gestão do conhecimento, pense em diferentes tipos de “aprendizes” e monte estratégias aderentes às suas particularidades.  E, por fim, o conhecimento não se deprecia com o uso, ao contrário dos outros ativos em que o seu valor decorre do uso/consumo. Ele é exponencial! Por Ana Carolina Prado Coordenadora de Conhecimento e Capacitação na Softplan – Unidade Setor Público

Qualidade do código: Saiba como revisar o código, medir sua qualidade e dicas de ferramentas!
Tech Writers Outubro 03, 2022

Qualidade do código: Saiba como revisar o código, medir sua qualidade e dicas de ferramentas!

Desenvolver um código de qualidade é essencial para reduzir a quantidade de bugs nos softwares, facilitar a manutenção do código e reter mais os usuários. Quando uma pessoa utiliza um software, ela espera que este software possa resolver seus problemas e otimizar sua rotina. Se o software apresentar muitos problemas, a pessoa tende a perder a confiança nele e optar por um concorrente. Por isso, hoje, aqui na Softplan, vamos te ensinar o que é um código de qualidade, como revisar seu código e dicas de ferramentas para auxiliar. Confira! O que é qualidade de código?  De maneira geral, a qualidade do código não possui uma definição exata. Cada equipe de desenvolvimento estabelece uma definição para ela, que no geral se resume na união de fatores comuns, como: manutenção, testabilidade, legibilidade e segurança. Ou seja, um código pode ser considerado de qualidade se ele for legível, de fácil manutenção, seguro e simples de testar.  Escrever um código de qualidade ou código limpo envolve uma série de práticas e padrões recomendados durante o desenvolvimento. Definem-se essas práticas já no início do projeto. Seguindo elas, aliado ao uso de ferramentas manuais ou automáticas para medir a qualidade do código, é possível construir um produto com mais segurança. Porque a qualidade do código é tão importante? Implementar um código com qualidade é relevante principalmente pelos seguintes fatores: Reduz a manutenibilidade e otimiza melhorias futuras; Reduz o risco de erros e bugs; Acelera as entregas dos códigos; Auxilia na retenção do cliente; Melhora a experiência da pessoa usuária (UX) com o produto final; Garante maior segurança de dados. Explicando melhor, criar um código de qualidade otimiza as manutenções e melhorias futuras, que ficam mais simples e rápidas de serem implementadas, tornando a dívida técnica pequena. Assim, não é preciso gastar horas procurando um bug em um código macarrônico. Outro benefício é gerar entregas com poucos ou nenhum bug e mais rápidas ao cliente, já que a equipe não vai gastar tantas horas tentando entender um código muito complexo. A qualidade do código também garante uma melhor experiência da pessoa usuária, evitando bugs e problemas de desempenho no produto final. Além disso, ela pode ter um impacto direto no quão seguro é o software. Por exemplo, mesmo pequenos defeitos, como não validar a entrada do usuário, podem deixar um aplicativo exposto a atores mal-intencionados e ataques maiores. Com estes benefícios, o cliente confia cada vez mais no produto entregue a ele, o que ajuda na retenção dos clientes. Todavia, a qualidade de software não se refere somente ao código limpo, mas a um conjunto de fatores que devem ser adotados como documentação, boas práticas, gestão e monitoramento, que serão Quais são as características de um código fonte de qualidade? Para um código fonte ser de qualidade ele deve ser fácil de entender, ter fácil manutenção e deve cumprir suas funções de maneira eficiente As principais características de um código fonte de qualidade são: Legibilidade: O código deve ser fácil de ler e entender para a equipe de desenvolvimento, com uma sintaxe clara, sem abreviações confusas e um estilo de codificação consistente; Simplicidade: Ele deve ser simples e conciso, a fim de reduzir erros e bugs; Modularidade: O código precisa ser dividido em módulos ou funções independentes, cada um com uma responsabilidade clara e bem definida. Isso torna o código mais fácil de testar, depurar e manter; Documentação: É importante documentar o código adequadamente, para ajudar as outras pessoas do time a entenderem a função de cada parte do código; Testabilidade: Deve ser fácil de testar e ter um conjunto abrangente de testes unitários para garantir que ele funcione corretamente; Confiabilidade: Deve ser confiável e lidar adequadamente com erros e exceções, retornando erros claros e informativos quando ocorrerem. Além disso, para garantir a qualidade no código, é importante ter um processo contínuo de revisões e aprimorações constantes. Então, o que é um código ruim? A qualidade do código está relacionada ao seu nível de complexidade e legibilidade. Quando ele está muito complexo, macarrônico, acaba sendo difícil de ser compreendido e receber manutenção. Por isso, é considerado de baixa qualidade. Se o código está mal organizado, não tem documentação, não segue boas práticas da programação e possui comentários mal estruturados ou nenhum comentário que auxilie na sua compreensão, é um sinal de que ele precisa ser revisado. Além disso, um código pode acabar sendo ruim se ele não tiver sido testado, pois isso aumenta as chances de gerar bugs e erros.  O código complexo, além de ter grandes impactos na produtividade da equipe, gera alto custo de sustentação. Isso também pode gerar erros no sistema e incompatibilidades, que quando não tratados rapidamente podem fazer com que o usuário final perca a confiança no produto/software. Como implementar a qualidade do código no dia a dia? Existem alguns pontos que você pode seguir para melhorar a qualidade do código, que farão toda a diferença. São eles: Pense duas vezes antes de criar o código, e quando feito pense se ele se encontra na maneira mais legível possível; Siga práticas melhores, como o S.O.L.I.D (aproveite para conhecer o princípio Singleton); Use ferramentas de qualidade de código como SonarQube. Caso você esteja usando uma IDE como eclipse ou IntelliJ, então você também pode usar o plugin sonar (SonarLint); Não crie validações que já existem em bibliotecas, como isEmpty ou isNull. Muitas bibliotecas de código aberto fornecem diversos métodos para criar validações. Um exemplo é a biblioteca Apache Commons que é um verdadeiro canivete suíço para desenvolvedores; Antes de criar uma classe, pesquise para ver se já não existe outra com a mesma funcionalidade; Procure seu líder imediato ou tech leader, e converse sobre a importância de estabelecer padrões de codificação para melhorar o software em sua totalidade. A importância da documentação na qualidade de código Quando uma equipe passa um projeto para outro time, a ausência de documentação de suporte com o código é sempre um sinal de alerta. Se a equipe de desenvolvimento anterior não fornecer nenhuma documentação, significa a execução inicial do projeto com uma abordagem falha. Provavelmente vai faltar a arquitetura de código e "o quadro geral", podendo facilmente resultar em falha no projeto. Com uma boa documentação disponível, a nova pessoa desenvolvedora que aderir ao projeto pode ter um processo de onboarding de alguns dias em vez de uma ou duas semanas, com uma redução significativa no custo de desenvolvimento. Como medir a qualidade do código? É possível avaliar a qualidade de um código de diferentes formas, como por exemplo, com uma política de code review, através de ferramentas e/ou de feedbacks das pessoas usuárias. As principais formas de medir a qualidade de um código-fonte são: Análise estática de código: Esta técnica examina o código-fonte sem executá-lo, a fim de identificar problemas comuns, como código redundante, variáveis não utilizadas, entre outros; Métricas de código: As métricas de código servem para avaliar o código e podem incluir o tamanho do código, complexidade, índice de coesão, entre outros; Testes de unidade: Ao testar cada parte isolada do código, é possível identificar erros lógicos, de sintaxe, falhas de segurança, etc; Code Review: Implementar uma cultura de revisão de códigos, em que as pessoas desenvolvedoras do time revisam os códigos dos outros profissionais. Isso ajuda a identificar problemas não detectados por ferramentas; Feedbacks das pessoas usuárias: Com feedbacks dos próprios users do seu software, é possível criar relatórios de bugs, avaliar tempo de resposta do sistema, facilidade de uso, entre outros. Além desses pontos, existem ferramentas que fazem uma análise completa de novos códigos enviados aos repositórios. Dicas de Ferramentas para Qualidade do Código Algumas ferramentas podem te auxiliar na hora de garantir a qualidade do seu código fonte. A ferramenta mais famosa é o SonarQube, que verifica quase tudo – qualidade do código, formatação, declarações variáveis, tratamento de exceções com uma integração com pipelines CI/CD, com um comando de linha única. Já a ESLint é uma ferramenta de análise de código estático para JavaScript. Ela consegue verificar se o código está seguindo as regras de estilo e boas práticas. Com a CodeClimate, uma ferramenta de análise de código estático, você pode ter feedbacks sobre complexidade do código, duplicação, cobertura de teste e vulnerabilidades. A Postman é a ferramenta ideal para testar a funcionalidade das APIs, enquanto a CodeFactor te dá informações como cobertura de teste, complexidade e duplicação de código. Além dessas, a GitHub Actions também pode ser usada, já que ela é uma plataforma de automação de fluxo de trabalho. É ideal para executar testes de qualidade de código em um repositório do GitHub. Como revisar o código? Para realizar uma boa revisão de código, é importante compreender o contexto em que o ele está sendo usado, ou seja, seu objetivo, sua arquitetura geral e o público-alvo.  Além disso, alguns fatores são fundamentais na revisão, como, por exemplo, checar se o código está consistente com outros códigos relacionados e se ele está legível, possui documentação e não é redundante. Também é importante testar o código para verificar se possui erros e se funciona como o esperado, além de deixar comentários para apontar melhorias e bugs encontrados. Depois destes passos, o ideal é propor soluções para os problemas encontrados e pedir a opinião de outras pessoas da equipe. Gostou de saber um pouco mais sobre qualidade do código e suas principais implicações? Confira mais conteúdos como este em nosso blog Tech Writers!  E se quiser fazer parte do nosso time, acompanhe nossas vagas na página de carreiras. Gostou de saber um pouco mais sobre Qualidade do código e suas principais implicações? Confira mais conteúdos como esse em nosso blog! Quer ser nosso próximo Tech Writer? Confira nossas vagas na página Carreira! Até a próxima!