Este post foi editado pela última vez por Summer em 27-09-2017 às 15:32
Este artigo é um conto que imita perguntas e respostas, e o autor usa um estilo humorístico para analisar brevemente o trabalho dos arquitetos: Quero ser arquiteto de software. Essa é uma ótima opção para jovens desenvolvedores de software. Quero liderar a equipe e tomar decisões importantes sobre bancos de dados e frameworks, servidores web, etc. Ah, então você não quer ser arquiteto de software de jeito nenhum. Claro que eu queria ser o tomador de decisões importantes. Tudo bem, mas você não inclui decisões importantes na sua lista, que são decisões irrelevantes. O que você quer dizer? Você está dizendo que bancos de dados não são decisões importantes, sabe quanto gastamos neles? Talvez custe demais. No entanto, bancos de dados não são uma das decisões importantes. Como você pode dizer isso? O banco de dados é o núcleo do sistema, onde todos os dados são sistematizados, classificados, indexados e acessados. Sem um banco de datos, não haveria sistema. O banco de dados é apenas um dispositivo de IO que fornece algumas ferramentas úteis para classificação, consulta e relatórios de informações, mas essas são apenas funções auxiliares da arquitetura do sistema. Ajuda? Isso é um absurdo. Isso mesmo, é auxiliar. As regras de negócio do sistema podem aproveitar algumas dessas ferramentas, mas essas ferramentas não são inerentes às regras de negócios correspondentes. Se necessário, você pode substituir as existentes por ferramentas diferentes; E as regras de negócios não vão mudar. Bem, sim, mas teve que ser recodificado, porque essas ferramentas foram usadas no banco de dados original. Esse é o seu problema. O que você quer dizer? Seu problema é que você acha que as regras de negócio dependem de ferramentas de banco de dados, mas não dependem. Ou pelo menos, não deveria ser assim até que uma boa arquitetura seja fornecida. É simplesmente loucura. Como criar regras de negócio que não usam essas ferramentas? Não estou dizendo que eles não usam ferramentas de banco de dados, mas não dependem disso. Regras de negócio não precisam saber qual banco de dados você está usando. Então, como você consegue regras de negócio sem saber quais ferramentas usar? Inverta as dependências para que o banco de dados dependa de regras de negócio. Garanta que as regras de negócio não dependam do banco de dados. Você está falando besteira. Pelo contrário, estou usando a linguagem da arquitetura de software. Este é o princípio da inversão de dependência: padrões de baixo nível devem depender de padrões de alto nível. Besteira! Critérios de alto nível (assumindo que se referem a regras de negócio) Chamando critérios de baixo nível (assumindo que se referem a bancos de dados). Portanto, o critério de alto nível dependerá do critério de baixo nível de acordo com o princípio de que o chamador depende do chamado. Todo mundo sabe disso! Isso é verdade em tempo de execução. Mas ao compilar, o que queremos é inversão de dependência. O código-fonte das diretrizes de alto nível não deve mencionar o código-fonte das diretrizes de baixo nível. Sem essa! Como você pode fazer uma ligação sem mencionar? Claro, sem problema. É isso que envolve orientação a objetos. Orientação a objetos é sobre criação de modelos no mundo real, combinando dados, funcionalidades e objetos coesos. Trata-se de organizar o código em uma estrutura intuitiva. É o que dizem? Como todos sabemos, essa é a verdade óbvia. Sim, é, porém, ao usar diretrizes orientadas a objetos, é realmente possível invocar sem mencioná-las. Bem, como fazer isso? No design orientado a objetos, os objetos enviam mensagens entre si. Isso mesmo, claro. Quando um remetente envia uma mensagem, ele não sabe o tipo de destinatário. Depende da linguagem usada. Em Java, o emissor conhece pelo menos o tipo base do receptor. No Ruby, o remetente ao menos sabe que o receptor é capaz de lidar com as mensagens recebidas. Está correto. De qualquer forma, porém, o remetente não sabe o tipo específico de receptor. Isso mesmo, bem, é. Portanto, um emissor pode projetar um receptor para executar uma função sem mencionar o tipo específico de receptor. Isso mesmo, isso mesmo. Eu entendo. No entanto, o remetente ainda depende do destinatário. Isso é verdade em tempo de execução. No entanto, é diferente quando compilado. O código-fonte do remetente não menciona nem depende do código-fonte do receptor. Na verdade, o código-fonte do receptor depende do código-fonte do remetente. De maneira nenhuma! O remetente ainda depende da classe que envia. Talvez a partir de algum código-fonte, fique mais claro. O parágrafo a seguir está escrito em Java. Primeiro vem o remetente: remetente do pacote; classe pública Emissor { receptor privado Receiver; Public Sender (Receiver r) { receiver = r; } público void doAlgo () { receiver.receiveThis (); } interface pública Receptor { void receiveThis (); } }Aqui está o receptor: receptor de paquete; importar remetente. Remetente; a classe pública SpecificReceiver implementa Sender.Receiver { public void receiveThis () { //faça algo interessante. } }Nota: O receptor depende do remetente, o SpecificReceiver depende do remetente, e não há informações relacionadas ao receptor no remetente. Sim, mas você está mentindo, você colocou a interface do receptor na classe do emissor. Você está começando a entender. O que você sabe? Claro, é o princípio da arquitetura. O remetente possui a interface que o receptor deve implementar. Se isso significar que eu tenho que usar classes aninhadas, então ...... Classes aninhadas são apenas um dos meios para um fim, existem outras formas. Espera aí. O que isso tem a ver com bancos de dados? Começamos a falar sobre bancos de dados. Vamos dar uma olhada um pouco mais no código. A primeira é uma regra simples de negócios: pacotes de Regras de Negócios; importar entidades Algo; classe pública BusinessRule { gateway privado BusinessRuleGateway; BusinessRule pública (BusinessRuleGateway gateway) { this.gateway = gateway; } empty public void execute (String id) { gateway.startTransaction (); Algo coisa = gateway.getAlgo (id); coisa.fazerMudanças (); gateway.saveAlgo (coisa); gateway.fimTransaction (); } }Regras de negócio não têm muito peso. Este é apenas um exemplo. Podem existir mais classes assim que implementam muitas regras de negócio diferentes. Ok, então o que exatamente é Gateway? Ele fornece todos os métodos de acesso a dados por meio de regras de negócio. Implemente da seguinte forma: pacotes de Regras de Negócios; importar entidades Algo; interface pública BusinessRuleGateway { Something getSomething (String id); void startTransaction (); void saveAlgo (Algo que acontece); void endTransaction (); }Nota: Isso está no businessRules. Ok, o que é a aula de algo? Representa um simples objeto de negócio. Eu coloco em entidades. entidades de empacotamento; classe pública Algo { público void makeChanges () { //... } }Em última análise, a implementação do BusinessRuleGateway, essa classe conhece o banco de dados real: banco de dados de pacotes; importar regrasNegóciosRegras Gateway; importar entidades Algo; a classe pública MySqlBusinessRuleGateway implementa BusinessRuleGateway { public Something getSomething (String id) { // use MySQL para obter algo. } empty público iniciarTransactione () { // iniciar transação MySql } empty público saveAlgo (Algo coisa) { // salvar coisa no MySQL } public void endTransaction () { // fim Transação MySQL } }Além disso, observe que as regras de negócio chamam o banco de dados em tempo de execução; No entanto, na época da compilação, o banco de dados envolve e depende de businessRules. Bem, acho que entendi. Você está apenas usando polimorfismo para esconder o fato de que o banco de dados é implementado das regras de negócio. No entanto, ainda é necessária uma interface para fornecer todas as ferramentas de banco de dados às regras de negócio. Não, de jeito nenhum. Não tentamos fornecer ferramentas de banco de dados para regras de negócios. Em vez disso, eles usam regras de negócio para criar interfaces para o que precisam. Implementar essas interfaces permite que você chame as ferramentas certas. Sim, mas se você precisar usar todas as ferramentas para todas as regras de negócio, então basta colocar a ferramenta na interface do gateway. Ah, acho que você ainda não entende. Entender o quê? Isso já está claro. Cada regra de negócio define apenas uma interface para as ferramentas de acesso a dados que precisa. Espera aí, o que você acha? Este é o Princípio de Segregação de Interfaces. Cada classe de regra de negócio utiliza apenas certas facilidades do banco de dados. Portanto, as interfaces fornecidas por cada regra de negócio só podem acessar as instalações correspondentes. No entanto, isso significa que existem muitas interfaces e muitas pequenas classes de implementação que chamam outras classes de banco de dados. Ótimo, você está começando a entender. Mas é muito bagunçado e uma perda de tempo. Por que fazer isso? Isso é organizado e economiza tempo. Vamos, pegue muito código só por codificar. Pelo contrário, decisões irrelevantes podem ser adiadas por decisões arquitetônicas importantes. O que isso significa? Lembro que no começo, você disse que queria ser arquiteto de software, não disse? Você quer tomar todas as decisões que realmente importam. Sim, era o que eu pensava. Você quer tomar decisões sobre bancos de dados, servidores web e frameworks, certo? Sim, você diz que nada disso importa. Apenas conteúdo irrelevante. Está correto. É isso. As decisões importantes tomadas por arquitetos de software são aquelas que permitem que você tome decisões sobre bancos de dados, servidores web e frameworks. Mas você precisa decidir quais primeiro! Não, não funciona. Na verdade, essas informações podem ser decididas mais tarde no ciclo de desenvolvimento, quando a informação é mais abundante. É um desastre se arquitetos identificarem frameworks antecipadamente apenas para descobrir que eles não fornecem o desempenho necessário ou introduzem restrições intoleráveis. Só quando o arquiteto decidir adiar a decisão é que ele tomará uma decisão quando a informação for suficiente; Equipes que não utilizam dispositivos e frameworks de IO lentos e intensivos em recursos podem criar ambientes de teste rápidos e leves a critério dos arquitetos. Apenas seus arquitetos se importam com o que realmente importa e atrasam quem não importa, e uma equipe assim é a sortuda. Besteira, não entendo nada do que você quer dizer. Bem, dê uma boa olhada neste artigo, caso contrário você terá que esperar mais 10 anos para entender.
|