CDD - Cognitive Driven Development - Design Orientado ao Entendimento - Uma forma de programar criada por brasileiros!
A importância de desenvolver estratégias que reduzam o cognitive load dos nossos códigos para garantir seu entendimento por todos. Foi desse raciocínio que nasceu o conceito de Cognitive-Driven Development, ou design orientado ao entendimento.
CDD - Cognitive Driven Development
Descobrir quais são as nossas limitações de entendimento e como a nossa mente atua nessa questão é tema de estudo de longa data. O artigo mais influente nessa área vem de 1956 e foi escrito pelo psicólogo George A. Miller, da universidade de Harvard. O título da famosa publicação é “The Magical Number Seven, Plus or Minus Two: Some Limits on our Capacity for Processing Information“.
http://psychclassics.yorku.ca/Miller/
Miller explica que provavelmente nós temos uma severa limitação na hora de processar informações. No resumo do resumo, é explicado que temos um limite de itens a serem entendidos em determinado momento que varia entre 5 e 9. Por isso o título +-7. Essa ideia foi fortemente explorada e é bem aceito hoje em dia que realmente temos essa limitação.
Esforço cognitivo, ou carga cognitiva se refere ao nível de utilização de recursos psicológicos como memórias, atenção, percepção, representação de conhecimento, raciocínio e criatividade na resolução de problemas.
A Teoria da Carga Cognitiva fundamenta-se na impossibilidade que o ser humano manifesta em processar muitas informações em simultâneo. O excesso de informação gera um esforço demasiado para todo o processo cognitivo o que origina uma sobrecarga cognitiva que dificulta a compreensão do conteúdo que se deseja apreendido.
https://sites.google.com/site/teoriadacargacognitiva/a-contribuicao-dos-principios-da-teoria-da-carga-cognitiva-na-aprendizagem-multimedia/resumo-1
Para entender mais sobre a teoria da carga cognitiva
http://www.ucs.mun.ca/~bmann/0_ARTICLES/CogLoad_Paas04.pdf
Um trecho retirado do artigo referenciado diz o seguinte: “The load is called ‘intrinsic’ if it is imposed by the number of information elements and their interactivity.”
Em tradução livre, temos: “A carga é chamada de ‘intrínseca’ se for imposta pelo número de elementos de informação e sua interativida”.
E é da ideia de carga intrínseca que nasce a proposta de design de código orientado a entendimento. Caso a gente considere que um pedaço de código é um material que precisa ser entendido, como podemos diminuir de maneira eficaz a carga intrínseca dele?
Afinal, o que é Cognitive-Driven Development (CDD)?
Cognitive-Driven Development (CDD), ou em português desenvolvimento orientado a cognição, é uma estratégia para reduzir a sobrecarga cognitiva durante o desenvolvimento ao melhorar o design do código.
Ou seja, a ideia é manter os níveis de entendimento sobre um pedaço de código dentro
do que o ser humano pode entender bem! Ou seja, dentro de +-7 items simultaneos.
Limitando a carga intrínseca do código ou Ponto de Complexidade Intrínseca (ICP)
Uma das bases do Cognitive-Driven Development (CDD) é analisar e buscar limitar a complexidade de um código, esta limitação pode ser arbritrária decidida no time. Para que a gente consiga, de fato, ter uma maneira interessante de limitar a carga intrínseca do código que escrevemos, precisamos seguir alguns passos.
A primeira tarefa do time é decidir qual vai ser a unidade de código que será analisada. Por exemplo, se falarmos de uma linguagem orientada a objetos temos algumas possibilidades de definição de unidade de código, como, por:
- método dentro de uma classe;
- classe;
- arquivo.
A equipe pode definir um número de linhas maximo por classe dentro de um arquivo.
100, ou seja o limite não pode passar de 100. Se passar outro arquivo deve ser criado.
O que mais foi explorado até agora(dentro dos teste internos an ZUP) é usar o arquivo como uma unidade de código a ter sua carga intrínseca limitada. Isso implica que se tivermos duas classes dentro do mesmo arquivo, vamos somar as cargas intrínsecas de cada uma e essa vai ser a carga total do arquivo.
Uma vez que a unidade de código a ser analisada foi definida, é importante que a equipe do projeto entre em um acordo sobre o que vai influenciar na carga. É o que chamamos de Intrisc Complex Point (ou Ponto de Complexidade Intrínseca) no Cognitive-Driven Development. Para facilitar, vamos referenciar estes pontos como ICP.
Aqui não existe regra, o objetivo do Cognitive-Driven Development (CDD) não é achar uma composição de Ponto de Complexidade Intrínseca (ICP) que forme uma métrica perfeita. A ideia é que a equipe, considerando suas características, encontre os ICP que façam sentido para aquele contexto.
Aquilo que a equipe achar naquele momento! E que pode mudar com o tempo!
E qual o limite de ICP que podemos ter então por unidade de código? Atualmente a nossa sugestão é que você tenha um número que seja o dobro ou maior ao número de ICP escolhidos. No exemplo citado temos cinco itens, então o limite por unidade de código seria dez ou mais.
Visão prática sobre o Ponto de Complexidade Intrínseca (ICP)
Por exemplo, a equipe de engenharia da Zup Edu definiu que para os projetos em Java que escrevemos, vamos considerar os itens abaixo como ICP:
- branches de código padrões (if, else, loops, when, case do when, try, catch);
- funções como argumento;
- condicionais;
- acoplamento com classes específicas do projeto;
- herança de classe abstrata ou concreta (extends).
Cada equipe pode definir seu conjunto de ICP e revisitá-lo com frequência. Até porque a combinação de níveis de habilidade da equipe pode influenciar no escopo do projeto e em vários outros fatores que afetam a qualidade e complexidade do código. Outro detalhe muito interessante é que o conjunto de itens influencia diretamente no estilo de código.
Algumas dicas práticas para escolher e trabalhar melhor com ICPs:
- Herança foi escolhida como ICP? O recado é: Use com moderação.
- Condicional foi escolhida como ICP? O recado é: Não crie if com várias condicionais
- Função como argumento foi escolhida como ICP? O recado é: Não exagerar em transformação de coleção.
- Apenas acoplamento com classe específica foi escolhido como ICP? O recado é: Saiba das tecnologias que sustentam o projeto, vamos usar sem moderação.
A definição do limite de ICP por unidade de código ainda precisa de muita exploração. O importante para o Cognitive-Driven Development (CDD) é que exista um conjunto de itens claros que a equipe considere que dificulta o entendimento, assim como um limite estabelecido.
Benefícios de criar um entendimento sobre complexidade
Com um conjunto de ICP claro e um limite definido, muitas atividades e debates são facilitados no intervalo de tempo em que o combinado estiver valendo:
- Esse código está complexo? Se o número de ICP estiver abaixo ou igual ao limite, a resposta é não.
- Esse código vai passar no review? Se o número de ICP estiver abaixo ou igual ao limite, a resposta é sim.
Não importa se a pessoa é junior, plena, sênior ou qualquer outro nível. Ninguém vai escrever um código que passa do limite de complexidade definido pela equipe!
Um limite sempre arbitrário e simples para qualquer um entender!
Quaisquer outras discussões sobre complexidade agora têm uma regra clara. Entendemos que isso facilita bastante o dia a dia de comunicação dentro do projeto no que diz respeito à análise do código em si.
Como o Cognitive-Driven Development se relaciona com o que você já utiliza hoje em dia?
Importante notar que o Cognitive-Driven Development (CDD) não vem com a ideia de ser a principal referência dentro do design do seu código. Limitar a dificuldade de entendimento é algo que pode ser útil em qualquer ponto do projeto.
Imagine que você está escrevendo um caso de uso inspirado na arquitetura proposta pelo Clean Architecture. Se a equipe tiver definido os pontos de complexidade intrínseca (ICP) e o limite, você vai conseguir ter um caminho claro de como separar o código de modo a fazer o caso de uso e ainda manter o nível de carga cognitiva necessário para entendimento adequado com os padrões da equipe.
Olhando ainda para as ideias de camadas propostas pela Clean Architecture, você pode encontrar situações semelhantes na camada de entidades. As classes que estão no núcleo da sua aplicação tendem a ser transversais ao sistema todo. Elas podem ganhar mais atributos, métodos etc.
Então como fazer para saber o limite daquele código no que diz respeito a facilidade de entendimento? Mais uma vez a ideia do Cognitive-Driven Development (CDD) pode ser aplicada para facilitar.
A mesma linha de raciocínio pode ser aplicada quando você está se inspirando no Domain Driven Design, pensando no princípio da responsabilidade única etc.
Peguei este artigo da zup e fiz comentários que estão citados!
https://www.zup.com.br/blog/cognitive-driven-development-cdd
Uma definição em vídeo do autor Alberto Luiz Oliveira Tavares de Souza
https://www.youtube.com/watch?v=rqw_Jnv6ZX4
Fontes:
https://www.zup.com.br/blog/cognitive-driven-development-cdd
https://ieeexplore.ieee.org/document/9240662
https://github.com/asouza/pilares-design-codigo/blob/master/ICSME-2020-cognitive-driven-development.pdf
Autores: Alberto Luiz Oliveira Tavares de Souza
Zup Innovation - Academy, São Paulo, SP, Brazil
E
Victor Hugo Santiago Costa Pinto
Zup Innovation - Academy,São Paulo,SP,Brazil
Entre em contato com um dos autores
https://twitter.com/alberto_souza
Ele é muito simpatico e sempre que pode responde a todos!