
As modernas tecnologias da informação surpreendem com seu poder, são oprimidas pelas oportunidades que se abrem, são desencorajadas pela perfeição técnica inerente a elas, mas há um ponto ridículo sobre o qual a TI quebra os dentes de novo e de novo. Mostre os dados do usuário no banco de dados, obtenha informações dele, coloque-os novamente no banco de dados, mostre o resultado. Campos de entrada, botões, marcas de seleção, inscrições - parece que eles podem ser tão proibitivamente difíceis de exigir construções intrigantes, como estruturas em cima de mecanismos de modelo em cima de estruturas em cima de transpilers? E por que, apesar de todos os tremendos esforços, temos o fato de que os exemplos de brinquedos no tutorial são feitos de maneira fácil e agradável, mas assim que o kit de ferramentas encontra as tarefas reais da vida real ... como dizer mais suave ... com a crescente complexidade das tarefas a serem resolvidas, há uma forte não linearidade de aumento dificuldades de implementação. Bem, seria uma questão de algo realmente intrigante no nível da física teórica ou da tecnologia espacial, porque não existe mesmo - botões e marcas de verificação. Por que esse absurdo continua envenenando a vida dos cidadãos e trabalhando coletivos por décadas?
As razões, provavelmente, como sempre, são muitas. Provavelmente, todos eles são dignos de consideração de uma maneira ou de outra, mas aqui e agora falaremos sobre a tarefa Mapeamento Objeto-Relacional (ORM), que sempre está por trás de alguns desses "botões e marcas de verificação" de alguma forma.
O que sabemos sobre ORM
- Armazenar dados em tabelas relacionais não significa dizer que é uma questão muito simples, mas, em geral, a idéia e os modos de sua aplicação são bastante claros e bem pesquisados.
- Com a programação de objetos, nem tudo é tão bom (existem várias abordagens concorrentes), mas, em geral, com a implementação e aplicação de tecnologias, tudo também é mais ou menos claro.
- Tanto isso quanto outro - sobre os dados, seu armazenamento e processamento. Isso é, de fato, a mesma coisa.
- Parece-nos lógico que deve haver uma ponte simples, compreensível, conveniente, previsível e universal entre os dois mundos.
- E sempre que encontramos essa ponte com facilidade, mas o infortúnio, sua simplicidade, compreensibilidade, conveniência, previsibilidade e universalidade não funcionam além de exemplos simples de tutoriais.
- Todo mundo sofre: os desenvolvedores, que precisam fazer um trabalho extremamente chato, e os usuários, que precisam lutar com software desajeitado e com os negócios, cuja realização de repente se torna insuportavelmente longa e cara, e a indústria como um todo.
- Eu já vi muitos ORMs diferentes, mas não vi nenhum bom. Isto é, que, além de exemplos simples, não se transforma em um fardo e num leito procrustino.
Por que tudo é tão bizarro
A base ideológica da teoria e prática dos bancos de dados relacionais é o cálculo predicado, ou seja, um ramo da matemática. Quanto à POO, falta uma base ideológica semelhante. Pode-se tentar formular a idéia básica de OOP assim: como o mundo consiste em objetos, seria conveniente modelá-lo neste mundo criando objetos dentro de um sistema de software. Nesse sentido, dois erros ao mesmo tempo. Em primeiro lugar, o próprio mundo não consiste e nunca consistiu em objetos. Em segundo lugar, desculpe, mas por que o programa precisa simular o mundo? Ou seja, temos uma afirmação conceitualmente incorreta, perfeitamente complementada por uma afirmação sem sentido do problema.
Todo ORM é uma tentativa de esticar claramente a correspondência unificada entre, de fato, o ramo da matemática e um conjunto amplo de práticas diversas, com base em considerações de conveniência, abordagens estabelecidas historicamente e também frequentemente em lendas, opiniões de autoridades e simplesmente conceitos errôneos. In vitro, pode ser feito funcionar, mas in vivo está fadado a parecer patético e trazer mais tristeza do que alegria.
Sobre a inevitabilidade da orientação a objetos
No entanto, a necessidade da orientação a objetos do nosso software é nossa realidade inevitável. Essa inevitabilidade é baseada principalmente no fato de que operar com objetos é a essência e o fundamento de qualquer uma de nossas atividades. O mundo em si não consiste em objetos, mas para entender algo neste mundo e fazer algo com este mundo, nós mesmos declaramos suas partes como objetos, os chamamos de nomes, tentamos entender seu comportamento, aplicamos a eles. esforços para obter os resultados desejados. Esta é a nossa maneira de funcionar, e é impossível deixá-la, e não é necessária. Tudo é um objeto, não porque realmente é, mas porque não podemos fazer o contrário. Aquilo que de maneira alguma pode ser um objeto está completamente fora dos limites de nossa capacidade de compreender e não pode servir como sujeito de nossos esforços.
Mesmo que o programa seja escrito sem o uso de técnicas de POO, inevitavelmente contém objetos (no sentido amplo da palavra), manipulando o que o desenvolvedor resolve seu problema - variáveis, tipos de dados, operadores, algoritmos, construções sintáticas, funções, módulos. Do ponto de vista do usuário, o programa também possui um conjunto de objetos com os quais interage - botões, rótulos, campos de entrada, páginas, sites e todo o sistema.
O que armazenamos em nossos bancos de dados
Como mencionado acima, os bancos de dados relacionais são baseados no cálculo de predicado. Um predicado é um fato formulado e, no nosso caso, armazenado em um meio. Apenas no caso, observo que o banco de dados relacional não é apenas e não muito sobre relacionamentos entre tabelas por chaves estrangeiras. Na terminologia adequada, as relações são o que chamamos simplesmente de tabelas. Ou seja, mesmo que seu banco de dados tenha apenas uma tabela com duas colunas (por exemplo, nome e número de telefone), você já possui um banco de dados relacional que estabelece o relacionamento entre dois conjuntos, nesse caso, conjuntos de nomes e números de telefone.
Um banco de dados relacional não armazena objetos, mas fatos. Os fatos armazenados, é claro, têm um objeto ("sobre o que é esse fato?"). E quando tentamos ensinar o sistema a responder a essa pergunta, temos entidades, ou seja, objetos aos quais os fatos estão associados. Se você trabalha corretamente, a estrutura de nossa base nasce de uma série de respostas à pergunta "que tipo de fatos pretendemos manter?". E somente no próximo estágio obtemos algo que se assemelha a objetos que dão fatos à objetividade. Você pode, é claro, projetar “a partir de objetos”, mas eu não recomendaria fazê-lo, exceto no trabalho de laboratório em assuntos não diretamente relacionados ao design do banco de dados. O perigo de erros de cálculo arquiteturais pesados é muito grande. Além disso, é pelo menos inconveniente.
Uma pequena digressão sobre bancos de dados de objetos. Um pensamento muito simples: se estamos cansados de problemas com o ORM, talvez devêssemos fazer algo com a parte que é "R"? Que nosso banco de dados não seja um monstro relacional difícil e exigente, mas algo que seja uma juventude elegante, especialmente adaptada para o armazenamento de objetos. Algum tipo de base esquemática do NoSQL, por exemplo. Mas no final, de repente, acontece que os ORMs semelhantes a NoSQL são ainda mais estranhos e artificiais do que os bons e antigos SQL. De qualquer forma, podemos ter e com prazer operar um DBMS sem circuito, mas não existem dados sem circuito na natureza. Não há nada mais indefeso, irresponsável e imoral que o ORM para bancos de dados sem circuito.
Good ORM
Um bom ORM é o ORM ausente. Bem, sério. Olhe para qualquer um dos seus sistemas ORM e tente honestamente responder à sua pergunta: quais são os benefícios desse monstro? Qual o motivo do seu uso, exceto promessas não cumpridas de felicidade e desacreditadas repetidamente preconceituosas? Certamente, existem algumas coisas úteis úteis, mas quais são elas no contexto das deformações arquitetônicas introduzidas e dos problemas de desempenho que surgem constantemente do nada?
Como regra, a API de banco de dados de "baixo nível" é simples, conveniente, completa e consistente. Normalmente, dedos suficientes para listar todos os recursos. Aprendê-los não é uma novidade divina, é uma tarefa.
Vou tentar esboçar um conjunto de princípios de arquitetura que permitem mapear objetos para um banco de dados sem usar o ORM:
- Armazenamos os fatos, operamos em objetos. Lembre-se de que o banco de dados armazena fatos e os modelos de objetos envolvidos no processamento de dados são projeções de conjuntos de fatos sob diferentes pontos de vista. Por exemplo, para o exemplo dado com nomes e números de telefone, podemos ter a classe Abonent, para a qual vários números podem ser armazenados, e também a classe PhoneNumber, para a qual vários assinantes podem ser configurados (não se esqueça que, além dos números móveis pessoais, temos onde ainda existem telefones de apartamentos e escritórios). E a tabela no banco de dados é apenas uma que define a relação muitos-para-muitos entre muitos nomes e números de telefone. Apenas duas projeções diferentes. Essa abordagem, a propósito, normalmente é dimensionada para casos muito mais complexos, permitindo que você tenha classes úteis no sistema como, por exemplo, "vendas médias por um determinado período, de acordo com uma combinação de critérios".
- Os fatos são projetados em objetos e vice-versa por meio de uma API orientada a problemas. Sem aplicar uma solução que afirma ser universal. Se você ainda não sabe como compor APIs convenientes, saiba como. E importante, ensine-se a documentá-los imediatamente.
- Encomende acima de tudo. Se você usar a versão clássica de um DBMS com um esquema de dados rígido, esse esquema em si trará ordem ao trabalho com dados. A estrutura extra codificada pela estrutura dos objetos é simplesmente redundante. Se você usar um DBMS sem esquemas, é claro que terá que fazer alguns esforços para garantir que seu banco de dados não se transforme em uma montanha de lixo devido ao fato de que diferentes desenvolvedores têm idéias diferentes sobre o que é armazenado.
- Independência do DBMS (se necessário). Se a propriedade mais interessante do ORM para você é a independência do DBMS, use ferramentas especiais como ODBC, JDBC, ADO ou, se isso não for possível, faça seu próprio nível de abstração. Não é tão difícil quanto pode parecer à primeira vista. Você não precisa de suporte para absolutamente todos os recursos de absolutamente todos os DBMS para sua tarefa, certo?
- Não se esqueça dos aspectos adicionais do trabalho com dados. Por exemplo, compartilhamento de acesso a dados (que podem ser arbitrariamente complexos), monitoramento, replicação e muito mais. Mas aqui tenho boas notícias para você: porque no seu ORM favorito, o complemento. o aspecto ainda é implementado de acordo com o princípio "você não vai agradar a todos, come o que dá", a rejeição de um serviço duvidoso com o qual você precisa lutar mais do que cooperar acabará sendo uma decisão estrategicamente correta.
Total
ORM é um assunto muito dolorido para a nossa indústria. Em uma época em que a inteligência artificial da nuvem agrega o blockchain quântico, a grande maioria da força de trabalho está ocupada mexendo na lógica de negócios e na interface do usuário com bancos de dados. Milhões de linhas de código terrível, pregadas com microscópios, dor e desespero em todos os lugares acompanham esse processo criativo. Uma das raízes desse triste estado de coisas é o equívoco extremamente persistente de que um ORM universal é, em princípio, possível. Mas é impossível, e há uma razão fundamental para isso, que não pode ser eliminada. A conscientização desse fato é o primeiro passo para sair desse pesadelo. Existe uma saída, existem alternativas, mas primeiro você precisa perceber, sentir e aprender a manter o foco da atenção.
PS Peço sinceras desculpas aos irmãos da profissão que investiram muito tempo e esforço na criação de numerosos melhores universais no mundo da ORM. Eu sinto muito mesmo.