Teoria em vez de heurística: melhorando como desenvolvedores de front-end



Tornando-se um desenvolvedor front-end melhor usando fundamentos em vez de heurísticas

Nossa experiência mostra que educadores não técnicos e pessoas autodidatas geralmente confiam não em princípios teóricos, mas em métodos heurísticos.

Heurística - padrões e regras comprovadas que um desenvolvedor aprendeu com a prática. Eles podem funcionar de maneira imperfeita ou limitada, mas em extensão suficiente e não requerem reflexão séria. Aqui estão alguns exemplos de heurísticas:

  • “Use $(document).ready(function(){}) para inicializar o código nos sites jQuery”
  • “O var self = this construção é necessária para chamar um método em uma função de retorno de chamada”
  • "As funções de seta não possuem return "

Ao mesmo tempo, o princípio teórico pode ser usado para encontrar soluções para outros problemas. Ele é invariavelmente fiel e frequentemente determina o próprio dispositivo de um ou outro elemento. Os princípios teóricos incluem, por exemplo:


Observe: citamos apenas exemplos heurísticos para enfatizar a natureza artesanal da heurística em comparação com o rigor dos fundamentos teóricos. Nenhum dos exemplos heurísticos é universal para todos os casos, mas eles funcionam em um número suficiente de situações para que os desenvolvedores que os utilizam recebam código de trabalho sem um entendimento completo de sua operação.

Argumentos para uma abordagem teórica


Muitas vezes nos deparamos com o fato de que desenvolvedores sem educação técnica não estão inclinados a resolver problemas usando princípios teóricos. Como regra, isso é explicado pelo fato de que no início de suas carreiras eles não tiveram a oportunidade de aprendê-las e, como os métodos heurísticos funcionam satisfatoriamente, eles continuam a usá-los.

No entanto, apesar da aparente complexidade, aprender uma teoria pode ser muito útil. Porque Então, essa teoria permitirá que você se sinta confiante de que sua solução funcione, além de exibir respostas independentemente para novas perguntas, sem precisar procurar as soluções de outras pessoas. No curto prazo, os algoritmos heurísticos podem parecer uma solução simples e rápida, mas geralmente levam a soluções imperfeitas - se é que existem.

Além disso, contando com métodos heurísticos, você nunca aprenderá como resolver problemas de verdade. Muitas vezes, você pode encontrar uma solução que funcione, mas mais cedo ou mais tarde você ficará parado, do qual não encontrará uma saída. Os programadores de C&P contam com heurísticas em seu trabalho.

Critérios de nível de habilidade do desenvolvedor


Ao entrevistar desenvolvedores de front-end, definimos uma tarefa de programação para eles e dizemos que eles são livres para usar qualquer fonte, seja Google ou Stack Overflow. Dessa maneira, é fácil determinar se o desenvolvedor é adepto de heurísticas ou teoria.

O primeiro, sem exceção, copia o código de exemplos mais ou menos adequados com o Stack Overflow. Somente quando o código não funciona como planejado, eles começaram a ajustá-lo por si mesmos. Muitas vezes eles falham.

Os últimos tendem a procurar respostas na documentação da API. Lá, eles encontram informações sobre quantos parâmetros uma função específica leva ou a sintaxe específica da forma expandida da propriedade CSS desejada.

Já nos primeiros cinco minutos da entrevista, você pode determinar exatamente a que tipo de programador o candidato pertence.

Exemplo


Tome Bill como exemplo. Ele concluiu vários cursos de treinamento, resolveu várias tarefas em JavaScript e criou sites em seu tempo livre, mas ele realmente não aprendeu JavaScript.

Quando Bill se deparar com um objeto como este:

 const usersById = { "5": { "id": "5", "name": "Adam", "registered": true }, "27": { "id": "27", "name": "Bobby", "registered": true }, "32": { "id": "32", "name": "Clarence", "registered": false }, "39": { "id": "39", "name": "Danielle", "registered": true }, "42": { "id": "42", "name": "Ekaterina", "registered": false } } 

Esse objeto pode exibir uma lista de usuários e se eles se registraram para um evento específico.

Suponha que Bill precise recuperar uma lista de usuários registrados. Em outras palavras, filtre-os. Ele encontrou um código no qual o método .filter() era usado para filtrar a lista. Então ele tenta algo como:

 const attendees = usersById.filter(user => user.registered); 

E aqui está o que ele recebe:

 TypeError: usersById.filter is not a function 

"Algo absurdo", pensa Bill, porque viu o código no qual .filter() funcionava como um filtro.

O problema é que Bill se baseou no método heurístico. Ele não entende que filter é um método definido em matrizes, enquanto usersById é um objeto regular que não possui um método de filter .

O Bill confuso pesquisa no Google o " filtro javascript ". Ele encontra muitas referências a matrizes e percebe que precisa transformar usersById em uma matriz. Então, perguntando “ javascript para transformar um objeto em uma matriz ”, ele encontra exemplos usando Object.keys() no Stack Overflow. Depois disso, ele tenta:

 const attendees = Object.keys(usersById).filter(user => user.registered); 

Dessa vez, o erro não é exibido, mas, para surpresa de Bill, o campo de attendees permanece vazio.

O fato é que Object.keys() retorna as chaves do objeto, mas não seu valor. De fato, o nome da variável do user é facilmente enganador, porque não é um objeto do user , mas um identificador, ou seja, uma cadeia de caracteres. Como o atributo registered não está definido para cadeias, o filter trata cada entrada como falsa e a matriz fica vazia.

Bill examina as respostas do Stack Overflow e faz as seguintes alterações:

 const attendees = Object.keys(usersById).filter(id => usersById[id].registered); 

Desta vez, o resultado é melhor: ["5", "27", "39"] . Mas Bill queria obter objetos de visitantes, não seu ID.

Para entender como filtrar os visitantes, Bill, irritado, procura por um " filtro de objeto javascript ", examina os resultados da pesquisa pelo Stack Overflow e encontra essa resposta com o seguinte código:

 Object.filter = (obj, predicate) => Object.keys(obj) .filter( key => predicate(obj[key]) ) .reduce( (res, key) => (res[key] = obj[key], res), {} ); 

Bill copia estas linhas e tenta:

 const attendees = Object.filter(usersById, user => user.registered); 

Tudo funciona - embora não esteja claro o porquê. Bill não entende por que a reduce necessária e como é usada. Além disso, Bill não entende que acabou de definir um novo método não-padrão para o Object global.

Mas Bill não se importa - funciona! As consequências ainda não lhe interessam.

O que Bill fez de errado?


Bill tentou um método heurístico para resolver o problema e encontrou os seguintes problemas:

  1. Usando .filter() em uma variável, Bill obteve um TypeError . Ele não entendeu que o filter não filter definido em objetos comuns.
  2. Ele usou Object.keys() para "transformar o objeto em uma matriz", mas isso por si só não trouxe nenhum resultado. Ele precisava criar uma matriz de valores de objetos.
  3. Mesmo depois de receber os valores e usá-los como uma condição para a filtragem, ele recebeu apenas identificadores em vez dos objetos de usuário associados a esses identificadores. Isso ocorre porque a matriz filtrada continha um ID, não objetos do usuário.
  4. Com o tempo, Bill abandonou essa abordagem e encontrou uma solução funcional na Internet. No entanto, ele ainda não entendeu como isso funciona - e não perderá tempo resolvendo o problema, porque ele tem outras coisas a fazer.

Este é um exemplo artificial, mas já encontramos muitas vezes desenvolvedores que resolvem problemas da mesma maneira. Para resolvê-los efetivamente, você precisa se afastar dos métodos heurísticos e estudar a teoria.

Vamos para o básico


Se Bill fosse um proponente de uma abordagem teórica, o processo seria assim:

  1. Para identificar os dados de entrada fornecidos e determinar a saída desejada - no sentido de suas propriedades: “Eu tenho um objeto cujas chaves são cadeias de caracteres que representam ID e valores são objetos que representam usuários. Desejo obter uma matriz cujos valores sejam objetos de usuário - mas apenas objetos de usuários registrados ”
  2. Para entender como pesquisar dentro de um objeto: “Eu sei que posso obter uma matriz de chaves em um objeto chamando Object.keys() . Eu quero obter uma matriz porque matrizes suportam enumeração . "
  3. Para perceber que esse método ajuda a obter as chaves, é necessário transformá-las em valores e lembre-se do map - um método óbvio de criar uma nova matriz, transformando os valores de outra matriz:

     Object.keys(usersById).map(id => usersById[id]) 
  4. Para verificar que agora você tem uma matriz de objetos de usuário que podem ser filtrados e que contém valores reais que você deseja filtrar:

     Object.keys(usersById).map(id => usersById[id]).filter(user => user.registered) 

Vá Bill dessa maneira, ele poderia trabalhar para nós.

Por que as pessoas não recorrem à teoria com mais frequência?


Às vezes eles simplesmente não a conhecem. Na maioria das vezes, eles estão muito ocupados e não conseguem encontrar tempo para aprender essa maneira de resolver problemas - eles só precisam de tudo para funcionar. Eles correm o risco de transformar essa abordagem em um hábito que se tornará um obstáculo ao desenvolvimento de suas habilidades.

Para evitar esses erros, sempre comece com uma teoria. Em cada etapa do processo, pense em que tipo de dados você está lidando. Em vez de confiar em padrões familiares o tempo todo, considere tipos de dados primitivos: matriz, objeto, string etc. Ao usar uma função ou método, consulte a documentação para saber exatamente quais tipos de dados os suportam, quais argumentos eles usam e qual é o resultado.

Com essa abordagem, você pode encontrar uma solução funcional na primeira tentativa. Você pode ter certeza de sua correção, porque selecionou especialmente suas ações com base na entrada fornecida e na saída desejada. Vá fundo ao básico de cada operação (tipos de dados e valores de retorno), em vez de formulações comerciais difusas (como "usuários registrados").

Source: https://habr.com/ru/post/pt458642/


All Articles