As estruturas colocam muita abstração? [fechadas]

24

Estou programando há pouco menos de um ano e tenho alguma experiência em escrever aplicativos de sistemas, aplicativos da web e scripts para empresas / organizações. No entanto, uma coisa que eu realmente nunca fiz foi trabalhar com um framework como Django, Rails ou Zend.

Observando a estrutura do Django, estou um pouco frustrado com o quanto é abstraído nas estruturas. Entendo os objetivos principais do código DRY e mínimo, mas parte dessa dependência excessiva de diferentes módulos e da pesada abstração das principais funções parece:

  1. Faz com que os programas sejam datados muito rápido devido à natureza em constante mudança dos módulos / estruturas,

  2. Torna o código difícil de entender por causa da infinidade de estruturas e módulos disponíveis e de todas as suas idiossincrasias,

  3. Torna o código menos lógico, a menos que você tenha lido toda a documentação; ou seja, eu posso ler algumas compreensões de lista e lógica condicional e descobrir o que um programa está fazendo, mas quando você vê funções que exigem a passagem de strings e dicionários arbitrários, as coisas ficam um pouco difíceis de entender, a menos que você já seja um guru em um determinado módulo; e:

  4. Torna difícil e entediante alternar entre estruturas. Alternar entre idiomas já é um desafio, mas é gerenciável se você tiver uma compreensão suficientemente forte de sua funcionalidade / filosofia principal. Alternar entre estruturas parece ser mais uma questão de memorização mecânica, o que, de certa forma, parece incentivar a própria ineficiência que essas estruturas foram projetadas para eliminar.

Nós realmente precisamos colocar 50 camadas de abstração em cima de algo tão simples quanto uma consulta MySQL? Por que não usar algo como a interface PDO do PHP, onde as instruções preparadas / testes de entrada são manipulados, mas a consulta SQL universalmente compreensível ainda faz parte da função?

Essas abstrações são realmente úteis? O inchaço dos recursos não os torna inúteis, tornando os aplicativos mais difíceis em comparação aos aplicativos similares criados sem o uso de uma estrutura?

user1427661
fonte
22
Palavras-chave: as a relatively inexperienced programmer- quanto mais você criar um software, mais gostará de gastar menos tempo reinventando a roda e mais tempo em casa fazendo as coisas que mais gosta.
sergserg
13
Do we really need to put like 50 layers of abstraction on top of something as simple as a MySQL query?- Primeiro, uma boa estrutura é uma camada de abstração (talvez 2 ou 3 internamente) e, em segundo lugar, "algo tão simples quanto uma consulta MySQL" na verdade envolve uma boa dúzia de abstrações. Mesmo depois que a consulta que você executa a partir de sua linguagem interpretada chegou ao servidor de banco de dados, você ainda tem consultas em bancos de dados em mecanismos em sistemas de arquivos em armazenamento físico. Então, resumindo: sim, precisamos de abstrações, porque elas impedem nossa cabeça de explodir.
back2dos
7
FWIW, sim, às vezes ultrapassamos o encanamento. O número de vezes que eu uso uma estrutura para concluir o trabalho é menor do que eu pensaria originalmente; às vezes, escrever seu próprio código resulta em um design mais simples, um ajuste mais próximo ao domínio do problema e melhor desempenho, sem as dores de cabeça do licenciamento.
Robert Harvey
2
Existem várias micro-estruturas por aí. Essas são estruturas leves que algumas pessoas acham mais atraentes. Por exemplo: flask.pocoo.org . Eu nunca usei isso.
Ipaul
Esta pergunta traz de volta memórias dolorosas do WCF da velha escola e do LINQ to SQL. Duas estruturas que passei muito tempo lutando. Uma estrutura que abstrai apenas o suficiente, é simples de entender e fácil de personalizar é realmente um pássaro raro. Mas eles existem.
Phil

Respostas:

21

Estruturas podem ser realmente complicadas. Os problemas podem surgir facilmente quando uma estrutura é "opinativa" demais, ou seja, quando ela realmente prefere um estilo de aplicação específico e todas as partes são voltadas para suportar esse estilo específico.

Por exemplo, se a estrutura abstrai completamente o processo de autenticação de um usuário, permitindo adicionar apenas um componente, adicionar um modelo de login em algum lugar e pronto, você obtém a autenticação do usuário gratuitamente. Isso economizou muito trabalho repetitivo ao se preocupar com cookies, armazenamento de sessão, hash de senha e outros enfeites.

Os problemas começam quando você percebe que o comportamento padrão do código de autenticação da estrutura não é o que você precisa. Talvez não esteja seguindo as melhores práticas de segurança mais recentes. Talvez você precise de um gancho personalizado no processo para acionar alguma ação, mas a estrutura não oferece um. Talvez você precise alterar os detalhes do cookie que está sendo definido, mas a estrutura não oferece nenhuma maneira de personalizar isso.

A abstração oferecida pela estrutura permitiu adicionar um recurso importante ao seu site dentro de minutos, em vez de dias inicialmente, mas no final, talvez você precise lutar contra a estrutura para fazer o que você precisa, ou você você precisa reinventar a funcionalidade do zero novamente para atender às suas necessidades.

Isso não quer dizer que as abstrações da estrutura sejam ruins, veja bem. É para dizer que essa é sempre uma possibilidade que você precisa ter em mente. Algumas estruturas são explicitamente voltadas para isso, elas oferecem uma maneira de obter algo rapidamente, como um protótipo ou mesmo uma estrutura de produção para um tipo de aplicativo muito específico e limitado. Outras estruturas são mais como coleções soltas de componentes que você pode usar, mas que ainda permitem muita flexibilidade para alterá-lo posteriormente.

Ao usar uma abstração, você sempre deve entender pelo menos aproximadamente o que ela está abstraindo. Se você não entende os cookies e os sistemas de autenticação, iniciar uma abstração não é uma boa ideia. Se você entende o que está tentando fazer e precisa apenas de um código que já o faz, em vez de ter que escrever seu próprio tédio, as abstrações economizam muito tempo. Abstrações mal escritas podem causar problemas mais tarde, por isso é uma faca de dois gumes.


Você também deve distinguir entre abstrações técnicas e abstrações de "regra de negócios" . Programar em uma linguagem de nível superior é uma abstração que você provavelmente não quer perder (Python, PHP, C # vs. C vs. Assembler; Menos vs. CSS), enquanto "abstrações de regras de negócios" pode ser difícil se não o fizerem. atenda exatamente às suas necessidades (autenticação com um clique x cookies de codificação manual).

Isso ocorre porque as abstrações técnicas raramente "vazam", ou seja, você dificilmente precisará depurar o código da máquina ao escrever aplicativos no Python. As abstrações de regras de negócios funcionam no mesmo nível técnico e, na verdade, são apenas "pacotes de códigos". Você provavelmente vai precisar depurar o cookie que está definido ou o hash de senha que é criado em algum momento, o que significa que você será mergulho através de lotes de código do 3o partido.

deceze
fonte
“Se você não entende os cookies e os sistemas de autenticação, iniciar uma abstração não é uma boa ideia.” Sim, mas provavelmente ainda é melhor do que construí-lo do zero.
svick
@svick Mais rápido? Sim. Melhor? Isso é discutível.
lunchmeat317
@ lunchmeat317 O que quero dizer é que, se alguém não sabe o que está fazendo e usa uma estrutura, é provável que cometa algum erro. Mas se ele escreve todo o código sozinho, é quase certo que cometerá um erro.
svick
2
aceita. "Você usa bibliotecas, mas os frameworks usam você" é uma boa citação. Precisamos de mais bibliotecas reutilizáveis ​​e muito menos estruturas all-in-one.
Gbjbaanb
11
@gbjbaanb Muito de acordo. Especialmente porque as estruturas de tudo e a pia da cozinha raramente têm a mais alta qualidade de código. As melhores bibliotecas da categoria geralmente são muito melhores que a implementação da estrutura genérica.
Deceze 22/03
29

Parece-me que você não entende abstrações e reutiliza códigos.

Toda a indústria de desenvolvimento de software é construída sobre abstrações. Só porque não usá-los, ou seja, evitar o uso de estruturas, bibliotecas e códigos gerais que não são escritos internamente, aumentaria o custo necessário para produzir um pedaço de software em cem mil, provavelmente até mais.

Como você não cria um jumbo a partir do zero, sem usar nenhum conhecimento de engenharia desenvolvido durante anos ao construir outras aeronaves, você não escreve software comercial a partir do zero.

Você entende isso usando PHP ou Ruby em primeiro lugar, você já tem uma quantidade enorme de abstrações, não é? Os mais óbvios:

  1. O sistema operacional, a linguagem de programação e o compilador fornecem uma grande abstração sobre o Assembler e o hardware,

  2. O servidor da web fornece uma abstração de soquetes, failover, protocolo HTTP, etc.,

  3. O SQL fornece uma abstração sobre como os dados são armazenados em um suporte de armazenamento permanente e mantidos na memória para acesso mais rápido, asseguram ACID, espelhamento etc.

Você sempre pode tentar criar um aplicativo Web sem usar nem um sistema operacional, nem um servidor Web, um banco de dados ou uma linguagem de programação de alto nível. Você descobrirá rapidamente que passou anos reinventando a roda, ou seja, recriando sua linguagem de programação, seu servidor da Web e seu banco de dados, uma vez que a qualidade deles estaria longe da qualidade dos produtos que realmente usamos.

Estruturas não são diferentes disso. Você pode fazer o que eles fazem. Só que você desperdiçará seu tempo refazendo a mesma funcionalidade, com a diferença de que essas estruturas o farão melhor e, muitas vezes, seu código será testado e documentado melhor que o seu.

Veja o exemplo de um carrinho para um site de comércio eletrônico. Você pode inventar o seu próprio e passar algumas semanas desenvolvendo-o, ou pode usar o que foi desenvolvido por anos por várias pessoas dentro de uma estrutura. Espera-se que eles sejam testados, sem contar o fato de que, durante alguns anos, esses desenvolvedores descobriram e corrigiram vários bugs que você não imagina ao desenvolver seu próprio carrinho.

Você pode responder que o deles é mais complicado porque possui mais casos de usuários. Por exemplo, os deles devem lidar com descontos, enquanto você não possui descontos em seu site e não precisa desse recurso no carrinho. Bem, você não é forçado a usar esse recurso, e não é como se ele penalizasse o desempenho do seu aplicativo Web.

Você pode ter um cenário muito básico quando é realmente mais fácil desenvolver seu próprio carrinho em vez de usar o existente. Da mesma forma, se a única coisa que seu aplicativo precisa é armazenar uma lista de números, nada mais, você não precisa de um banco de dados: um simples preenchimento de texto seria suficiente. Nesses casos, não exagere na engenharia do seu aplicativo: cenários simples exigem soluções simples.

Outro fator é a legibilidade do seu código. Imagine que você criou um site de comércio eletrônico. Mais tarde, você saiu do projeto e outro desenvolvedor deve mantê-lo.

  • Se você tivesse usado um carrinho fornecido por uma estrutura, seu colega ficaria aliviado: ele teria que manter um pequeno pedaço de código que se baseia em uma estrutura confiável e fortemente documentada. Ainda melhor: esse desenvolvedor pode ter sido usado para trabalhar com essa estrutura e é familiar a ela. Caso contrário, ele pode fazer perguntas sobre o Stack Overflow: com certeza, alguém já usou o framework.

  • Se você tivesse seu próprio carrinho, seu colega teria que manter algum código personalizado, talvez nem mesmo documentado, sem conseguir obter ajuda em qualquer lugar.

Ao usar uma estrutura, você conta com um código que é:

  • Escrito por desenvolvedores experientes,

  • Frequentemente revisados ​​por pares,

  • Testado em unidade,

  • Documentado extensivamente,

  • Usado por anos por milhares de desenvolvedores,

  • Muitas vezes, há suporte para que você possa relatar um bug e vê-lo realmente corrigido,

  • Conhecido por muitos desenvolvedores que conhecem as possíveis advertências e problemas e podem ajudar em sites como o Stack Overflow.

  • Disponível para você agora, de graça.

Arseni Mourzenko
fonte
3
Desculpe, mas isso não responde à pergunta. Do jeito que eu interpretei, essa pergunta é sobre quando há muita abstração e os problemas que isso causa, não se a abstração e as estruturas podem ser úteis. O OP parece já entender que eles podem ser úteis. No entanto, abstrações ruins podem ser tão dolorosas e limitantes quanto boas abstrações podem ser úteis e libertadoras.
3
@ MattFenwick - para mim, o OP está dizendo que, se você usar essas estruturas, a abstração foi longe demais e causa mais problemas do que valem a pena. Certamente a questão não é: más abstrações são ruins?
JeffO 16/03
3

Eu concordo - a maioria das estruturas se tornam ditadores inchados. Eles prometem liberdade, mas você acaba em servidão. observe uma estrutura como uma ferramenta - a melhor ferramenta é a que fica fora do seu caminho. Se em PHP eu sugiro verificar a estrutura do Codeigniter, porque é um equilíbrio elegante entre convenções e liberdade e tem uma grande comunidade. E para o pôster que usou o exemplo de um carrinho de comércio eletrônico - eu gostaria de poder concordar com você. mas, tendo analisado o código para muitas soluções de comércio eletrônico - e projetado algumas - eu discordo respeitosamente do seu exemplo.

cartalote
fonte
2

Hmmm Um aspecto do LedgerSMB em que trabalhamos muito foi a nossa abordagem ao framework. Existem dois problemas fundamentais que acompanham esse tipo de abstração. Esses são:

  1. Explosão de dependência e

  2. Abstração errada

O primeiro é realmente melhor do que a alternativa que está reinventando a roda. O segundo é um pouco difícil de rotular porque pode vir de um caso de problema mal definido ou, mais frequentemente, de pessoas que usam algo fora do uso pretendido.

Vejamos ORMs, por exemplo. Evito o uso de ORMs, porque geralmente o db acaba sendo projetado para o modelo de objeto do aplicativo, porque na melhor das hipóteses são camadas de abstração com vazamento. Este não é necessariamente o caso. Encontrei desenvolvedores que conseguem preservar o bom design do banco de dados e o bom aplicativo enquanto usam ORMs, mas recorrem a muitas coisas que o hype da orm diz que não devem ser necessárias, como encapsular a API relacional do banco de dados por trás de visualizações atualizáveis.

Um grande problema, é claro, é que, quanto mais automatizado o código, principalmente quando ele também é opaco, mais difícil é ver o que está acontecendo de errado. Este é um ponto sobre os ORMs que @jhewlett destaca acima (consulte /software//a/190807/63722 ).

Um bom paralelo pode ser aviônicos avançados como uma estrutura para pilotar uma aeronave. Eles foram altamente projetados para garantir a confiabilidade e são um fator no aumento da segurança de vôo. No entanto, como muitos artigos no IEEE Spectrum apontam, isso tem um custo de recuperação devido a erros fora dos limites do que é considerado aceitável da perspectiva da automação. O mesmo vale para a depuração. Uma coisa é depurar o código SQL no seu programa. É uma coisa muito diferente depurar uma parte do seu programa que escreve o código SQL para o seu programa usar.

Escrevemos a estrutura do LedgerSMB do zero, porque no momento em que começamos, não havia realmente boas estruturas que faziam o que queríamos. Na verdade, é uma coisa que me deixa muito feliz e, de acordo com um desenvolvedor mais novo do projeto, torna a personalização do aplicativo bastante direta. (Na verdade, mantemos a geração de código SQL no mínimo e, em vez disso, focamos nas funções definidas pelo usuário, escritas à mão, o que significa que as partes da escrita do sql são cola muito fina). Sim, ele fornece muita abstração em alguns lugares, mais do que alguns programadores estão acostumados (em particular, "mapear propriedades do objeto para argumentos nesse procedimento armazenado" nos dá uma resposta de tempos em tempos). Tentamos, no entanto, manter tudo simples e consistente, para que seja direto determinar o que deu errado. Isso funciona muito bem.

No final, "demais" é um pouco subjetivo, mas em um nível objetivo, também depende do que você está fazendo. Se você estiver fazendo exatamente o que a estrutura foi projetada para fazer, uma estrutura bem projetada fornecerá uma quantidade perfeita de abstração. Se você estiver fazendo algo que seja um pouco menos adequado, a abstração se tornará muito e com vazamento.

Chris Travers
fonte
2

Sim, eles são úteis. Eles fornecem o benefício de muitos outros desenvolvedores experientes trabalhando para resolver um problema que você precisa resolver, com os benefícios adicionais de testá-lo, corrigindo muitos bugs e fornecendo soluções para problemas complicados com os quais você não precisa se preocupar. você mesmo usando a estrutura.

Eles podem ser um exagero? Certo. Tudo isso depende do que você precisa e do que a estrutura traz para a mesa. Se você tem um aplicativo Web simples, talvez o Rails seja um exagero para você, e você deve considerar algo mais simples como o Sinatra como uma solução.

Definitivamente, existe uma curva de aprendizado em todas as estruturas e é mais acentuada com mais trabalho que economiza para você. No entanto, aprender a estrutura significa que você economizou tempo e pode aproveitar todo esse conhecimento no próximo projeto, em vez de reescrever seu aplicativo do zero, pela segunda vez.

Mas, você diz, copiarei meu código do projeto antigo e posso usá-lo como ponto de partida para o meu novo projeto! Vou mudar o que é diferente, e talvez tornar alguns dos meus objetos / funções mais gerais, e pensar em uma maneira melhor de resolver esse trecho complicado de código! Parabéns, você acabou de criar uma estrutura. Faça isso mais algumas milhares de vezes e você terá algo como Django, Rails ou Zend.

mestre da caça
fonte
1

As estruturas geralmente resultam em mais produtividade (talvez após uma ligeira curva de aprendizado), mas geralmente há uma troca envolvida. Em alguns casos, por exemplo, você obtém produtividade do programador ao custo de desempenho reduzido.

Considere os mapeadores objeto-relacionais (ORMs). Eles são ótimos, pois cuidam de muitos códigos de mapeamento tediosos para você. Eles podem até criar seus objetos para você. No entanto, ao abstrair o SQL, é muito mais difícil argumentar sobre desempenho e otimizar seus gargalos.

Se você estiver criando um aplicativo que não terá muitos dados ou consultas complexas, o desempenho pode não ser um problema para você. De fato, o tempo do programador é o gargalo de muitos projetos, e estruturas, bibliotecas e linguagens de alto nível ajudam a aliviar isso.

jhewlett
fonte
1

Concordo que "Você usa bibliotecas, mas estruturas usam você". Essa é uma maneira muito elegante de colocar isso. Não concordo que, assim que você começar a reutilizar o código, comece a criar uma estrutura, pois geralmente não precisará fazer muito mais do que copiar e colar rapidamente para usar seu código novamente - isso é uma biblioteca que você está construindo; não é necessário ficar estranho sobre como você introduz o código em seu site ou aplicativo.

Para mim, o ponto crucial é que tenho que tirar mais proveito de um recurso do que exige que eu invista. Ou, de outro ângulo, eu diria que, assim que as necessidades de uma estrutura forem maiores que as recompensas disponíveis, todas as vantagens estarão ausentes. Então é 'Sim! Por favor! E obrigada! a todos que criarem ativos que cairão direto e funcionarão conforme necessário dentro do meu próprio html / CSS / PHP e SQL.

Uma coisa que considero incompreensível é que se diz que as estruturas facilitam a manutenção? Se a malha complexa de peças inter-funcionais não estiver funcionando como o esperado, é melhor saber tudo o que há para saber sobre a estrutura em questão. Ou esteja pronto para uma enorme entrada de nova sintaxe.

user2583049
fonte
0

Algumas pessoas dizem que este é o Princípio de Hollywood de estruturas: "Não ligue para nós, nós ligaremos para você". Por outro lado, sempre que você usa uma biblioteca, seu código chama a biblioteca , e não o contrário.

Como você pode ver, o ponto importante é quem está no controle - ou seja, no controle do fluxo de controle. Quem decide qual declaração é executada depois de qual?

Existem argumentos a favor e contra, e sempre que vejo discussões intermináveis, costumo pensar que isso deve ser uma questão de gosto, e não uma pergunta objetivamente decidível. Caso contrário, já teria sido decidido.

Na minha opinião, se você prefere usar estruturas ou bibliotecas diz algo sobre que tipo de desenvolvedor você é, e não se uma das duas abordagens é superior e, eventualmente, prevalecerá.

Se você prefere estruturas, prefere trocar liberdade por segurança: você provavelmente é mais pragmático e tende a confiar que outras pessoas farão seu trabalho corretamente. Se você prefere bibliotecas, prefere trocar segurança por liberdade: você provavelmente é mais idealista e questiona as idéias e reivindicações de outros.

Eu não acho que seria sensato decidir que é melhor ser como o primeiro ou o segundo.

Respondendo à sua pergunta: As estruturas colocam muita abstração? Depende de quem você é e, especificamente, a que distância dos primeiros princípios você se sente confortável.

...

E ainda mais especificamente, se você não gosta de estruturas como o Django, procure "microframeworks" como o Flask :)

logc
fonte