SOLID

O acrônimo SOLID é apresentado no livro Agile Software Development - Principles, Patterns, and Practices do autor Robert C. Martin (Uncle Bob), sendo composto por 5 princípios de projeto para o gerenciamento de dependências.

Os sintomas (design smells) de um projeto ruim são:

  • Rigidez - Rigidity: o projeto é difícil de mudar;
  • Fragilidade - Fragility: o projeto é fácil de quebrar;
  • Imobilidade - Immobility: o projeto é difícil de reusar;
  • Viscosidade - Viscosity: é difícil fazer a coisa certa;
  • Complexidade Desnecessária - Needless Complexity: sobreprojeto, excesso de complexidade adicional;
  • Repetição Desnecessária - Needless Repetition: abuso do mouse, excesso de repetição; e
  • Opacidade - Opacity: expressão desorganizada.

Princípios

Os 5 princípios de projeto são:

  • Princípio da Responsabilidade Única - Single Responsibility Principle (SRP) por Robert C. Martin com base nos trabalhos de Tom DeMarco e Meilir Page-Jones sobre coesão:

    "A class should have only one reason to change"

    Adaptado para o livro: Um elemento de programação deve ter apenas uma razão para mudar - mantenha um equilíbrio entre baixo acoplamento e alta coesão.

    O princípio refere-se as mudanças das funcionalidades por um particular ator da aplicação e não na transformação de uma arquitetura monolítica, principalmente em diversos elementos anêmicos (uso estrutural sem utilizar de sua principal proposta).

    O gerenciamento de dependências utiliza-se das características de organização da tecnologia utilizada, tais como módulos, pacotes, classes, métodos, funções e etc...

    Aplicar o princípio muito cedo na camada de domínio pode resultar em futuros problemas de projeto.

    Um método prático para a aplicação do SRP:

Análise de SRP para __________

O _____  _____ para ele mesmo.
O _____  _____ para ele mesmo.
O _____  _____ para ele mesmo.
...

Veja também Low Coupling e High Cohesion em GRASP.

  • Princípio do Aberto-Fechado - Open-Closed Principle (OCP) por Bertrand Meyer (criador da linguagem de programação Eiffel) em 1988:

    "Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"

    Adaptado para o livro: Os elementos de programação deve ser aberto para a extensão, mas fechado para modificação - minimize as necessidades de fazer mudanças para elementos de programação existentes.

    Open: abstração por polimorfismo / Closed: definição de Interface de Programação de Aplicação - Application Programming Interface (API).

    O gerenciamento de dependências utiliza-se da abstração e polimorfismo para adicionar novas funcionalidades, assim mantendo a definição sem alterações.

    Pode ser aplicado para qualquer elemento de programação.

    Veja também Protected Variations em GRASP.

  • Princípio de Substituição de Liskov - Liskov Substitution Principle (LSP) por Barbara Liskov em 1988:

    "Subtypes must be substitutable for their base types"

    Adaptado para o livro: Os subtipos devem ser substituíveis pelos seus tipos de base.

    Definição do princípio:

    If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T

    Adaptado para o livro:

    Se para cada objeto o1 do tipo S há um objeto o2 do tipo T de forma que, para todos os programas P definidos em termos de T, o comportamento de P é inalterado quando o1 é substituído por o2 então S é um subtipo de T

    Regras sobre o uso do polimorfismo por subtipos de herança são baseados no trabalho Design By Contract (DBC) de Bertrand Meyer,

    com requisitos de assinatura:

    • contravariância: dos argumentos/parâmetros das funções/métodos em um subtipo, sendo o sentido do relacionamento ascendente ao tipo, ou seja, assume um tipo menos específico;
    • covariância: dos tipos de retorno em um subtipo, sendo o sentido do relacionamento descendente ao tipo, ou seja, assume um tipo mais específico; e
    • exceção: não pode ser novas e/ou maior que a definida no tipo.

    e requisitos de comportamento:

    • invariante: qualquer predicado deve ser preservado em um subtipo;
    • pré-condição: uma condição ou predicado não pode ser mais forte em um subtipo, porém pode ser mais fraca - onde o supertipo funcionava, o subtipo deveria também; e
    • pós-condição: uma condição ou predicado não pode ser mais fraca em um subtipo, porém pode ser mais forte - onde o supertipo causou um efeito, então o subtipo deveria também.

    Dois problemas comuns são: primeiro, qualquer modificação no tipo afeta todos os subtipos; e segundo, os subtipos evoluem com proposta diferente do tipo.

    Uma violação do princípio é uma violação latente do OCP.

    O gerenciamento de dependências utiliza-se do polimorfismo para manter correta a árvore de relacionamentos.

    A violação do princípio pode ser corrigida com fatoração e/ou uso do polimorfismo por subtipos de interface, como o relacionamento por composição/agregação e delegação.

    Veja também Delegação, Composição e Agregação em Princípios Básicos e Polymorphism em GRASP.

  • Princípio da Segregação de Interfaces - Interface Segregation Principle (ISP):

    "Clients should not be forced to depend on methods that they do not use"

    Adaptado para o livro: Os clientes não devem serem forçados a dependerem de métodos que não usam.

  • Princípio da Inversão de Dependência - Dependency Inversion Principle (DIP):

    Definição do princípio:

    a. High-level modules should not depend on low-level modules. Both should depend on abstractions.

    b. Abstractions should not depend on details. Details should depend on abstractions.

    Adaptado para o livro:

    a. Os módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações.

    b. Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações.

    Também conhecido por Princípio de Hollywood: "Não nos chame, nós chamaremos você" - "Don't call us, we'll call you".

    Solução para dependências: cíclica e estável-instável/flexível.

Princípios do Desenvolvimento de Pacotes

Os 6 princípios do desenvolvimento de pacotes são divididos em granularidade (coesão) e estabilidade (acoplamento).

Granularidade: Os Princípios da Coesão de Pacotes

  • Princípio da Equivalência entre Liberação e Reuso - The Reuse-Release Equivalence Principle (REP): the granule of reuse is the granule of release.

    Adaptado para o livro: a granularidade do reuso é a granularidade do lançamento.

    Ou todas as classes em um pacote são reutilizáveis ou nenhuma delas são.

  • Princípio do Reuso Comum - The Commom-Reuse Principle (CRP): the classes in a package are reused together. If you reuse one of the classes in a package, you reuse them all.

    Adaptado para o livro: as classes em um pacote são todas reutilizadas juntas. Se você reusa uma classe no pacote, reusará todas elas.

  • Princípio do Fechamento Comum - The Commom-Closure Principle (CCP): the classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all the classes in that package and no other packages.

    Adaptado para o livro: as classes em um pacote devem ser fechadas em conjunto contra os mesmos tipos de alterações. Uma alteração que afeta um pacote afeta todas as classes nesse pacote e nenhuma em outro pacote.

Estabilidade: Os Princípios do Acoplamento de Pacotes

  • Princípio das Dependências Acíclicas - The Acyclic-Dependencies Principle (ADP): allow no cycles in the package-dependency graph.

    Adaptado para o livro: não permitir ciclos no grafo pacote-dependência.

  • Princípio das Dependências Estáveis - The Stable-Dependencies Principle (SDP): depend in the direction of stability.

    Adaptado para o livro: dependa na direção da estabilidade.

  • Princípio das Abstrações Estáveis - The Stable-Abstractions Principle (SAP): a package should be as abstract as it is stable.

    Adaptado para o livro: um pacote deve ser tão abstrato quanto estável.

Métricas

A Coesão Relacional - Relational Cohesion (H) de um pacote dá-se pela média dos relacionamentos internos (R) pelo total (N) do elemento de programação na fórmula: H = (R + 1) / N.

A Instabilidade - Instability (I) de um pacote dá-se pela relação dos acoplamentos aferentes (Afferent Couplings - Ca, saídas) pelos acoplamentos eferentes (Efferent Couplings - Ce, entradas) na fórmula: I = Ce / (Ce + Ca), sendo estável (responsável e independente) quanto mais próximo de 0.0 e instável (irresponsável e dependente) quanto mais próximo de 1.0.

A Abstração - Abstractness (A) de um pacote dá-se pela relação do número de classes abstratas (Na) pelo número de classes (Nc) na fórmula: A = Na / Nc, sendo não abstrata quanto mais próximo de 0.0 e abstrata quanto mais próximo de 1.0.

A Distância da Sequência Principal - Distance from the Main Sequence (D) dá-se pela fórmula: D = |A + I - 1|, sendo a Zona de Exclusão - Zone of Exclusion quanto mais próximo de 0.0 e a Zona de Dor - Zone of Pain (A e I ~= 0) ou Zona de Inútilidade - Zone of Uselessness (A e I ~= 1) quanto mais próximo 1.0.

results matching ""

    No results matching ""