Criar uma biblioteca open source é uma experiência prazerosa para muitos desenvolvedores. Pois, permite criar uma solução para um determinado problema que outros desenvolvedores têm ou que irão ter e poupar tempo e esforço. E há uma possibilidade que centenas ou milhares de pessoas ao redor do mundo usem a solução.
É bem provável que já teve a oportunidade de usar muitas bibliotecas na sua carreira profissional mas será que já teve a oportunidade de criar uma biblioteca, gem, package etc? Quais são as coisas que um desenvolvedor pode fazer para criar uma biblioteca de boa qualidade e de fácil consumo? Como pode ajudar os consumidores da sua biblioteca a saber o que deu errado para corrigir? Quais são alguns princípios ou modelos mentais que possam ajudar você a criar algo que seja simples de usar? Como reduzir e lidar com a complexidade? Como lidar com mudanças que irão acontecer durante o ciclo de vida da sua biblioteca?
Nesta série de artigos irei responder essas perguntas e dar dicas para ajudar você a criar bibliotecas com maior qualidade, flexibilidade e que sejam mais fáceis de consumir. Mas antes há uma pergunta importante que todos nós devemos fazer.
1. Preciso mesmo de criar uma biblioteca?
Antes de investir tempo e energia para criar uma biblioteca, pesquise para ver se já existem outros disponíveis para resolver o seu problema. Ian Summerville ao falar sobre fundamentos de engenharia de software no seu livro intitulado Engenharia de software 9a edição expressou um conselho digno da sua atenção:
“Você deve fazer o melhor uso possível dos recursos existentes. Isso significa que, quando apropriado, você deve usar o software já desenvolvido, em vez de escrever um novo. — Ian Summerville”
Caso as bibliotecas existentes não sejam aptas para uso no seu projecto por razões de negócio, licenças, ou má qualidade, poderá seguir em frente. O tema a seguir mudou completamente a minha visão sobre desenvolvimento de software.
2. Pense no cliente
É essencial pensar no cliente final que irá consumir a sua biblioteca, neste caso o desenvolvedor. Isso envolve ter ou mostrar empatia, mas antes precisamos definir claramente o que significa ter empatia e depois veremos como isso está relacionado ao desenvolvimento e engenharia de software. De acordo com o site www.significados.com.br empatia significa:
“A capacidade psicológica para sentir o que sentiria uma outra pessoa caso estivesse na mesma situação vivenciada por ela. Consiste em tentar compreender sentimentos e emoções, procurando experimentar de forma objetiva e racional o que sente outro indivíduo.”
Daí poderá surgir uma pergunta da sua parte: Mas como isso está relacionado ao desenvolvimento de software?
Visto que a empatia permite nos colocar no lugar de uma outra pessoa, seguir os princípios de desenvolvimento orientado a empatia permite criar software centrado ao desenvolvedor, no caso que estejamos a desenvolver uma biblioteca. Vai ajudar-nos a pensar nas dificuldades do consumidor e diminuir fricção com uma documentação clara e fácil de entender. Também, se aplicado corretamente permite-nos criar software que seja mais fácil de usar e com uma interface ou API mais simples e um produto final de maior qualidade.
Como fazer na prática?
Pense em como o consumidor vai usar a sua biblioteca e veja o que pode complicar o trabalho dele e diminuir a sua produtividade. Vamos usar como exemplo uma biblioteca desenvolvido na NEXT para interagir com a API da ProxyPay para efectuar pagamentos na rede multicaixa e outra exemplo fictício.
A API poderia ser desenhado deste jeito:
Exemplo A1
val proxyPay = ProxyPayPayment()
proxyPay.config = ProxyPayConfig.getInstance()
proxyPay.referenceRequest = request
...
Antes de continuar a sua leitura, análise o código acima e procura problemas que um desenvolvedor pode encontrar.
Exemplo B1:
private void makeNormal(Customer customer) {
Order o1 = new Order();
customer.addOrder(o1);
OrderLine line1 = new OrderLine(6, Product.find("TAL"));
o1.addLine(line1);
OrderLine line2 = new OrderLine(5, Product.find("HPK"));
o1.addLine(line2);
OrderLine line3 = new OrderLine(3, Product.find("LGV"));
o1.addLine(line3);
line2.setSkippable(true);
o1.setRush(true);
}
Em essência, criamos os vários objetos e os unimos. Se não podemos configurar tudo no construtor, precisamos criar variáveis temporárias para nos ajudar a construir o produto final — este é particularmente o caso em que você está adicionando itens nas coleções.
Este é a forma mais convencional que tenho visto para juntar um conjunto de objectos. Conseguiu notar como pode ser muito trabalhoso para o desenvolvedor montar todos os objectos necessários para sua tarefa?
Aplicando o princípio de empatia permite-nos achar uma maneira mais simples de lidar com o mesmo caso. Uma boa alternativa é usar um fluent interface e o Builder pattern.
Solução para A1:
val proxyPay = ProxyPayPayment.Builder()
.addProxyPayConfiguration(ProxyPayConfig.getInstance())
.addReferenceRequest(request)
.build()
Solução para B1:
private void makeFluent(Customer customer) {
customer.newOrder()
.with(6, "TAL")
.with(5, "HPK").skippable()
.with(3, "LGV")
.priorityRush();
}
Qual dessas opções deixa a intenção do código mais claro? É bem provável que a sua resposta seja os dois últimos e com boa razão visto que a API foi desenhada para ser legível e para fluir como um poema bem escrito. O preço de fazer isso é tirar mais tempo para pensar e construir a API mas com certeza o artefacto final será algo bem mais fácil para o cliente entender e consumir.
Em resumo
Antes de começar a escrever uma única linha de código procura entender melhor o problema e colocar-se no lugar do cliente.
Desenhar como os vários componentes da biblioteca irão interagir.
Outro ponto essencial é desenhar a API e pensar em como o desenvolvedor vai usar a sua biblioteca e prever os possíveis problemas que possa encontrar ao usar a sua biblioteca.
3. Assume sempre que o cliente seja “estúpido”
Recentemente comprei uma cadeira para o meu escritório e tive o prazer de montá-lo. Todas as peças foram cuidadosamente colocadas e organizadas na sua caixa. O manual teve desenhos bem simples para ajudar-me a montar a cadeira sem ter que ligar um amigo (Quem quer ser milionário). O manual não tinha texto nenhum. Apenas números para apresentar os passos diferentes para montar a cadeira com sucesso. O que o fabricante da cadeira pensou antes de criar-lo? A equipe provavelmente pensou em como poderiam facilitar a vida de quem vai montar a cadeira e consequentemente poupar seu tempo. Eles assumiram que o cliente fosse “estúpido”. Quer dizer, diminuíram a complexidade para o benefício de quem vai montar.
Por vezes como desenvolvedores gostamos de mostrar o quão inteligente nós somos por criar coisas demasiados complexos ou usar recursos da linguagem de programação que são poucos conhecidas ou “exotéricos”. Isso cria uma barreira para quem vai usar a sua biblioteca. Porquê? Lembra que o desenvolvedor está com tempo limitado e precisa fazer uma entrega o mais rápido possível e na melhor qualidade possível. Isso pode causar vários problemas, um deles que merece maior destaque é:
O desenvolvedor pode cometer um erro ao usar a sua biblioteca se for demasiado complexo usá-o.
Do mesmo jeito que alguém pode cometer um erro ao montar uma cadeira porque há muitas peças e o jeito de montar-lá é demasiado complexo.
Como podemos reduzir complexidade?
O livro “The Laws of Simplicity” (As Leis da simplicidade) escrito por John Maeda diz algo que mudou o meu modo de pensar completamente e que é aplicável em quase tudo na vida incluindo desenvolvimento de software e tecnologia.
“A maneira mais simples de obter simplicidade
é através da redução ponderada.- John Maeda”
O segredo consiste em reduzir em vez de aumentar. Elimina tudo que não for necessário. Simplifique o seu código, a sua interface e aplique o padrão de desenho melhor adequado para o seu problema.
Qual vai ser o resultado disso?
A sua biblioteca será mais fácil de manter e consumir, e podes ter a certeza que os consumidores sentir-se-ão mais inteligentes por terem escolhido a sua solução.
No próximo artigo desta série irei abordar sobre outras dicas que irão ajudar você a criar bibliotecas melhores.
Este é o Alexandre Juca, ele é Engenheiro de Software na NEXT e é apaixonado por Fintechs, Segurança, I.A e Negócios.
A sua missão é revolucionar e impulsionar empresas usando tecnologia.
Lista de algumas bibliotecas open source desenvolvidas por Alexandre Juca e que tem ele como contribuidor:
ProxPay Elixir - https://github.com/nextbss/proxypay-elixir
ExOauth2 - https://github.com/AlexJuca/ex_oauth2
OktaAuth - https://github.com/nextbss/okta_auth
ProxyPay Kotlin — https://github.com/nextbss/proxypay-kotlin
BiometricKit — https://github.com/AlexJuca/BiometricKit
Kamba Android SDK — https://github.com/usekamba/kamba-android-sdk
Kamba Woocommerce — https://github.com/usekamba/kamba-woocommerce
Hades - https://github.com/fklement/hades
Top comments (0)