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
Introdução aos conceitos de Experiência do Usuário (UX) e seus processos
Tech Writers Dezembro 06, 2021

Introdução aos conceitos de Experiência do Usuário (UX) e seus processos

Neste artigo, mostraremos como a experiência do usuário (UX) está presente em diversos momentos do nosso cotidiano, além disso, vamos: Apresentar seus conceitos básicos;  Ressaltar sua importância e relevância dentro de projetos atuando como direcionador estratégico;  Explicar, brevemente, os processos e atividades relacionados à área.  Observe as situações a seguir: Desespero ao perder o horário pelo despertador não ter tocado; Desconforto por complicações da maquininha ao pagar com cartão; Estresse em longas filas de farmácias ou supermercados; Aborrecimento por não conseguir utilizar o aplicativo do banco e ainda ter a inconveniência de precisar ir até lá para resolver seu problema. Alguma delas já aconteceu com você? Muitas vezes achamos que isso é má sorte, mas será que é mesmo? O que pode ter acontecido: Você perdeu o horário porque desligou o alarme na noite anterior, por ter sido feriado, e o sistema não te perguntou por quanto tempo gostaria de ter deixado desligado; O cobrador estava utilizando uma maquina nova e não conseguiu passar o cartão, pois não sabia mexer nela e as informações estavam muito confusas; As filas estavam gigantes porque “o sistema travou”, como sempre ouvimos dos atendentes; Você precisou ir até o banco, pois o aplicativo não previa ações que você precisaria realizar. Então, a resposta é: não é má sorte! Tudo isso está diretamente relacionado com UX, a experiência do usuário. O que é UX – Experiência do Usuário? Você percebeu que os sentimentos das situações foram destacados? Desespero, desconforto, estresse e aborrecimento.  Quando estes cenários acontecem e sentimentos negativos são despertados, dizemos que a experiência que a pessoa, o usuário, teve com o produto ou serviço foi ruim.   Tudo poderia ser diferente se houvesse uma maior preocupação em ter clareza do problema a ser resolvido: buscar entender como cada decisão de projeto está afetando ou poderá afetar os objetivos e necessidades dos usuários A falta de conhecimento sobre estes pontos faz total diferença entre o sucesso ou fracasso de um produto/serviço e sobre a satisfação ou insatisfação dos usuários com ele.  Mas como garantir a satisfação dos usuários? Em todas as áreas da Softplan temos um centro de competências especializado em experiência do usuário. Na área responsável pelas soluções de Justiça esse centro é  o CCUX (Centro de Competências em User eXperience), o qual conta com uma equipe de designers atuantes em cada vertical do SAJ (Ministérios Públicos, Defensorias, Procuradorias e Tribunais de justiça). É difícil ter certeza se vamos conseguir alcançar a satisfação dos usuários e o sucesso do produto. Afinal, não existe mágica, bala de prata ou remédio milagroso.  No entanto, nossa equipe dedica-se a aumentar as chances disso acontecer, até mesmo antes de ser escrita qualquer linha de código. Para isso, os designers utilizam uma série de conceitos, técnicas e processos que os guiam para proporcionar boas experiências aos usuários e, assim, minimizar chances de falhas dos projetos.Embora eles sejam conhecidos como os profissionais que trabalham diretamente com Experiência do Usuário, é de extrema importância que todos os envolvidos no projeto também tenham uma base de conhecimento sobre os métodos que aplicamos. Isso nos possibilita criar estratégias dentro de equipes multidisciplinares, ou seja, envolvendo outras áreas de atuação e agregando conhecimentos diversos ao projeto, possibilitando assim soluções ainda mais assertivas.  O famoso processo de UX Podemos resumir as etapas do processo de UX em: Descrição da imagem acima: objetivos e estratégias, seta para direita, pesquisa e análise, seta para direita, ideação e protótipo seta para direita, testes e iteração. Cada uma delas possui atividades excelentes que proporcionam o levantamento de dados e insights, além de tornarem todos os esforços do projeto muito mais eficazes.  Isso possibilita que o desenvolvimento de produto siga no caminho certo, de acordo com as verdadeiras necessidades do usuário, e não a partir de suposições.  Em seguida, relatamos brevemente a essência de cada uma delas. Objetivos e estratégias Nessa primeira etapa, precisamos tirar todas as nossas dúvidas sobre o projeto e identificar cenários que ainda precisam ser explorados. Isso é, realizados a partir de um mapeamento de nossas certezas (as quais devem ser fundamentadas com evidências e dados), suposições e dúvidas.  Além disso, também é importante: Buscar por conhecimentos internos documentados; Definir fronteiras e métricas; Planejar uma visão a longo prazo; Conhecer limitações; Esclarecer objetivos de negócio; Objetivos de produto; Identificar ou se aproximar dos atores-chave do projeto. Tudo isso nos possibilita planejar ações ou montar um roteiro para as etapas seguintes.  Pesquisa e Análise Aqui, a aproximação empática com os usuários é fundamental, ou seja, é necessário ter a capacidade de se colocar no lugar do outro para entender suas dores, necessidades e desejos.  Precisamos conhecer bem nossos clientes/usuários, conversar com eles, ficar imersos em suas vidas, entender seu contexto, seu comportamento, e até tentar sentir na pele o que eles sentem antes, durante e depois do contato com o produto/serviço.  Nessa aproximação com os usuários, analisar ações é mais importante do que apenas ouvi-los e anotar seus pedidos.  Devemos diferenciar atitude de comportamento. Ou seja, é necessário distinguir o que eles falam e expressam (suas solicitações, expressões faciais ou corporais), do que eles realmente fazem e como agem (quais informações e ferramentas utilizam, quais caminhos e decisões são tomados).  É importante ter este discernimento porque é comum que os usuários proponham e peçam soluções para problemas que poderiam ser resolvidos de maneiras mais eficazes, com até mais soluções de um problema ao mesmo tempo e que entregassem muito mais valor a ele. Resumidamente, essa etapa de pesquisa visa proporcionar a coleta de dados para validar ou invalidar nossas suposições, responder nossas dúvidas, embasar e direcionar todas as decisões que envolvem o produto.  Depois de ter feito um grande levantamento de evidências e ter conhecido melhor os usuários, coletamos informações concretas e não ficaremos mais reféns das nossas suposições.  Nesta etapa, também vamos analisar e sintetizar essas informações para identificar e definir o foco do problema ou ponto de melhoria do serviço/produto.  É importante frisar que, enquanto não temos total clareza do problema a ser resolvido, é difícil propor soluções que façam a diferença aos usuários. Ideação e protótipo É hora da ideação, ou seja, propor alternativas de solução para os problemas apresentados.  Neste momento é ideal que a discussão seja multidisciplinar e que busque trazer ideias disruptivas.  Não podemos ter medo de ser julgados e nem devemos julgar as ideias dos colegas, essa é a famosa fase de Brainstorming.    Depois de abrir o leque de ideias, é momento de convergir num propósito, selecionar uma solução que tenha maior probabilidade de entregar valor aos usuários, porém, que sejam tecnicamente viáveis de serem implementadas e em prazo plausível.  Faz parte do dia a dia do trabalho do designer balancear as necessidades dos usuários com as limitações técnicas e necessidades de negócio. Testes e iterações “Solução em mãos?! Hora de implementar?”  Calma lá! Que tal fazer um protótipo, ou quem sabe alguns, antes?  A ideia é que sejam protótipos de baixo custo e que sejam colocados em contato com os usuários o quanto antes para que seja possível validar ou invalidar as hipóteses e, o mais importante, falhar o quanto antes!  No CCUX da área de Justiça da Softplan, realizamos protótipos em alta fidelidade, já em HTML e CSS, pois foi a maneira mais eficiente encontrada para testar e coletar feedbacks.  Porém, isso depende muito do contexto e do perfil dos usuários que estão realizando os testes. Caso faça sentido, vale até testar com desenhos!   Durante os testes é essencial observar, ficar atento aos comportamentos dos usuários perante ao protótipo, além de coletar dados e documentá-los, pois em seguida vamos analisá-los mais calmamente e realizar os ajustes necessários de acordo com o que foi visto.  Dica: Nesses momentos é importantíssimo não se apegar às suas soluções, pois, muitas vezes, o que acabamos propondo inicialmente pode não ser a melhor solução que resolva as necessidades e dores dos usuários.  Apaixone-se pelo problema e não pela solução. Se necessário, é possível realizar ainda mais rodadas de testes, com protótipos diferentes, atingir a segurança sobre o que se está entregando, o que será desenvolvido e o que chegará às mãos dos usuários.  Metodologias de cascata, vai contra princípios ágeis? Todo o processo foi descrito linearmente, porém, não devemos nos prender a isso, podemos e devemos voltar atrás quando e quantas vezes acharmos necessário. Logo, a imagem abaixo apresenta o esquema que expliquei anteriormente. Descrição da imagem acima: todas as etapas do processo com setas indo e voltando entre cada uma delas. Utilizamos este processo como um guia, mas a ideia principal é que, conforme vamos conhecendo mais os usuários e tendo mais clareza dos problemas a serem resolvidos, a gente consiga pensar em ideias cada vez mais assertivas para solucionar os seus problemas e entregar produtos/serviços que as pessoas realmente amem. E aí, gostou de conhecer um pouquinho mais sobre os conceitos por trás de UX?  Confira mais conteúdos como esse em nosso Blog!

Proud Tech 2021: Principais insights da Trilha Tech para desenvolvedor de software!
Tech Writers Novembro 29, 2021

Proud Tech 2021: Principais insights da Trilha Tech para desenvolvedor de software!

Quem é desenvolvedor de software sabe que se manter atualizado e entender tudo que o mercado apresenta é um grande desafio.  Nesse sentido, o Proud Tech, evento para quem ama tecnologia e quer estar sempre por dentro desse universo é uma ótima pedida! A edição de 2021 reuniu softplayers e convidados de softplayers para compartilharem conhecimento com outros apaixonados pelo tema.  Dentre as diversas trilhas, estava a Trilha Tech, na qual muitos desses profissionais de referência falaram sobre curiosidades e código legado, inteligência artificial e a importância do não funcional. Por isso, neste conteúdo abordaremos os principais insights, para você saber o que rolou por lá. Veja só: A importância do não funcional para desenvolvedor de software Para entender as abordagens, vale resgatar o que é não funcional para um desenvolvedor de software. Entender esse conceito é importante para saber como superar desafios. Na palestra sobre o tema, Lucélia Siqueira ressalta o que ocorre quando o não funcional é negligenciado. Para permitir esse entendimento, ela chama atenção para a importância de tentar mudar esse cenário.  Retomando explicações sobre o que seria a definição de não funcional, a palestrante também relembra que esse termo diz respeito a atributos de sistema com características como: segurança; confiabilidade; escalabilidade. Em outras palavras, pode ser entendido como o critério para avaliar a operabilidade de um sistema. Para ela, no entanto, ele é tudo o que lastreia as demandas funcionais, garantindo a qualidade do software em desenvolvimento. Assim o profissional consegue aplicar melhorias em seu projeto. Esse requisito é capaz de descrever como o sistema executa alguma tarefa, enquanto o funcional diz o que é que ele executa.  Portanto, é possível não somente conhecer o que o software faz, mas qual o seu desempenho. Validar um bom software sabendo previamente a performance é muito mais seguro e certeiro. Lidando com o código legado  Na linguagem de um desenvolvedor de software, código legado se refere àquele que é geralmente desenvolvido em um primeiro momento sem pensar nos custos que poderão existir depois para manutenção. Isso é um problema, pois sem planejamento adequado ou testes, que são boas práticas, não é possível saber se o software será sustentável a longo prazo. Também não dá para dizer e saber se haverá boa aceitabilidade.  Algumas técnicas de eliminação de dependências são abordadas no livro “Trabalho eficaz com código legado” e são muito importantes para serem conhecidas por um desenvolvedor de software.  Nesta palestra, Jefferson Henrique menciona que essa leitura é uma das mais desejadas para quem trabalha no ramo. Quem não leu deve tê-la em uma lista para fazer isso, por certo. O profissional aborda que esse conceito não é visto somente em empresas antigas, mas também nas novas. Na palestra, é ressaltada uma fala de Michael Feathers, que afirma que código legado é todo aquele que não tem cobertura em testes automatizados. Logo, independente do framework, código legado é todo aquele que não te oferece um feedback. Sem esse retorno, o desenvolvedor sempre trabalha em um “ponto cego”. Sem saber melhor o desempenho da solução, sua manutenção fica ainda mais complicada depois. A  importância da Inteligência Artificial na Justiça brasileira  Outro ponto interessante para um desenvolvedor de software é compreender como a inteligência artificial tem um emprego muito útil na sociedade. Um case bem interessante é discutido na palestra de Mauricio Seiji.  Desse modo, são abordadas funcionalidades da solução de inteligência artificial da Softplan para combate à violência doméstica, que veio para preencher lacunas na organização dos dados. Seiji explica que os Ministérios Públicos têm um papel não só de combate, como também de prevenção desse tipo de problema. Para ajudar a Justiça brasileira, ele participou do desenvolvimento de uma solução que utiliza aprendizagem de máquina para ajudar a identificar quando isso acontece, como veremos adiante. Aplicando a aprendizagem de máquina Utilizando uma técnica específica de aprendizagem de máquina, chamada classificação de textos, foi possível criar um sistema que auxiliasse a classificar corretamente os dados de que esses órgãos dispunham para entender melhor o que se passava e separar corretamente cada informação.  Assim, casos antes classificados, por exemplo, como crime comum, puderam ser analisados do ponto de vista da violência doméstica, para identificá-la. Todo esse conjunto de dados bem interpretado, por região, inclusive, ajuda a Justiça a tomar providências. Desse modo, por meio de gráficos, é possível mostrar esses dados e ajudar na tomada de decisões. A inteligência artificial, nesses casos, tem uma acurácia de cerca de 93% (grande índice de acertos).  Com base em dados, o Ministério Público consegue tomar atitudes mais acertadas com relação a decisões que envolvam seu orçamento, ações de prevenção à violência, conscientização e combate. Viu como todos esses insights são importantes para um desenvolvedor de software? Então aproveite e fique por dentro de tudo o que rolou no Proud Tech através de nossas redes sociais!

Programadores iniciantes: confiram os principais insights do Proud Tech 2021
Tech Writers Novembro 22, 2021

Programadores iniciantes: confiram os principais insights do Proud Tech 2021

Faz parte do clube de programadores iniciantes e quer aprender mais sobre desenvolvimento de software? Então fique atento a este conteúdo, em que falaremos do que rolou na Trilha Softdraft do Proud Tech 2021. Esse é um evento promovido por nós, da Softplan, para outros apaixonados por tecnologia. Dividido em trilhas que aconteceram paralelamente, trouxemos para o Proud Tech diversos palestrantes experientes no mercado.  A Trilha Softdraft era focada em assuntos introdutórios e abordou aspectos como evolução do Java e qualidade do software. Por isso, é de grande importância para quem está começando a desbravar esse universo.  Parte dos conhecimentos compartilhados vieram de: Felipe da Silva Corrêa, desenvolvedor desde 2008; Julio de Lima, que trabalha dentro de uma empresa de consultoria financeira; Christian Fritsch, que atua com front-end há 10 anos; Andre Baltieri, que desde 2003 trabalha com desenvolvimento e aplicações web.  Confira um pouco sobre o que foi tratado e leia o conteúdo na íntegra, para saber como foram as palestras que você não pôde assistir ou para relembrar os pontos mais importantes, caso tenha visto. Coisas que ninguém conta para programadores iniciantes sobre trabalhar com Java Felipe da Silva Corrêa traz uma visão muito interessante para programadores iniciantes, que sempre se perguntam por onde começar.  Abordando a evolução do Java ao longo dos anos e as principais dicas para atuar no mercado, ele traz também uma visão do que geralmente as pessoas não dizem sobre os desafios de atuar nesse segmento, mas que, ao saber, ajudam o profissional a vencê-los. Felipe inicia a palestra resgatando que o Java é um projeto que começou no início dos anos 90. Naquela época, não tinha esse nome e era praticamente um projeto universitário, mas foi evoluindo ao longo dos anos. Sua primeira versão comercial veio em 1995 e até hoje, 27 anos depois, ele continua no mercado, embora tenha passado por transformações. Transformações do Java Entre os fatos marcantes do que tornaram o Java tão conhecido, está o boom da internet no início dos anos 2000. Assim, vieram plataformas e soluções que conseguiam trabalhar atendendo as necessidades de web com Java, de forma primitiva, gerando código HTML estático, renderizado em browser. Em 2007, a mantenedora disponibilizou o código (open source). Abrindo à comunidade, todos puderam alimentar o Java e fomentá-lo. Em 2008, a empresa foi comprada pela Oracle. A partir disso, o Java dividiu-se em duas possibilidades: open source e o enterprise (licenciado). Depois disso, passamos pela década de desenvolvimento de frameworks, até chegarmos ao que temos hoje, inclusive com serviço de streaming, como a Netflix, utilizando o recurso. Dicas para atuar Felipe fala do que se pode esperar do mercado e dá 5 dicas de como se preparar: descubra como conversar na língua de quem você está falando, mesmo que ela seja diferente da sua; aprenda além da sua especialidade, tendo ao menos noções das outras, entenda antes de tirar conclusões (não somente olhe para um código e o considere ruim, entenda como ele funciona); se mantenha atualizado, o Java sempre tem novidades; aprenda Linux. Carreira em testes e qualidade de software: Um guia prático!  Para programadores iniciantes, é muito importante entender a carreira e como se guiar na qualidade. Julio de Lima, em sua palestra, fala do motivo de testarmos a qualidade de software, que está relacionado ao objetivo de evitar que problemas nas aplicações cheguem até as mãos de clientes. Ele explica que no contexto tradicional, haveria testadores, mas que no desenvolvimento ágil esse papel é feito pelo próprio time de software.  Saber como conduzir esses testes passa, então, inclusive pela etapa de pensar nessa cultura antes de ele ser desenvolvido. Afinal, por qual framework começar? Dicas para programadores iniciantes em relação a por qual framework começar podem ser vistas na palestra de Christian. Aprender um framework, como é visto nela, é importante porque possibilita um guia de estilo para seguir. Isso ajuda, inclusive, em situações nas quais não é o mesmo profissional que começa um processo que irá terminar de desenvolvê-lo. Entre as dicas de framework do palestrante estão: escolher um framework que seus amigos já usam; usar um framework que as empresas de interesse já utilizam; utilizar o que possui a documentação mais agradável. Clean Code: como manter seu código limpo? Programadores iniciantes também podem ter muita curiosidade para compreender como trabalhar com clean code. Baltieri apresentou, em sua palestra, regras gerais como: seguir as convenções (se o projeto já tiver um padrão); seguir a lógica de KISS (tudo o mais simples possível); praticar a regra do escoteiro (se pegar um código para manutenção, devolvê-lo melhor do que ele estava, aplicando, por exemplo, o clean code em um trecho);  trabalhar na causa raiz do problema, não ficar apenas o remediando. Para finalizar, o conceito de Code Smells é trazido. Ele é utilizado para designar quando algo no código não é coerente. Baltieri ressalta as seguintes características: rigidez; fragilidade; imobilidade; complexidade desnecessária; repetição desnecessária; opacidade. Trabalhar para minimizar esses efeitos é imprescindível para atingir uma solução que seja eficaz e mais fácil de usar. Conseguiu entender a relevância de compreender esses aspectos para programadores iniciantes? Fique por dentro de tudo o que rolou no Proud Tech através de nossas redes sociais! 

Principais novidades introduzidas no JAVA 1.8 
Tech Writers Novembro 13, 2021

Principais novidades introduzidas no JAVA 1.8 

Como muitos sabem, a nova versão JAVA 1.8 foi lançada em Outubro de 2021, com melhorias, novas funcionalidades e correções de bugs recorrentes da antiga versão. A seguir, veja as novidades e exemplos práticos e objetivos. Boa leitura! Principais novidades introduzidas nos recursos do JAVA 1.8 A seguir, exemplificaremos as principais novidades nos recursos do JAVA 1.8. São elas: Default Methods em interfaces; Lambda e Functional interfaces; Method References; Stream; Nova API de Datas; Default Methods em interfaces Abaixo, criaremos uma List do tipo String contendo títulos de alguns jogos marcantes que serão utilizados nos exemplos do conteúdo. List<String> jogos = new ArrayList<>();jogos.add(“Top Gear”);jogos.add(“The Legend of Zelda: Ocarina of Time”);jogos.add(“Shadow of the Colossus”); Antigamente, o comum para fazer uma ordenação de objetos em uma Listlist era utilizar a classe Ccollections e o método estáticgo sort. System.out.println(jogos);//  [Top Gear, The Legend of Zelda: Ocarina of Time, Shadow of the Colossus]Collections.sort(jogos);System.out.println(jogos);//  [Shadow of the Colossus, The Legend of Zelda: Ocarina of Time, Top Gear] É importante lembrar que o código acima compilou sem a necessidade de nenhuma alteração. Isso ocorre porque a classe String implementa uma interface chamada Comparable, que obriga a declaração do método compareTo. Dentro dessa técnica, a configuração é feita na ordem lexicográfica. E se quisermos ordenar as palavras em uma ordem diferente?  Se quisermos fazer a ordenação por tamanho das palavras, por exemplo, precisamos criar um comparador para informar ao método sort. É necessário criar uma classe. O nome dela não tem muita importância, mas é obrigatório que ela tenha implementado a interface Comparator e uma declaração para o método compare. class ComparadorDeStringPorTamanho implements Comparator<String> {    public int compare(String s1, String s2) {        if(s1.length() < s2.length())            return –1;        if(s1.length() > s2.length())            return 1;        return 0;    }} Agora, precisamos passar para o método sort esse comparador, pois ele possui uma reescrita que recebe uma List e um Comparator. Comparator<String> comparador = new ComparadorDeStringPorTamanho();System.out.println(jogos);//  [Top Gear, The Legend of Zelda: Ocarina of Time, Shadow of the Colossus]Collections.sort(jogos, comparador);System.out.println(jogos);//  [Top Gear, Shadow of the Colossus, The Legend of Zelda: Ocarina of Time] Com o novo recurso de Default Methods, agora podemos criar métodos com corpo dentro de uma interface. A partir disso, a interface List passa a ter uma implementação do método sort. //  Método sort dentro da interface Listdefault void sort(Comparator<? super E> c) {    Object[] a = this.toArray();    Arrays.sort(a, (Comparator) c);    ListIterator<E> i = this.listIterator();    for (Object e : a) {        i.next();        i.set((E) e);} Perceba que, para implementar o sort pela List, obrigatoriamente devemos informar um Comparator. Comparator<String> comparador = new ComparadorDeStringPorTamanho();jogos.sort(comparador);System.out.println(jogos);//  [Top Gear, Shadow of the Colossus, The Legend of Zelda: Ocarina of Time] Lambda e Functional interfaces Nesse tópico, vamos continuar no mesmo contexto do último exemplo. public class App {    public static void main(String[] args) throws Exception {        Comparator<String> comparador = new ComparadorDeStringPorTamanho();        List<String> jogos = new ArrayList<>();        jogos.add(“Top Gear”);        jogos.add(“The Legend of Zelda: Ocarina of Time”);        jogos.add(“Shadow of the Colossus”);        jogos.sort(comparador);        System.out.println(jogos);        //  [Top Gear, Shadow of the Colossus, The Legend of Zelda: Ocarina of Time]    }}class ComparadorDeStringPorTamanho implements Comparator<String> {    public int compare(String s1, String s2) {        if(s1.length() < s2.length())            return –1;        if(s1.length() > s2.length())            return 1;        return 0;    }} É possível deixar o código lambda um pouco melhor? public class App {    public static void main(String[] args) throws Exception {        List<String> jogos = new ArrayList<>();        jogos.add(“Top Gear”);        jogos.add(“The Legend of Zelda: Ocarina of Time”);        jogos.add(“Shadow of the Colossus”);        jogos.sort(new Comparator<String>(){            @Override            public int compare(String s1, String s2) {                if(s1.length() < s2.length())                    return –1;                if(s1.length() > s2.length())                    return 1;                return 0;            }        });        System.out.println(jogos);        //  [Top Gear, Shadow of the Colossus, The Legend of Zelda: Ocarina of Time]    }} Pelo fato da abordagem da classe ser simples, podemos fazer com que o compilador do java crie uma Anonymous Classes. Mas ainda podemos melhorar mais um pouco. Perceba que o método compare possui algumas condicionais testando os tamanhos dos títulos. Essencialmente, estamos testando números com números e no Integer temos um método compare que faz exatamente isso. jogos.sort(new Comparator<String>(){    @Override    public int compare(String s1, String s2) {        return Integer.compare(s1.length(), s2.length());    }} Atenção, o tipo Double também implementa esse método. Mesmo nosso último código ficando um pouco mais compacto, ainda está um pouco verboso.  Nesse contexto, foi adicionado um recurso chamado lambda, mas o seu funcionamento só é possível através de uma Functional interfaces. Essas interfaces possuem 1 único método abstrato, mas, além desse método, elas podem ter outros métodos, desde que sejam default ou static. Essa estrutura é fundamental, pois assim o compilador sabe exatamente que o corpo da expressão lambda que escrevemos é a implementação de seu único método abstrato. Então, como o Comparator é uma Functional interfaces, podemos utilizar um lambda. jogos.sort((String s1, String s2) -> {    return Integer.compare(s1.length(), s2.length());}); O compilador do java nos permite deixar o código um pouco mais curto. jogos.sort((jogo1,  jogo2) -> Integer.compare(jogo1.length(), jogo2.length())); Method References Nesse tópico, continuaremos no mesmo contexto do último exemplo. public class App {    public static void main(String[] args) throws Exception {        List<String> jogos = new ArrayList<>();        jogos.add(“Top Gear”);        jogos.add(“The Legend of Zelda: Ocarina of Time”);        jogos.add(“Shadow of the Colossus”);        jogos.sort((jogo1,  jogo2) -> Integer.compare(jogo1.length(), jogo2.length()));        System.out.println(jogos);        //  [Top Gear, Shadow of the Colossus, The Legend of Zelda: Ocarina of Time]    }} A interface Comparator possui um novo método (comparing), que deve receber uma interface Function, que por sua vez é uma Functional interfaces. jogos.sort(Comparator.comparing(jogo -> jogo.length())); É como se tivéssemos escrito assim. //Estamos falando abaixo: Dado uma String, vamos devolver um Integer que será o return do lambda jogo -> jogo.length()Function<String, Integer> function = jogo -> jogo.length();jogos.sort(Comparator.comparing(function); Nesse caso, como temos uma invocação simples do método length do String, é possível utilizarmos Method References. jogos.sort(Comparator.comparing(String::length)); Um destaque, a utilização do Method References precisa de atenção., Eessa prática só funciona para invocações simples. No próximo tópico, veremos um exemplo em que ele não pode ser utilizado. Stream Nesse tópico, vamos continuar no mesmo contexto do último exemplo. Mas, agora, precisamos de uma classe Jogo. public class Jogo {    private String titulo;    private int lancamento;    public Jogo(String titulo, int lancamento) {        this.titulo = titulo;        this.lancamento = lancamento;    }    public String getTitulo() {        return titulo;    }    public void setTitulo(String titulo) {        this.titulo = titulo;    }    public int getLancamento() {        return lancamento;    }    public void setLancamento(int lancamento) {        this.lancamento = lancamento;    }   } public class App {    public static void main(String[] args) throws Exception {        List<Jogo> listaDeJogos = new ArrayList<>();        listaDeJogos.add(new Jogo(“Top Gear”, 1992));        listaDeJogos.add(new Jogo(“The Legend of Zelda: Ocarina of Time”, 1998));        listaDeJogos.add(new Jogo(“Shadow of the Colossus”, 2005));    }} Stream é uma nova interface que possibilita a utilização de diversos métodos bem interessantes. Vamos filtrar nossa lista para que apenas os jogos com lançamentos inferiores aos anos 2000 sejam exibidos no terminal. Uma maneira simples de fazer isso, antigamente, seria criandor um foreach com uma condicional testando cada valor. for (Jogo jogo : listaDeJogos) {    if (jogo.getLancamento() < 2000) {        System.out.println(jogo.getTitulo());    }} Mas existe uma maneira melhor: Invocar o filter do Stream. listaDeJogos.stream()    .filter(jogo -> jogo.getLancamento() < 2000); Nesse caso, não conseguimos utilizar o Method References, pois não estamos usando uma simples invocação do filter. Esse trecho de código não soluciona nosso problema, ele está testando item por item com a nossa condicional, mas uma modificação em um stream não modifica a coleção/objeto que o gerou. Para funcionar, podemos utilizar o forEach, que o próprio Stream implementa. listaDeJogos.stream()    .filter(jogo -> jogo.getLancamento() < 2000)    .forEach(jogo -> System.out.println(jogo.getTitulo()));    //  Top Gear    //  The Legend of Zelda: Ocarina of Time Como não temos o método toString na classe Jogo, não podemos utilizar o Method References, pois precisamos informar qual parâmetro o System.out deve imprimir no terminal. Nova API de Datas Agora temos várias classes com diversos métodos que facilitam (e muito) o trabalho relacionado com datas no java. A seguir, veja alguns exemplos de LocalDate: LocalDate date = LocalDate.now();System.out.println(date);//  2021-08-17date = LocalDate.of(2021, Month.DECEMBER, 15);System.out.println(date);//  2021-12-15 Já para usar o  DateTimeFormatter na formatação de um LocalDate, você pode fazer da seguinte forma: DateTimeFormatter formatador = DateTimeFormatter.ofPattern(“dd/MM/yyyy”);String novaData = date.format(formatador);System.out.println(novaData);//  15/12/2021 Exemplo de como extrair o dia nominal da semana utilizando DayOfWeek DayOfWeek semana = DayOfWeek.from(date);System.out.println(semana);//  WEDNESDAY Exemplos de LocalDateTime: LocalDateTime time = LocalDateTime.now();System.out.println(time);//  2021-08-17T11:29:56.861110time = LocalDateTime.of(2021, Month.DECEMBER, 15, 21, 30, 0);System.out.println(time);//  2021-12-15T21:30 Exemplo de como formatar um LocalDateTime utilizando DateTimeFormatter: DateTimeFormatter formatadorTime = DateTimeFormatter.ofPattern(“dd/MM/yyyy hh:mm:ss”);String novaTime = time.format(formatadorTime);System.out.println(novaTime);//  15/12/2021 09:30:00 Exemplo de como comparar LocalDate utilizando Period: LocalDate date1 = LocalDate.of(2021, Month.DECEMBER, 15);LocalDate date2 = LocalDate.of(2051, Month.JANUARY, 22);Period periodo = Period.between(date1, date2);System.out.println(periodo);//  P29Y1M7DSystem.out.printf(    “Falta %d anos, %d mês e %d dias.”,    periodo.getYears(),    periodo.getMonths(),    periodo.getDays());//  Falta 29 anos, 1 mês e 7 dias. Conclusão sobre o JAVA 1.8 O que foi exemplificado nos tópicos é apenas uma visão muito superficial de todo o poder dessas novas mudanças. Existem muitos outros métodos que trazem soluções boas para diversos problemas que, eventualmente, surgem no desenvolvimento de nossas aplicações.  O conselho que fica é: sempre tenha em mente que, se estamos quebrando a cabeça para escrever algum método, é provável que já exista um método pronto para fazer isso por nós.  Vale sempre verificar as documentações e as soluções existentes. Saiba mais em nosso Blog! Materiais interessante: Mergulhe em tecnologia — ALURA Documentação JAVA

A evolução da sociedade e da tecnologia
Tech Writers Novembro 04, 2021

A evolução da sociedade e da tecnologia

https://open.spotify.com/episode/3kXrDANPbBkNim7RRIKQZv?go=1&sp_cid=65617f9945b6dafa4bd6df3d4f755a20&utm_source=embed_player_p&utm_medium=desktop A evolução da sociedade e da tecnologia No nosso segundo episódio da Together in Tech, conversamos a respeito do desenvolvimento da sociedade junto da tecnologia, desde os primórdios até os dias atuais. Para isso, convidamos a antropóloga Andressa Soilo para dialogar e trocar ideias com o host Guilherme Brasil. O bate-papo foi muito interessante e abordaremos alguns tópicos discutidos aqui nesse artigo.  Os últimos 10 anos da sociedade Ao analisar a linha de tempo da humanidade podemos perceber que muitas coisas mudaram ao longo dos últimos 10 anos. Naquela época, não havia aplicativos para se locomover, para pedir comida ou para requisitar serviços em geral. Hoje em dia, qualquer item que alguém possa necessitar é possível ser encontrado na internet.  Durante o bate-papo, Andressa aponta a questão de que a tecnologia surgiu antes do digital. Quando pensamos nela, muitas vezes ligamos a concepção de que é apenas um ”mundo” de smartphones, impressoras 3D, robótica, inteligência artificial, drones e naves espaciais. No entanto, isso são itens sofisticados que estão ganhando espaço no mercado no momento. Como vivemos em um contexto marcado pelo digital, tendemos a acreditar que a tecnologia está ligada unicamente a isso. O digital certamente impacta a vida das pessoas, visto que é algo que está muito presente no cotidiano. O instagram é um exemplo de rede social que representa o efeito que a tecnologia insere hoje em dia. Muitas pessoas vêm se sentindo cada vez mais inseguras por conta das pressões estéticas da sociedade no meio digital. Além disso, as fake news também são outro exemplo de como o digital se enquadra em nossas vidas. Essas mentiras que se propagam rapidamente geram desinformação e até mesmo causaram diversas mortes durante a pandemia do COVID-19. Ou seja, pode-se perceber de forma clara que atualmente a tecnologia tem quase o mesmo conceito de digital e que nos impacta profundamente.  Questão geracional Estamos vivendo em um período onde as mudanças tecnológicas estão se transformando em uma velocidade rápida. Por isso, certas gerações acabam se perdendo ao acompanhar as alterações tecnológicas. O exemplo citado para demonstrar essa situação é o aparecimento do Tik Tok. Uma nova rede social que ganhou um grande espaço e de forma acelerada nesse mundo. Pessoas de uma geração mais velha, como é o caso da Andressa, nem sequer chegam a baixar e saber utilizar essa rede.  Atualmente, as crianças já crescem sabendo utilizar smartphones e outros aparelhos. Às vezes, até mesmo, aprendem de maneira autodidata. Algo totalmente distinto de gerações passadas, que muitas vezes possuem dificuldade em usar certas tecnologias.   ”No momento, a gente vive uma pluralidade de entendimentos do modo de como nós incorporamos a tecnologia na atualidade.” – Andressa expõe sua opinião. Os impactos da tecnologia  Na conversa, Andressa diz que não há um consenso se a tecnologia digital de hoje em dia é positiva ou negativa. A tecnologia por si só não faz mal a ninguém, mas sim como os indivíduos a utilizam. Isso porque, ela é ambivalente. Ou seja, ela pode trazer tanto impactos bons como ruins para a sociedade.  Caso as pessoas desejam utilizar a tecnologia para algo positivo, ela possui um grande potencial de gerar benefícios em suas vidas. Entretanto, também há diversos aspectos negativos que afetam principalmente o emocional dos indivíduos. Ao manusear a tecnologia de forma prejudicial, problemas psicológicos como ansiedade, depressão e crises de pânico podem começar a surgir na vida dessas pessoas. Esses tipos de transtornos mentais são mais comuns na sociedade do século XXI e são causados pelo mau uso do digital. Dessa forma, é preciso estar atento ao modo como você utiliza a tecnologia diariamente. Ela está te trazendo benefícios? Gostou dessas reflexões? Ouça o bate-papo completo. Nele falamos de outras questões relacionadas com a sociedade e a tecnologia.

Padrão de Projeto Strategy: O que é, quando devo usar, como aplicar e exemplos!
Tech Writers Novembro 02, 2021

Padrão de Projeto Strategy: O que é, quando devo usar, como aplicar e exemplos!

Entre os diferentes padrões de projeto, o Strategy permite criar uma família de algoritmos, encapsular cada um deles e torná-los intercambiáveis, permitindo que o algoritmo varie independentemente dos clientes que o utilizam e facilitando a manutenibilidade do seu código. Se você está iniciando no mundo de padrões de projeto e qualidade de código, mas ainda não sabe bem como usar o Strategy, não se preocupe. Vamos te mostrar hoje o que é o Strategy, quando usar e como aplicar, com exemplos. Você vai perceber que este padrão é mais simples do que pensa e que ele pode te ajudar bastante no seu dia a dia. Confira! O que é o Padrão Strategy? O Strategy é um padrão de projeto comportamental que define uma família de algoritmos, garantindo que o algoritmo varie independentemente dos clientes que fazem uso dele. Com ele, você pode transformar um conjunto de comportamentos em objetos e então torná-los intercambiáveis. Hoje, iremos abordar somente o Strategy. Mas, além dele, existem outros padrões de projeto em Java, como por exemplo, o Composite e o Decorator, que são abordados no livro Padrões de Projeto da GoF, a Gang of Four - ou em português, Gangue dos Quatro, caso você tenha interesse em explorar mais o assunto. Ainda de acordo com a Gangue dos Quatro, no livro Design Patterns: Elements of Reusable Object-Oriented Software, temos a seguinte definição: “Um padrão de projeto nomeia, abstrai e identifica os aspectos-chave de uma estrutura de projeto comum para torná-la útil para a criação de um projeto orientado a objetos reutilizável […]”. Como funciona o Padrão de Projeto Strategy? Vamos entender como funciona o Strategy Design Pattern: imagine que temos um e-commerce e no carrinho de compras da loja podemos aplicar algumas promoções dependendo de vários fatores. Por exemplo, é possível aplicar uma promoção de acordo com o valor mínimo de compra, a quantidade de produto, frete grátis, entre outros. Neste cenário, podemos ter muitas variações de algoritmos dentro do carrinho de compras. Porém, ao fazer tudo isso dentro da classe de carrinho sem separar o algoritmo, provavelmente haveria várias condicionais IFS para checar em quais casos aplicar cada promoção, gerando diversas alterações da classe do carrinho. É aí que o Strategy entra, pois ele soluciona esse problema separando o algoritmo. Dessa forma, dentro do carrinho de compras, teremos um campo para linkar uma estratégia de desconto que será uma família inteira de estratégias. Ou seja, podemos separar o algoritmo da regra de negócio.   Quando devo usar o padrão Strategy? O padrão Strategy é muito comum no código Java e pode ser usado em situações em que o seu código terá muitas variações de algoritmo e condições, gerando uma corrente de IFs. Vale reforçar que não são todas as cadeias de IFs que precisam ser substituídas por um Strategy, apenas se as alterações forem frequentes a longo prazo. Este padrão ajuda a facilitar a manutenibilidade do código e tornar a potencial expansão do seu código mais simples e objetiva. Isso é possível através da descentralização da responsabilidade da manipulação de um objeto abstraído por uma interface e suas diferentes “estratégias” de implementação. Como aplicar o Strategy na prática? Agora que você já entendeu melhor o conceito do padrão Strategy e quando utilizá-lo, vamos sair um pouco da parte teórica e partir para a prática. Vamos visualizar um problema e refletir sobre ele para, então, testar a implementação do design pattern em questão. Exemplo de aplicação Strategy Java: O Problema Para entender melhor como aplicar o Strategy, imagine que existe um objeto Funcionario com suas propriedades e uma classe CalculadoraSalarial que realiza o reajuste salarial deste funcionário de acordo com sua performance durante o ano. Com um ENUM que existe dentro das propriedades do objeto Funcionario, mede-se a performance do colaborador. Veja no exemplo a seguir: Agora, imagine as seguintes regras de negócio: Se o funcionário tiver uma performance NEGATIVA no momento do cálculo, ele não deve receber reajuste salarial. Se o funcionário tiver uma performance POSITIVA no momento do cálculo, seu salário deve receber um reajuste com aumento salarial de 5%. Devido a lógica por trás do negócio, o ideal é não retornar um valor de reajuste “X” por padrão. Dessa forma, podemos criar uma exceção caso no futuro exista algum novo tipo de performance que esquecemos de implementar na nossa calculadora. Implementando o método reajustaSalario (no exemplo, utilizando Java), podemos chegar a um resultado parecido com o seguinte: O código acima está funcional. Porém, uma semana após a implementação, vamos supor que o time solicitou a criação de um novo tipo de performance: EXCELENTE. Nesta nova condição, o colaborador que conquistar a performance “excelente” recebe 10% de reajuste salarial. Sendo simples e direto, o ENUM seria implementado com mais um tipo, o “EXCELENTE”. Por último, a implementação do método reajustaSalario ficaria semelhante ao exemplo abaixo: É em cenários parecidos com este que o padrão Strategy é aplicado: onde o código pode facilmente se expandir criando uma corrente de IFs. No exemplo acima, estamos “pegando leve” ─ no mundo real, encontra-se IFs encadeados em uma frequência muito mais comum, muitas vezes em situações piores do que o nosso. Tudo isso prejudica a legibilidade do código e não é uma boa prática. E como podemos implementar o Strategy nesse caso? Existem diversas formas de se resolver um problema com Strategy, a maioria delas envolve a implementação de uma interface ou de uma abstração. No nosso exemplo, as coisas são bem mais simples graças ao nosso ENUM. Provavelmente, até agora, a nossa implementação de Performance foi a seguinte: A partir de então, ao implementarmos um método abstrato dentro do nosso ENUM, todos os diferentes tipos dentro dele exigirão uma implementação, causando erro em tempo de compilação caso essa exigência não seja atendida, obrigando o desenvolvedor a implementar o método. E, assim, podemos alterar a forma que a nossa calculadora retorna o reajuste salarial do funcionário. Isso facilita imensamente a leitura do código e sua manutenção, tornando ele mais simples. Este processo deverá seguir os princípios SOLID (cinco princípios da Programação Orientada a Objetos). Aproveite para ler nosso artigo sobre um dos princípios mais importantes do SOLID: Single Responsability Principle. Depois de aplicar o Strategy, basicamente, contanto que a regra de negócio fundamental não mude, não precisamos mais sequer tocar na nossa “Calculadora”. Como temos certeza de que o método retornaReajusteSalarial possui sua devida implementação dependendo do tipo de performance, garantimos, também, que não exista o cenário descrito anteriormente, onde o desenvolvedor esqueceu de implementar o cálculo do reajuste. É importante reforçar que esta não é a única forma de implementar o padrão de projeto Strategy, mas é um ótimo jeito de exemplificar como é mais fácil de implementá-lo no nosso código do que você imagina.  Opinião do Autor sobre o Padrão de Projetos Strategy Por mais que seja diversas vezes confundido por parecer complexo, o Strategy é bem mais simples de ser implementado do que parece e poderia muito bem ser mais visto no código de vários sistemas orientados a objeto. Durante o desenvolvimento, às vezes podemos acabar criando a ideia errada de que tentar aplicar Design Patterns consome muito tempo.  Na verdade, uma vez que você conhece e domina Design Patterns, eles só têm a agregar para a velocidade e elegância da sua solução. Os padrões de projeto facilitam o desenvolvimento e tornam a manutenibilidade e evolução do código mais simples. E você, já aplicou o Strategy em algum dos seus códigos? O que achou do deste design pattern? Deixe seu comentário!