Arquitetura Limpa
O que são Design e Arquitetura?
- Software é feito de software. Grandes construções de software são compostas de componentes de software menores e assim por diante.
- "Arquitetura representa as decisões significativas de design que moldam um sistema, onde a significância é medida pelo custo da mudança" - Grady Booch
- Uma arquitetura boa de software é construída no caminho, é algo dinâmico e não estático.
- Regras de arquitetura de software são independentes de todas as outras variáveis. Porque os blocos de códigos (sequência, seleção, interação e indireção) não mudaram muito com o decorrer do tempo e portanto a forma de organizá-los (arquitetura) também não.
- O objetivo da arquitetura de software é minimizar os recursos humanos necessários para construir e manter um determinado sistema. Boas arquiteturas minimizam o custo de manutenção e dão flexibilidade ao software. Afinal, o software foi inventado para tornar "suave" a mudança de comportamento das máquinas.
- A maior mentira em que os desenvolvedores acreditam é a noção de que escrever um código bagunçado permite fazer tudo mais rápido a curto prazo e só diminui o ritmo a longo prazo. A única maneira de seguir rápido é seguir bem.
Paradigmas da Programação
Paradigmas são maneiras de programar, relativamente não relacionadas às linguagens. Eles nos dizem o que não fazer, mais do que nos dizem o que fazer.
- Programação Estruturada
Impõe disciplina sobre a transferência direta do controle. (Execução e leitura sequencial do código sem "goto")
- Programação Orientada a Objetos
Impõe disciplina sobre a transferência indireta do controle. Encapsulamento, herança e polimorfismo. Com a OO temos a habilidade de obter controle absoluto, por meio do polimorfismo, sobre cada dependência do código fonte do sistema.
- Programação Funcional
Impõe disciplina sobre a atribuição. Já que a imutabilidade é forte nesse paradigma.
Princípios de Design
- SRP: O Princípio da Responsabilidade Única
Um módulo deve ser responsável por um, e apenas um, usuário ou stakeholder
- OCP: O Princípio Aberto/Fechado
Um artefato de software deve ser aberto para extensão mas fechado para modificação.
- LSP: O Princípio de Substituição de Liskov
O princípio define que os objetos de uma superclasse devem ser substituídos por objetos de suas subclasses sem quebrar a aplicação. Classes filhas nunca deveriam infringir as definições de tipo da classe pai.
- ISP: O Princípio da Segregação de Interface
Não dependa de algo que contém itens desnecessários, por isso pode causar problemas inesperados.
- DIP: O Princípio da Inversão de Dependência
Os sistemas mais flexíveis são aqueles em que as dependências de código-fonte se referem apenas a abstrações e não a itens concretos.
Princípios dos Componentes
- Componentes
São unidades de implantação que podem ser dinamicamente ligadas em tempo de execução.
- Coesão de Componentes
REP: Princípio da Equivalência do Reúso/Release. A granularidade do reúso é a granularidade do release. Com muitos pacotes teremos que efetuar releases granulados.
CCP: Princípio do Fechamento Comum. Reúna em componentes as classes que mudam pelas mesmas razões e nos mesmos momentos.
CRP: Princípio do Reúso Comum. Não force os usuários de um componente a dependerem de coisas que eles não precisam.
- Acoplamento de Componentes
Não permita ciclos no grafo de dependência dos componentes.
Arquitetura
- O que é?
Arquitetura de um sistema de software é a forma dada a esse sistema pelos seus criadores. O propósito dessa forma é facilitar o desenvolvimento, implantação, operação e manutenção do sistema de software contido nela.
Bons arquitetos projetam o software para maximizar o número de decisões não feitas.
- Independência
Uma boa arquitetura faz com que o sistema seja fácil de mudar, de todas as formas necessárias, ao deixar as opções abertas e independentes. Desacoplar os casos de uso (regras de negócio) da aplicação é muito importante para uma boa arquitetura.
- Fronteiras: Estabelecendo Limites
Para estabelecer limites em uma arquitetura de software, primeiro particione o sistema em componentes. Alguns desses componentes são regras centrais de negócio; outros são plug-ins que contêm funções necessárias, mas sem relação direta com o negócio central. Em seguida, organize o código desses componentes para que as flechas entre eles apontem em uma única direção - na direção do negócio central.
- Anatomia do Limite
O cruzamento de limites não é nada mais do que uma função de um lado do limite chamando uma função do outro lado e transmitindo alguns dados. Temos que lidar com as dependências nesse cruzamento.
- Política e Nível
A arte da arquitetura geralmente envolve a organização dos componentes agrupados em um grafo acíclico direcionado. A direção das dependências é baseada no nível dos componentes aos quais se conectam. Os componentes de nível mais baixo são projetados para que dependem dos componentes de nível mais alto. Quanto mais longe da entrada do seu sistema maior o nível da política.
- Regras de Negócio
Regras de negócio São regras ou procedimentos que geram ou economizam o dinheiro da empresa. Podem ou não ser implementados por meio de software.
Entidade é um objeto contido em nosso sistema de computador. Ela incorpora um pequeno conjunto de regras cruciais de negócios que operam com base nos Dados Cruciais de Negócios.
Casos de usos é uma descrição da maneira como um sistema automatizado é usado. Ele especifica a entrada a ser fornecida pelo usuário, a saída a ser retornada e os passos de processamento envolvidos no processo. Os casos de uso controlam a dança das entidades.
- Arquitetura Gritante
A arquitetura deve deixar claro o que o seu software faz.
- Arquitetura Limpa
Ao separar o software em camadas e obedecer a Regra da Dependência, você criará um sistema intrinsecamente testável, com todos os benefícios inerentes. Quando uma das partes externas do sistema se tornar obsoleta, como a base de dados ou o framework web, você poderá substituir o elemento obsoleto com um esforço mínimo.
- Apresentadores e Objetos Humble
O padrão de Objeto Humble serve para separar os comportamentos difíceis de testar dos comportamentos fáceis de testar. Apresentadores são objetos testáveis que trabalham os dados para serem visualizados (GUI).
- Limites Parciais
Às vezes o custo dos limites é alto e não compensa porque talvés esse limite não seja necessário (YAGNI: You Aren't Going to Need It). Portanto, você pode fazer um limite parcial.
- Camadas e Limites
Como arquiteto você precisa prever o futuro do software. Avaliar quais camadas e limites serão necessários.
- O componente Main
O componente Main é o detalhe final - a política de nível mais baixo. É o ponto de entrada inicial do sistema. Pense em Main como um plugin de aplicação que faz configurações iniciais, reúne todos os recursos externos e, então, entrega o controle para a política de alto nível da aplicação.
- Serviços: Grandes e Pequenos
Por mais úteis que os serviços sejam para a escalabilidade e desenvolvimento de um sistema, eles não são, em si mesmos, elementos arquiteturalmente significativos. A arquitetura de um sistema é definida pelos limites especificados dentro desse sistema e pelas dependências que cruzam esses limites. A arquitetura não é definida pelos mecanismos físicos pelos quais os elementos se comunicam e são executados. Um serviço pode ser um componente único, completamente cercado por um limite arquitetural. Por outro lado, um serviço pode ser composto de vários componentes separados por limites arquitetônicos. Em casos raros, os clientes e serviços são tão acoplados que não têm nenhuma significância arquitetural.
- O Limite Teste
Os testes não estão fora do sistema. Na verdade, são partes do sistema que devem ser bem projetadas para que viabilizem os benefícios desejados de estabilidade e regressão. Os testes que não são projetados como parte do sistema tendem a ser frágeis e difíceis de manter. Esses testes geralmente acabam sendo eliminados na manutenção - descartados por serem difíceis demais de manter.
- Arquitetura Limpa Embarcada
Deixar que todo o código se torne firmware não é bom para a saúde do seu produto a longo prazo. Ser capaz de testar apenas no hardware-alvo não é bom para a saúde do seu produto a longo prazo. Uma arquitetura limpa embarcada é boa para a saúde do seu produto a longo prazo.
Detalhes
- Base de Dados é um Detalhe
A estrutura de dados organizacional, ou modelo de dados, é arquiteturalmente significante. As tecnologias e sistemas que movem os dados para dentro e para fora de uma superfície magnética giratória não são. Sistemas de banco de dados relacionais que forçam os dados a serem organizados em tabelas e acessados com SQL têm muito mais a ver com tabelas do que com SQL. Os dados são significativos. A base de dados é um detalhe.
- A Web é um Detalhe
Os dados de entrada completos e os dados de saída resultantes podem ser colocados em estruturas de dados e usados como valores de entrada e valores de saída no processo que executa o caso de uso. Nessa abordagem, podemos considerar que cada caso de uso opera o dispositivo de entrada e saída da UI de forma independente do dispositivo.
- Frameworks são Detalhes
Quando confrontado com um framework, tente não casar com ele tão rápido. Veja se não há maneiras de namorar com ele por um tempo antes de mergulhar de cabeça. Mantenha o framework atrás de um limite arquitetural se possível, pelo máximo de tempo possível. Talvez você possa encontrar uma maneira de conseguir o leite sem comprar a vaca.