Penso que, mais cedo ou mais tarde, todo desenvolvedor pensa em sua mente que o código precisa ser escrito de uma certa maneira. Por que a estrutura deste autor é tão fácil de usar e a imersão nela é tão rápida? Por que esse pedaço de código parece horrível para mim? Neste momento, uma rodada importante no desenvolvimento do desenvolvedor como profissional ocorre. Ele não apenas começa a pensar em como implementar uma tarefa específica, mas também em como
formalizar sua decisão. Pensamentos sobre uma certa estruturação do código e seu belo design começam a surgir na minha cabeça. Alguém começa a criar para si um certo conjunto empírico de regras para o design do código, alguém ajuda a literatura ou aconselha os camaradas mais experientes. Em qualquer um desses cenários, o código começa a ser visto não apenas como uma solução incondicional para o problema. Há pensamentos de que parte do código é
feia , mas aqui ficou legal e
elegante . Mas quem define esses critérios de beleza em relação ao código e o que é estabelecido neles? Está tudo claro sobre etiqueta e beleza de código?
Isenção de responsabilidade: este artigo tem como objetivo compartilhar pensamentos que surgiram no processo de tentar entender o conceito de código bonito. Esses pensamentos não reivindicam ser a verdade suprema. Só espero que esses pensamentos, pensamentos e argumentos provavelmente ajudem alguém a observar o processo de escrever código de uma perspectiva um pouco diferente. Além disso, nem uma única regra formal do formulário "Escreva o código dessa maneira e você será feliz". Uma grande quantidade de literatura de autores muito mais respeitados já foi escrita sobre esse tópico.
Todos os interessados em discussões sobre o tópico sobre o que é código de beleza, em que ele pode ser expresso, por que todas as práticas conhecidas não conseguem encerrar essa pergunta de uma vez por todas, peço gato.
Boas e más práticas
"... e perguntou ao bebê: - O que é bom e o que é ruim?" - Mayakovsky V.V.
E frequentemente nos perguntamos como formatar corretamente nosso código. Para responder a essa pergunta, uma grande quantidade de literatura profissional já foi escrita no mundo. Tomemos, por exemplo, os trabalhos mais populares sobre esse assunto, mais amplamente ouvidos:
Eu acho que há um grande número de livros que podem complementar esta lista. Mas a história não é sobre a necessidade de aplicar essa ou aquela abordagem. Não é sobre como este ou aquele livro é bom ou ruim. No decorrer da reflexão, podemos concluir que mesmo o uso de todas as boas práticas descritas nesses livros não garante um código bonito. E que tudo isso pode ser tanto em detrimento quanto para o bem. Acontece que, se não houver uma "fórmula para o sucesso" definida, talvez valha a pena começar pelo menos com um esboço de pensamentos sobre o que exatamente você deseja alcançar, tentando escrever um código bonito. Sabemos o que é código, mas nenhum de nós pode dizer o que é um código bonito.
Pré-requisitos para pensamentos
Não importa como alguém queira separar a programação em uma disciplina independente separada, tudo se resume à engenharia. Consequentemente, pensamentos e idéias gerais no campo da engenharia são válidos tanto para a indústria automotiva e de construção quanto para programação. Tudo isso é sobre a aplicação do conhecimento científico à criação de algo prático, até certo ponto material (se estamos falando sobre desenvolvimento de software, podem surgir disputas puramente filosóficas sobre a materialidade). Do ponto de vista prático, quanto mais simples o sistema (design, idéia) - mais conveniente, mais fácil de trabalhar e manter, e
mais bonito parece.
Uma explicação para esse pensamento é um exemplo da indústria automotiva.Tomemos um exemplo da indústria automotiva. No momento, temos uma grande variedade de carros de várias categorias e características de preços, além da estrutura interna das unidades. Vamos deixar de lado todos os pensamentos sobre o componente econômico (custo, relações públicas, marketing, etc.) e tentar avaliar a situação atual no mercado de automóveis em termos de confiabilidade. Tendo restringido o campo do raciocínio, nos restringimos à avaliação da unidade de potência. Isso se aplica, por exemplo, aos motores de automóveis. No momento, as pessoas já inventaram muitos tipos diferentes de motores, cada um dos quais é bom em seu campo. Os princípios de seu trabalho são pensamentos simples sobre a localização dos pistões, cilindros, número e volume. Tudo isso, em um grau ou outro, afeta apenas dois indicadores - confiabilidade e potência. As realidades atuais são tais que a solução mais confiável é usar uma grande unidade atmosférica. Os motores turboalimentados são menores em comparação com as soluções atmosféricas, no entanto, implicam o uso de uma unidade separada para suprimento de ar (turbinas), o que complica o sistema como um todo. Além disso, como o próprio motor é menor, em uma empresa com uma turbina, ele pode produzir a mesma ou até mais potência do que um motor de aspiração natural 2 ou 3 vezes maior. Isto é conseguido devido ao fato de que o motor, liberando mais potência, trabalha no limite de possibilidades. Ao mesmo tempo, um grande motor com aspiração natural produz aproximadamente a mesma potência, mas é mais fácil de usar e muito mais engenhoso. Ou seja, uma solução mais simples é ao mesmo tempo a mais pragmática.
Explicação deste pensamento por um exemplo da naturezaOutro exemplo simples pode ser retirado da natureza. Desde a sua aparição no planeta, as abelhas vêm construindo colméias. As colmeias são consideradas as estruturas de insetos mais avançadas. O problema é como as abelhas constroem favos de mel. Para a construção de favos de mel, é utilizado um mínimo de material - cera, que é apresentada da maneira mais ideal - na forma de hexágonos. Aqui podemos novamente observar o triunfo da simplicidade. Em vez de usar materiais mais fortes ou estruturas mais complexas (que provavelmente exigirão algumas colunas auxiliares, suportes e assim por diante), um material simples e uma forma simples, mas mais avançada, são usados para obter a solução mais pragmática e elegante . Evidência de que tal solução é bonita, muito. Tome, por exemplo, impressão 3D. Quem está mais ou menos interessado em impressoras 3D sabe que as impressoras imprimem modelos, dentro dos quais existe uma estrutura de favo de mel que espiamos nas abelhas.
Explicação dessa idéia por um exemplo de matemáticaNeste exemplo, a simplicidade pode não ser tão óbvia. Muitas pessoas, principalmente de mentalidade não técnica, acham a matemática complexa e a maior parte inútil. A idéia principal que lançou as bases para toda a matemática é a idéia de que todas as situações da vida podem ser modeladas. Deve-se ter em mente que muitas vezes o modelo resultante é muito mais simples e menos detalhado que o processo da vida real. O exemplo mais simples é, digamos que um pastor tenha um rebanho de ovelhas. Mas o dia estava difícil, e ele adormeceu no trabalho e, quando acordou, pensou que precisava ter certeza de que todas as ovelhas estavam no lugar. Neste momento, o aparato matemático mais antigo - números - pode vir em seu auxílio. Por si mesmos, os números não significam nada. Em uma figura abstrata, isoladamente da realidade, não há mais sentido do que tentar colocar calças sobre sua cabeça. Mas com relação à situação de determinar o número de objetos, eles não têm igual.
Vou dar um exemplo mais complexo. Meu programa universitário tinha um assunto extremamente útil chamado Algoritmos Combinatórios. A maior parte deste curso foi dedicada ao estudo da teoria de grafos e vários algoritmos de grafos. Falar sobre teoria dos grafos era anteriormente sobre outros assuntos, mas apenas superficialmente. Ou seja, todos os meus colegas de classe já imaginavam o que era e com o que era. Alguém até trabalhou em laboratório na implementação de qualquer algoritmo em gráficos. Mas foi em um dos pares de algoritmos combinatórios que o professor perguntou de repente: "E quem pode dizer por que esses gráficos são necessários?" Curiosamente, nenhum dos membros foi capaz de responder, com um silêncio grave. A resposta foi óbvia e simples - são necessários gráficos para modelagem. Por si só, ninguém precisa de gráficos, assim como a capacidade de implementar a travessia em largura ou profundidade. Mas, como aplicado a muitas situações da vida, é extremamente conveniente abandonar vários detalhes desnecessários e deixar apenas uma essência abstrata.
Existem muitos outros exemplos semelhantes da vida humana e da natureza que serão unidos por um pensamento comum: geralmente uma solução simples é a mais bonita. É no momento em que descubro quão simples esse ou aquele objeto parece ser tão necessário na vida, o pensamento de que ele é feito
maravilhosamente rasteja em minha cabeça. Enquanto não estamos falando de estética, exclusivamente sobre o dispositivo "compartimento do motor".
Uma vez deparei com o livro
Kevlin Henney - 97 coisas que todo programador deveria saber: sabedoria coletiva dos especialistas . Este livro tem 97 pequenos capítulos escritos por pessoas diferentes e relacionados apenas ao fato de serem todos sobre programação. Um tipo de sabedoria mundana de pessoas com vasta experiência em programação. Imediatamente faça uma reserva de que uma descrição tão detalhada não seja de forma alguma um anúncio. Mas não posso mencionar este livro, porque um de seus capítulos exige pensar que
código bonito é código simples . Em geral, é chamado de “a beleza está na simplicidade” (a beleza está na simplicidade). O autor inicia o capítulo com uma citação de Platão de que todas as coisas bonitas são simples:
A beleza do estilo, a harmonia, a graça e o bom ritmo dependem da simplicidade - Platão
Foi esse aforismo que despertou ainda mais meu interesse no campo do belo código e a aplicabilidade do conceito de uma “bela solução” ao código e, como resultado, a equivalência de um belo código ao simples.
O que é beleza?
Então, chegamos à própria questão da beleza do código. Para entender da maneira mais objetiva possível se beleza é sinônimo de simplicidade em nossa pergunta, devemos começar com um conceito básico. Vá para a Wikipedia para obter uma definição:
A beleza é uma categoria estética que denota perfeição, uma combinação harmoniosa de aspectos de um objeto, na qual este evoca prazer estético no observador.
Falando em código, não podemos raciocinar exclusivamente de um ponto de vista estético. Um código bonito (perfeito, bom) combina estética e semântica. A semântica do código também deve pertencer à categoria de "soluções bonitas".
Acho que muitos concordam que, além do valor prático, o código (mais precisamente, o resultado de seu trabalho e o processo de criação) é criativo. A analogia criativa mais próxima do desenvolvimento de software é a criação de uma obra literária. Esses ramos da criatividade, sem dúvida, têm muito em comum. Para simplificar, o código do programa pode ser comparado a um livro. Ambos são
simulacros de pensamentos. A única diferença é que, grosso modo, o resultado do código é algum tipo de resultado na tela do dispositivo, e o resultado da leitura do livro são
alucinações, séries visuais, associações e impressões que surgem em nossas mentes. Ao escrever livros, um grande número de regras é levado em consideração, permitindo que você formate corretamente o texto. Esse momento é semelhante às regras de uma linguagem de programação e ao fluxo de trabalho do compilador / tradutor / intérprete. O texto fonte do livro passa por rigorosa edição iterativa antes de aparecer diante dos olhos do leitor. Mas o conteúdo é mais importante. Por outro lado, poucas pessoas podem dominar o livro mais interessante e fascinante até o fim ou entender corretamente se os pensamentos não forem corretamente (leia-se: lindamente) enquadrados em um texto coerente.
Por que o código bonito é importante?
Na expressão dos pensamentos no papel, sem dúvida vale a pena focar nas regras da linguagem, bem como na estrutura e simplicidade da expressão. Impressões e pensamentos que serão transmitidos ao leitor e que imagens aparecem em sua cabeça dependem diretamente disso. Tudo é um pouco mais complicado com o código. O usuário final do nosso software não se importa com a beleza da escrita e com o tipo de experiência que o desenvolvedor obtém ao trabalhar com esse código. O usuário final está interessado apenas na qualidade do produto lançado, em como ele funciona e em como é conveniente usá-lo.
Diferentemente da literatura, a qualidade do código é uma característica importante para o desenvolvedor ou a equipe que trabalha nele. Não precisa ser desenvolvedor. Toda a equipe (por exemplo, gerentes de projeto, chefes e investidores) pode sofrer uma abundância de erros durante o desenvolvimento. No entanto, no caso de especialistas de outras áreas, a beleza do código os preocupa apenas indiretamente. Primeiro de tudo, os desenvolvedores se tornam vítimas de código feio. Por que isso é tão importante para eles? Na maioria das vezes, ao desenvolver um produto, passamos a analisar o código, navegando nele, em busca de um local onde você precisa escrever ou corrigir as linhas necessárias.
Tudo seria muito mais simples se uma pessoa estivesse envolvida no desenvolvimento de um determinado produto. Todo o código-fonte seria consistente e compreensível para ele. Mas, para que esse mesmo software possa ser desenvolvido em tempo real, e não décadas, uma equipe de vários desenvolvedores geralmente está envolvida no desenvolvimento de um software. Faz seus próprios ajustes. Por exemplo, o conceito de beleza (em particular, a beleza do código) cada desenvolvedor pode ter o seu. Mas como o trabalho continua em equipe - são definidos padrões para configurar a equipe para pensar
mais ou menos o mesmo. Isso nos permite fazer com que, ao ler o código, o desenvolvedor nem sempre possa entender ^ se ele ou outra pessoa escreveu o código e quem exatamente, e dá uma sensação de comunidade, integridade da equipe. Dizemos "Código do nosso aplicativo", e não "meu pedaço de código" ou "meu script". Grosso modo, estamos tentando obter uma idéia geral sobre a beleza de um grupo de pessoas conectadas por um software e, na maioria das vezes, nada mais. Acontece que, no conceito de código de beleza, há subjetividade, mas tentamos minimizá-lo dentro da equipe. Mas é possível tornar o conceito de código beleza completamente objetivo? O que estamos recorrendo na tentativa de alcançar a beleza objetiva e quanto isso funciona? Para chegar à resposta a essas perguntas, vale a pena considerar o pouco em comum que absolutamente todas as pessoas têm. A saber: o cérebro e como processa a informação.
Qual é o melhor trabalho do cérebro?
Na Internet, você pode encontrar inúmeros artigos sobre como o cérebro funciona no reconhecimento de informações. Por exemplo, você pode consultar
este artigo.
Nosso cérebro processa uma enorme quantidade de informações e, para otimizar sua atividade, usa modelos. Esses padrões são formados no curso de nossas vidas. Um bom exemplo é o processo de leitura. Quanto mais literatura uma pessoa lê em um idioma, maior sua velocidade de leitura. Quanto mais livros você lê, mais palavras você lê e mais vezes você os encontra. O reconhecimento visual de palavras que ocorrem com frequência ocorre muitas vezes mais rápido do que a leitura de uma nova terminologia (especialmente para uma área de assunto desconhecida). Quanto mais livros um autor leu, mais rápido ele será capaz de ler outros trabalhos desse autor. Isso é verdade porque cada autor possui um vocabulário e estilo de escrita limitados.
Se você olhar mais fundo, aprendemos a ler a partir do fato de que estamos aprendendo o alfabeto. Mais precisamente, aprendemos a reconhecer letras escritas e só então assumimos o reconhecimento de palavras. Outro fato interessante está relacionado ao reconhecimento de letras - a velocidade de reconhecimento de letras pelo cérebro também depende da fonte, se estamos falando de texto impresso ou de caligrafia para textos manuscritos. Além disso, quando se trata de textos manuscritos, a situação pode chegar ao ponto do absurdo - a escrita pode ser tão ruim que simplesmente não conseguimos entender o que está escrito (olá para os médicos). O processo de ensinar uma criança a ler, provavelmente, é precisamente o fenômeno vital que inspirou as pessoas a criar redes neurais. Aqueles que estão interessados neste tópico podem ver materiais sobre como o texto é reconhecido usando algoritmos de redes neurais.
Quando lemos as palavras, somente nos estágios iniciais prestamos atenção a todas as letras. E eles nos ensinam a ler de acordo - primeiro por letra, depois por sílabas e só então por palavras. Existe um estudo interessante, cuja tese pode responder por si mesma:
Segundo os rzelulattas, o ilseovadny odongo de um unquirtiset unly não está aberto, em casulos as abóboras em solva são assadas imediatamente. Galvone, cortando e batendo bkvuy blyu no msete. No passado, os bkuvs podiam ser selados em um texto completamente aberto e totalmente rasgado, sem brem. Pichriony Egoto, é porque não fabricamos cada abóbora separadamente, mas é tudo sólido.
E essa é outra prova de que o cérebro trabalha com padrões. Todas as novas informações que recebemos do cérebro também estão tentando conduzir os modelos existentes, recorrendo a 3 princípios básicos:
- exclusão - excluímos da memória informações exclusivas (menos modelo) não utilizadas
- distorção - refere-se ao exagero ou subavaliação de algo. Por exemplo, em nossa vida cotidiana as palavras “nunca”, “sempre”, “nada”, “tudo”, “tudo” são frequentemente usadas. Se você pensar bem, todo uso dessa palavra é uma mentira ou uma distorção dos fatos.
- — -, . .
, ,
, . . , . — (code in terms of domain). , ( — «» «»).
Depois de pensar nos modelos, pensei em qual código funcionaria mais. O pensamento de ofuscar o código passou pela minha cabeça. Afinal, isso é feito apenas para complicar a compreensão de outros programadores do funcionamento interno do seu sistema. Além disso, o código ofuscado mostra claramente a importância da percepção visual do código.Como métodos de ofuscação, você pode trazer este conjunto:- Nomes longos e sem sentido de variáveis, classes, métodos e funções. As palavras longas não são apenas mais difíceis de ler, mas você nunca viu essas combinações de letras e números em sua vida.
- , . , , . , . , . , . - , « ».
- , . . , , . . , .
Acontece que um código bonito deve ser criado a partir de repetições redundantes simples . Existe até um acrônimo conhecido DRY sobre esse assunto - não se repita. No entanto, isso sempre é verdade se você olhar para o mundo em geral?Um ótimo exemplo é a música. Ela não pode se locomover sem repetição. Vale ressaltar que há exceções a essa afirmação. O exemplo mais simples de uma exceção é o solos virtuosos. Eles são lembrados pelos fãs, apesar de muitas vezes não conterem repetições. Mas, em geral, a regra funciona. Se você olhar para a música que está ganhando cada vez mais força - Rap / Hip-hop -, você pode ver isso mais claramente. A estrutura negativa consiste quase completamente em simples fragmentos de repetição curta, que nem sempre caracterizam sua beleza. Como um exemplo degenerado, podemos lembrar o metrônomo - ninguém argumentará que seu tique-taque uniforme e monótono é uma excelente composição musical.Um aumento no número de repetições na música pode ser considerado sua otimização ou melhoria? Você pode ver a música clássica primeiro, cheia de movimentos inesperados, partes únicas e um pequeno número de repetições. A tendência atual é quase independente do gênero, os trabalhos se tornaram mais curtos. Eles agora são chamados de músicas e são completamente estereotipados em termos de estrutura - há uma introdução, um refrão, uma simples palestra. Tomamos esses componentes em várias variações e combinações e obtemos uma fórmula mais ou menos universal. Tais trabalhos são mais fáceis de "ir" para o público. É por isso que existem muitos mais conhecedores de música clássica e conhecedores de música popular.Eles agora são chamados de músicas e são completamente estereotipados em termos de estrutura - há uma introdução, um refrão, uma simples palestra. Tomamos esses componentes em várias variações e combinações e obtemos uma fórmula mais ou menos universal. Tais trabalhos são mais fáceis de "ir" para o público. É por isso que existem muitos mais conhecedores de música clássica e conhecedores de música popular.Eles agora são chamados de músicas e são completamente estereotipados em termos de estrutura - há uma introdução, um refrão, uma simples palestra. Tomamos esses componentes em várias variações e combinações e obtemos uma fórmula mais ou menos universal. Tais trabalhos são mais fáceis de "ir" para o público. É por isso que existem muitos mais conhecedores de música clássica e conhecedores de música popular.Outro exemplo desse fenômeno de constante repetição e simplificação é a indústria de jogos. O gênero de jogos casuais, fluindo suavemente para o gênero hiper-casual, está ganhando cada vez mais popularidade. São jogos destinados a repetir uma cadeia simples de ações rápidas, estritamente limitada por um curto período de tempo. Embora jogos variados complexos e jogos de baixa repetição, por exemplo, o gênero de estratégias, estejam passando portempos difíceis agora.Se houver um exemplo da inoperabilidade da abordagem simples de padrão não redundante, essa abordagem deve sempre funcionar para o código?Como obter código OOP simples e o que pode ajudar?
A partir do momento em que mergulhamos na profissão, complexos e intrincados, à primeira vista, princípios e abordagens estão circulando ao nosso redor. Especialistas seniores, sob cuja ala estudamos, falam sobre várias abordagens, padrões e livros que valem a pena ser lidos para ter sucesso no campo da POO. Acho que as palavras mais ouvidas são padrões de design e SOLID . Nem todo mundo fica imediatamente claro por que tudo isso é necessário. Mas o ponto geral é escrever um código bonito e correto. E como isso nos ajuda, e é sempre? Todos os padrões e abreviaturas mágicas têm como objetivo ensinar-nos a pensar em programação com os mesmos padrões que ao ler e analisar texto simples.Os padrões de design são sempre bons?
Desde o início, os desenvolvedores aprenderam padrões. Vamos tentar descobrir o porquê. Qualquer padrão de design visa tornar a entidade o mais compacta possível e simples. Ela não fez o que não deveria e fez o que lhe era exigido da maneira mais concisa. Tudo isso não é apenas tornar a solução arquitetonicamente sustentável, mas também facilitar a compreensão da solução. De projeto para projeto, você usa aproximadamente o mesmo conjunto de padrões. A repetição frequente desses padrões acelera o processo de design e o processamento do código existente no cérebro, reduzindo o tempo necessário para a busca de um determinado código.O desenvolvimento de software por si só não interessa a ninguém, exceto para fins educacionais, que podem ser deixados de fora da caixa. O desenvolvimento de software sempre tem algum tipo de objetivo comercial. Vale a pena notar aqui que, quando se fala em uma meta de negócios, nem sempre se trata de dinheiro. Talvez o objetivo seja ganhar uma reputação, ajudar alguém ou simplesmente se mostrar para a família / amigos ("Olha, eu escrevi um jogo!") E assim por diante. Na maioria das vezes, é uma meta de negócios fundamental para a escolha da arquitetura do aplicativo. Primeiro, os requisitos são analisados, com base nos quais se pode concluir se o software será suportado, qual será o ciclo de desenvolvimento. Todos esses fatores são sobrepostos a informações sobre recursos - uma equipe ou seu próprio conhecimento. Todos esses fatores são explícitos ou implícitos (se você está apenas começando sua jornada no desenvolvimento de software,você não precisa pensar em arquitetura, mas definitivamente começará em breve) afetará as abordagens e os padrões que usará durante o desenvolvimento. Com base na arquitetura, abordagens e padrões escolhidos, uma base de código de software é exibida.Antes que a conversa se transformasse em padrões de design, a beleza do código podia ser vista de uma maneira abstrata. Ou seja, era possível imaginar hipoteticamente algum arquivo de origem retirado do contexto. Guiados exclusivamente pelo componente visual do código, sem prestar atenção à sua semântica, podemos concluir se o código é bonito ou não. É quando, em um momento preciso, a fonte abstrata se torna parte da base de código (parte de algo maior, parte de software), novas variáveis começam a ser introduzidas na equação de beleza do código.Suponha que um projeto chegue a um novo desenvolvedor que nunca viu o código desse projeto. Antes de tudo, ele precisa entrar no projeto, em outras palavras, para estudar a base de código. Durante o estudo, o desenvolvedor formará sua opinião sobre o projeto, mais precisamente sobre o que ele consiste. E, neste momento, o desenvolvedor pode ter os seguintes pensamentos - “Esta solução é feia” ou vice-versa “Uau! Que solução elegante (bonita) ... ". Nesse caso, beleza refere-se à arquitetura, que é expressa por meio de código. Ou seja, o conceito de beleza semântica também pode interferir com o conceito de beleza de código - desde que a solução seja arquitetonicamente correta. A abordagem ou o padrão foi selecionado corretamente e é sustentado.Este é exatamente o lugar onde tudo se torna mais complicado:- Se você não está familiarizado com essa ou aquela abordagem, sua ideia pode não ser óbvia, incompreensível e percebida em um contexto negativo ou positivo. Tal caso é o mais imprevisível.
- Você pode estar familiarizado com a abordagem e adotá-la negativamente, por exemplo, antipadrões.
- Você pode estar familiarizado com a abordagem e encará-la positivamente.
Nos dois últimos casos, será muito mais fácil você concluir e expressar seus pensamentos sobre o código e sua beleza.Acontece que é precisamente por isso que todos somos forçados a aprender padrões de design - para que todos falemos a mesma língua, de maneira padronizada. Além disso, um padrão é o que nosso cérebro gosta de trabalhar.No entanto, chegamos ao ponto em que tudo pode não ser tão simples quanto parece. Um arquivo de origem pode combinar a implementação de vários padrões. Omitimos a questão da correção de tal solução, depende muito da situação e pode ser a decisão certa e a errada. Diluir a implementação de um modelo com a implementação de outro pode complicar a percepção do código, tornando-o feio aos nossos olhos. Um padrão implementado incorretamente exacerba a situação. Pode parecer para você, até o final, que você entende o código, uma vez que está subordinado ao padrão e, então, acontece que durante todo esse tempo você o percebeu incorretamente. Nesse momento, um código bonito perde todo o seu charme e se torna não tão bonito, mas com um amor. Nesse caso, a falta de um padrão pode parecer mais bonita,do que um padrão implementado incorretamente. Outro aspecto diz respeito a abordagens ou antipadrões incorretos. Em essência, um antipadrão é um padrão que não deve ser usado. No entanto, esse é um padrão que, de certa maneira, confere legibilidade e compreensão, isto é, simplicidade e beleza ao código. Acontece que o uso de padrões no código do projeto é uma faca de dois gumes.Estilo de escrita da API
Falando sobre o belo design da API, na maioria das vezes, trata-se de um determinado serviço ou de uma biblioteca (ou estrutura). O serviço geralmente parece ser algo externo ao código; portanto, em nosso contexto, é melhor considerar a biblioteca. A escolha de um ou outro tipo de API afetará não apenas a estrutura do código da biblioteca, mas também a aparência do código do cliente usando a biblioteca. De improviso eu posso trazer 2 estilos.O estilo clássico é que enquadramos a biblioteca em uma entidade específica (classe) e todos os métodos que estão nessa classe executam uma ação específica, retornando um resultado específico que não depende do estado da entidade principal da biblioteca. A maioria dos vários plugins é feita no estilo clássico, portanto, não deve haver problemas para entender esse estilo.O segundo estilo são interfaces fluidas . Essa abordagem consiste no fato de que, na saída da biblioteca, obtemos o mesmo objeto que acionou a ação, apenas agora configurado de forma um pouco diferente. Um exemplo é a implementação do LINQ em C #. Nele, ações em cadeia são executadas na mesma coleção (IEnumerable). Em cada etapa da solicitação, de alguma forma, modificamos a coleção até obter o resultado desejado. Outro exemplo do C # é um contêiner de injeção de dependência chamado Zenject .Nele, os ligantes de dependência são escritos em um estilo fluido:Container.Bind<Foo>().AsSingle().NonLazy().FromInstance(FooInstance");
Um exemplo muito famoso de uma interface fluida da Swift é a estrutura popular
Alamofire .
Nele, você pode ver frequentemente esses desenhos:
Alamofire.request( .GET, "http:foo.com", parameters: ["include_docs": "true"],encoding: .URL).validate().responseJSON { (response) -> Void in... }
Na maioria dos casos, o estilo apropriado pode ser escolhido com base na situação atual. Mas ninguém se preocupa em reescrever a API da biblioteca de um estilo para outro sem alterar a funcionalidade e isso se torna uma questão de gosto ou beleza. Em geral, as interfaces fluidas não são tão comuns quanto o estilo clássico, mas, dependendo de um grande número de fatores, elas podem tornar o código mais bonito ou mais feio. A derivação de uma fórmula universal aqui também falha.
Produtos de beleza para idiomas
Já chegamos à conclusão de que, para a beleza, precisamos de modelos, sem eles em qualquer lugar. Os padrões devem ser reconhecíveis, simples e curtos. Com padrões de design, tudo acabou sendo ambíguo. Mas, além dos padrões arquitetônicos, as construções da linguagem que você está escrevendo também vêm em socorro. O mesmo padrão de design implementado em um idioma pode parecer bonito e feio, dependendo de ferramentas de idioma específicas.
Comum para a maioria, se não todas as linguagens de programação, para a maioria, está comentando uma ferramenta de linguagem que não afeta a semântica do código, mas afeta sua beleza. Adicionar um bom comentário no lugar certo pode melhorar a aparência do código. Mas vale a pena escrever um comentário isoladamente do estilo geral (por exemplo, linguagens do tipo c permitem descrever comentários de três maneiras diferentes), pois estraga imediatamente a imagem geral e distrai visualmente a percepção do próprio código.
Como vítima, vejamos algumas das ferramentas que o C # nos fornece. Uma das ferramentas mais simples nesse idioma é a palavra-chave
var . Evita indicar explicitamente o tipo de uma variável quando é declarada, usando var para qualquer tipo ou interface.
Por um lado, essa ferramenta ajuda a remover quase todos os nomes de tipos nos corpos dos métodos. Por outro lado, faz você pensar sobre a que tipo essa ou aquela variável pertence. A grande maioria dos desenvolvedores que condolenciam o C # consideram o uso de var uma boa prática. Ou seja, essa ferramenta de linguagem pode ser considerada mais útil do que prejudicial em termos de beleza do código.
A diretiva
#region #endregion permite especificar blocos de código que podem ser recolhidos no IDE. É uma das ferramentas mais controversas. Em algumas equipes, o uso desta diretiva é estritamente proibido; em outras, é recomendado de forma obrigatória. Um argumento para não usar essa diretiva é que ela dilui o código com inserções semanticamente inúteis que impedem que você se concentre no próprio código. Como argumento "para", pode-se citar uma prática em que os métodos de classe são agrupados por região, de maneira que você possa facilmente e sem editar o código ver sua implementação interna, ou uma API externa, ou uma implementação de um ou outro padrão (que geralmente pode parecer modelo e é removido para a região para que os olhos não fiquem com calos). Em resumo, podemos dizer que a ferramenta é mais do que controversa.
A ferramenta final a considerar com certeza é
expressões lambda e métodos anônimos. Em termos gerais, podemos dizer que ambas as ferramentas são projetadas para descrever o método da maneira mais compacta possível, geralmente sem declará-lo explicitamente. Para esses propósitos, podemos resgatar recursos como diminuir a assinatura, tipos de parâmetros de entrada e saída, forçando o compilador a exibir tudo isso explicitamente para nós. A ferramenta, que muitos tendem a considerar parte integrante da linguagem, tem a posição mais controversa em termos de beleza do código. Por exemplo, é difícil imaginar o LINQ sem expressões lambda, pois elas são compactas e concisas. Mas se você abusar do uso deles, todo o código da classe pode ser facilmente transformado em uma bagunça ilegível.
Ferramentas de linguagem como métodos de extensão (métodos de extensão), foreach vs for, métodos anônimos, operador ternário, encadeamento de construtores e outros permanecem fora do escopo da análise. Todos eles também estão unidos pelo uso controverso em certas partes do código. A partir disso, podemos concluir que não há açúcar sintático perfeito, o que torna o código inegavelmente mais bonito.
Como um material adicional sobre o tema do açúcar sintático, não posso perder a jovem linguagem de programação - Swift. Na maioria das vezes, ele não oferece construções de linguagem exclusivas. No entanto, sua capacidade de omitir o ";" no final da linha de código, fiquei mais desmembrado com minha noção atual do processo de escrever código. Eu sei que, na leitura usual desse recurso, ele não é percebido como algo fora do comum. Porém, durante o desenvolvimento do combate nesse idioma, a princípio foi bastante difícil reconstruir. Não escreva ";" no final de uma linha de código é a prática recomendada nesse idioma. Parece que isso é um pouco real, mas você também pode traçar um paralelo com ele fora do contexto de programação. Esse paralelo está nas regras de pontuação da maioria dos idiomas do mundo. Estamos acostumados a colocar pontos no final de uma frase, durante anos formando um padrão para reconhecer pensamentos completos em um texto. Talvez em uma oportunidade simples de omitir ";" uma regra oculta está oculta no código, que pode ser expressa da seguinte maneira: escreva apenas um prazo de código em uma linha do arquivo de código-fonte. E esta recomendação é expressa em última análise na forma de prática para não colocar ";" no final da linha, não dando a oportunidade de adicionar outra coisa a essa linha. No entanto, Swift também possui algumas boas inovações de sintaxe, como a declaração de
guarda .
Se for sobre ";" no final de uma linha de código, é difícil não mencionar a linguagem Python. Essa linguagem está repleta de todos os tipos de açúcar sintático. Uma parte considerável desse açúcar é controversa, mesmo que eu possa dizer que claramente não é necessário, apenas complicando a leitura do código. No entanto, tudo isso é ambíguo no contexto do fato de que o limiar para entrada no idioma é extremamente baixo. Parece que os desenvolvedores de linguagem fizeram todos os esforços para garantir que você possa escrever código em Python, prestando o mínimo de atenção possível à sintaxe. Outro dos recursos dessa linguagem, eu observaria a falta de alocação explícita de blocos de código (os colchetes "{}" não são usados). Em vez de destacar explicitamente as vidas de Python recuadas. Por um lado, isso é melhor percebido visualmente, porque o texto possui menos caracteres de serviço sem sentido. Por outro lado, você deve prestar atenção ao recuo, que na maioria dos idiomas claramente não é necessário. Esta linguagem não poderia prescindir das quebras dos padrões C. Em vez de uma instrução try-catch, temos try-except. Pelo nome, o operador parece lógico, mas é difícil reconstruir.
Como o último exemplo controverso de uma ferramenta de linguagem encontrada em muitas línguas, darei classes e métodos generalizados (Genéricos). As generalizações em si são projetadas para nos salvar de ter que duplicar fortemente o código padrão. Ou seja, pelo menos em termos de livrar-se da duplicação de código em locais diferentes, as generalizações servem como uma ferramenta para tornar o código mais bonito. Mas o próprio conceito de um tipo parametrizado por outro tipo é percebido bastante difícil. Cada vez que se depara com a generalização no código, é preciso dedicar mais tempo à compreensão da semântica do que à compreensão da semântica do código não generalizado.
Considerando os pontos indicados acima, pode-se argumentar que o açúcar sintático também é uma ferramenta controversa que pode tornar o código cada vez menos bonito.
O lado do software que pode nos ajudar
Toda a subjetividade da abordagem para escrever código e o conceito de sua beleza podem ser confusos. Esse problema é especialmente grave em uma situação em que um novo desenvolvedor chega a uma equipe bem coordenada. Freqüentemente, um iniciante não tem escolha a não ser imitar o código já escrito e ajustar no curso ao estilo existente. É disso que a maioria das pessoas não gosta quando chega a um novo emprego. Todos os seus padrões de percepção, cadeias neurais, reflexos que se formaram ao longo dos anos de experiência, começam a causar danos em vez de benefícios passados. Felizmente, pelo menos nessa área, é possível introduzir algumas práticas gerais, livres de subjetividade.
Além disso, temos pensado e resolvido isso por um longo tempo. Os IDEs modernos foram muito longe dos editores de texto convencionais e podem facilitar muito a tarefa de manter o estilo do código. O destaque da sintaxe é talvez a ferramenta mais antiga do IDE. Apesar de sua simplicidade e familiaridade, a idéia é a mesma - formar um modelo específico que ajude a escrever código. O exemplo mais simples é sublinhar uma determinada palavra no código em vermelho por erro. Além disso, muitos lugares duvidosos aos quais você deve prestar atenção estão marcados em amarelo. Tudo isso junto é um modelo que se formou em nossa cabeça desde a infância com a ajuda dos semáforos.
Em termos de beleza do código, os IDEs modernos também tentam ajudar o máximo possível. Por exemplo, você pode usar um IDE bastante jovem no JetBrains - Rider. Aqui, a simplificação das condições lógicas e a ajuda na escolha de um nome de variável, verificação ortográfica de comentários e nomes de variáveis, alinhamento automático e muito mais são úteis.
Quanto à nomeação de variáveis, alinhamento do código, inserção de guias em vez de espaços e espaços no código mesclado - esse é todo o ponto principal que ajuda a projetar o texto como código em um estilo que combina com você. E o IDE fará a maioria dessas edições em segundo plano para você. Acontece que você só precisa ensinar a ela o que deseja e, posteriormente, ele se tornará um assistente indispensável para você, o que economizará muito tempo. Os detalhes de como ensinar seu estilo ao IDE não são relevantes para o assunto deste artigo. Mas se você pensar nesse conceito como um todo, o processo será muito semelhante ao processo de introdução de um novo desenvolvedor na equipe. Uma ferramenta indispensável para isso é um documento de contrato de estilo de código. A única diferença é que o desenvolvedor o receberá na forma de um documento e o IDE o gerará ou salvará em um arquivo de configuração interno, em um formato que apenas um deles entenda.
Assim, o passo inegável em direção a um código bonito é sua padronização. Muitas empresas em todo o mundo não escrevem um documento que padronize o estilo do código. Acontece que uma catástrofe assume proporções terríveis - o número de projetos que estão sendo desenvolvidos simultaneamente na empresa é igual ao número de estilos de codificação usados na empresa. Em tais circunstâncias, a transição de um desenvolvedor de um projeto para outro se torna ainda mais trivial. Se ninguém monitora a padronização da base de código, o código tende a se transformar em um código em massa, e a adaptação em um novo projeto parece mudar para outra empresa, causando mais estresse do que poderia. Juntamente com um aumento no nível de estresse durante a transição para um novo projeto, o período de adaptação também aumenta.
Tais problemas podem ser evitados tendo em estoque apenas um documento com uma convenção de estilo de código. Este documento também pode ser considerado uma ferramenta de desenvolvimento. Tendo esse documento e um IDE moderno em seu arsenal, você pode simplificar bastante sua vida automatizando o estilo do código no nível do IDE. Isso reduzirá o limite para o desenvolvedor ingressar na equipe e o número de reivindicações contra o desenvolvedor durante a revisão do código. A idéia de automatizar e usar as ferramentas de desenvolvimento ao máximo está longe de ser nova, pode ser encontrada em várias fontes, incluindo o lendário livro "Pragmatista-programador".
Resumindo: as ferramentas de desenvolvimento têm um efeito muito positivo na beleza do código. Além disso, o fator de subjetividade não afeta a utilidade dessas ferramentas.
Um lado do software que pode estragar tudo.
Já nos familiarizamos com a parte boa do software. Mas todas as soluções técnicas visam tornar o código mais bonito? Acontece que quando um produto está quase pronto para lançamento, verifica-se que ele não corresponde às características técnicas de um dispositivo específico, que é tão importante para o suporte. Esse problema é especialmente grave no campo do desenvolvimento de software de jogos. Alguém pode ter objeções razoavelmente razoáveis de que você pode escrever imediatamente o software ideal e fazer otimização durante o desenvolvimento, obtendo a solução mais ideal. Para tais objeções, pode-se citar um contra-argumento:
A otimização prematura é a raiz de todo mal. -Donald Knut
O debate sobre se essa afirmação é verdadeira ou não não diz respeito à beleza do código e está além do escopo do raciocínio atual.
Mas a otimização pode afetar adversamente a beleza do código. Isso nem sempre acontece, mas existem algumas práticas que provavelmente podem ser expressas longe do código mais legível. Exemplos de tais otimizações:
Essas otimizações são bastante difíceis de implementar, mas são necessárias no desenvolvimento da computação de alto desempenho e em várias outras situações. Mas, por exemplo, o uso excessivo de interação multithread tende a complicar bastante o código. Temos uma situação em que a beleza do código pode ser sacrificada para otimização técnica.
Com quem posso entrar em contato para obter conselhos?
Decidimos que, independentemente da subjetividade do conceito da beleza do código, existem práticas para ajudar a mantê-lo - um documento sobre o estilo do código e um IDE configurado corretamente. Este pacote pode realmente facilitar a vida, mas não garante um resultado de 100%. A razão para isso é o fator humano. O desenvolvedor pode estar familiarizado com o documento de estilo de código, ter um IDE configurado corretamente e, no entanto, ignorar todas as regras e avisos do IDE. Pode haver pelo menos 2 razões para isso:
- Desenvolvedor sem escrúpulos. Talvez o desenvolvedor ainda não esteja acostumado a um novo estilo para ele e escreva da maneira usual. Ou talvez ele simplesmente não considere manter um estilo comum um ponto importante, que vale a pena prestar atenção.
- Uma certa combinação de circunstâncias. A maioria de nós conhece ou tentou o Agile e pratica sprints com um prazo fixo e um conjunto de tarefas. Na vida, há situações em que uma solicitação veio “de cima” sobre a necessidade de implementar um recurso importante aqui e ontem que não foi incluído no sprint atual. Nenhuma empresa pode garantir que isso não aconteça. Ao implementar esses recursos, muitas vezes coisas acontecem, como uma “decisão no joelho” e um “hotfix”. Muitas vezes, essas coisas são feitas por uma questão de velocidade e simplesmente não há tempo para seguir a beleza de uma edição dessas.
Não importa o motivo que levou o desenvolvedor a escrever um código feio e preenchê-lo em uma base de código comum. Ao mesmo tempo, assim que uma emenda entrar na liberação, é provável que ela permaneça em uma forma tão feia. Parece que o que poderia dar errado se todos entendermos que isso acontece apenas em situações excepcionais e que isso não pode ser feito? A essência do problema é que esse é o precedente que ocorreu. Isso significa que é muito provável que, depois de algum tempo, quando todos esquecerão o contexto da situação ocorrida, algum desenvolvedor depare com esse código feio durante o trabalho. Então, pensamentos errados podem surgir em sua mente: se isso já estiver no projeto, a adição de outra porção não ficará pior. A receita para o desastre é simples - repita a última ação n vezes até que o projeto inteiro consista em lugares "excepcionais" - janelas quebradas.
Tal efeito é muito bem descrito em
Broken Window Theory . Você pode lidar com janelas quebradas de maneira simples - precisamos apenas de um guarda que monitore o código. Em relação à programação, essa solução se encaixa bem com o conceito de revisão de código. Não posso citar um único efeito colateral ruim da prática de realizar revisões regulares de código. A única coisa que as pessoas líderes podem tocar é o desperdício de um tempo significativo na condução de uma revisão de código e na correção de comentários. Pode ser difícil para essas pessoas explicar o que é dívida técnica e de onde ela vem. Mas, no contexto da beleza do código, a revisão de código é uma prática puramente positiva.
Além da pessoa que conduz a revisão de código no projeto (ou várias pessoas), você também pode entrar em contato com os desenvolvedores da linguagem ou com o guru da programação para obter orientação. Obviamente, você não deve confiar no fato de poder escrever uma carta ou ligar diretamente por esse mesmo guru. Porém, para a maioria das linguagens de programação, existem oficiais ou geralmente aceitos
padrões de estilo de código escritos por pessoas respeitáveis. Exemplos:
- Python - PEP8
- C # - StyleCop
- Swift - O Guia oficial de estilo do raywenderlich.com Swift
- Objective-C - O guia oficial de estilo do raywenderlich.com Objective-C
Seguir os padrões de estilo de código geralmente aceitos é uma boa prática para ajudar a manter seu código bonito. Embora a subjetividade também esteja presente em padrões geralmente aceitos, não é possível concluir que o código escrito por padrões comuns seja bonito.
Conclusão sem conclusão
Todos os pensamentos considerados sobre a beleza do código levam exclusivamente à sua subjetividade, mesmo em termos de simplicidade. A simplicidade, por sua vez, decorre de quão fácil é entender o código e quão compacto é (ou vice-versa). Todas as ferramentas descritas, a escolha entre uma abordagem ou outra, formam uma caligrafia, dando reconhecimento e apoio de outros desenvolvedores. Ao mesmo tempo, verifica-se que o conceito de beleza no código ainda se presta a alguma padronização, embora muito fraca. Em termos gerais, podemos assumir que o padrão está mais correlacionado com a beleza do código, embora sejam possíveis variações aqui.Chegar a um consenso entre todos os desenvolvedores do mundo pode nunca ter sucesso. Mas vale a pena abordar a conclusão do conceito de código de beleza. Talvez, pensando em por que você prefere escrever de uma maneira ou de outra, comece a escrever um código mais legível e a expressar seus pensamentos com mais clareza no código. Ou, esse entendimento o ajudará a fazer a escolha na direção de alguns dos estilos existentes.