Arquitetura de Software
Comecemos com algumas definições conceituais sobre Arquitetura de Software, segundo David Garlan e Mary Shawn:
“arquitetura de software é um nível de design voltado para questões que vão: além dos algoritmos e das estruturas de dados da computação. A projeção e a especificação da estrutura geral do sistema emergem como um novo tipo de problema. As questões estruturais incluem organização total e estrutura de controle global; protocolos de comunicação, sincronização e acesso a dados; atribuição de funcionalidade a elementos de design; distribuição física; composição de elementos de design; escalonamento e desempenho; e seleção entre as alternativas de design.”
No RUP temos a seguinte definição:
“a arquitetura de um sistema de software (em um determinado ponto) é a organização ou a estrutura dos componentes significativos do sistema que interagem por meio de interfaces, com elementos constituídos de componentes e interfaces sucessivamente menores.”
Existem diversos padrões de arquitetura de software, abaixo uma lista de alguns separados por sua forma:
- Estrutura: Camadas, Pipes e Filtros, Quadro-negro
- Sistemas Distribuídos: Broker
- Sistemas Interativos: Modelo-Visão-Controlador (MVC), Apresentação-Abstração-Controle
- Sistemas Adaptáveis: Reflexo, Microkernel
Partindo desta lista podemos perceber que de acordo com nossa necessidade e contexto, nossos aplicativo, ou partes dele, pode ser projetado de diferentes formas arquiteturais. No decorrer do texto falaremos mais do padrão arquitetural em Camadas.
Visões de Arquitetura:
Ao projetar a arquitetura de um software, podemos visualizar sua estrutura por vários “ângulos”. Estas diferentes visões de arquitetura podem ser divididas em:
- Visão de Casos de Uso, que contém casos de uso e cenários que abrangem comportamentos significativos em termos de arquitetura, classes ou riscos técnicos. Ela é um subconjunto do modelo de casos de uso.
- Visão Lógica, que contém as classes de design mais importantes e sua organização em pacotes e subsistemas, e a organização desses pacotes e subsistemas em camadas. Ela contém algumas realizações de caso de uso. É um subconjunto do modelo de design.
- Visão de Implementação, que contém uma visão geral do modelo de implementação e sua organização em termos de módulos em pacotes e camadas. A alocação de pacotes e classes (da Visão Lógica) nos pacotes e módulos da Visão de Implementação também é descrita. Ela é um subconjunto do modelo de implementação.
- Visão de Processos, que contém a descrição das tarefas (processo e threads) envolvidas, suas interações e configurações, e a alocação dos objetos e classes de design em tarefas. Essa visão só precisará ser usada se o sistema tiver um grau significativo de simultaneidade.
- Visão de Implantação, que contém a descrição dos vários nós físicos da maior parte das configurações comuns de plataforma e a alocação das tarefas (da Visão de Processos) nos nós físicos. Essa visão só precisará ser usada se o sistema estiver distribuído. Ela é um subconjunto do modelo de implantação.
Arquitetura de Software em Camadas
Contexto
Um sistema grande que requer decomposição.
Problema
Um sistema que deve resolver as questões em diferentes níveis de abstração. Por exemplo: as questões de controle de hardware, as questões de serviços comuns e as questões específicas de domínio. Seria extremamente indesejável escrever componentes verticais que lidem com essas questões em todos os níveis. Uma mesma questão deveria ser resolvida (possivelmente de maneira inconsistente) várias vezes em diferentes componentes.
Força
- As partes do sistema devem ser substituíveis.
- As alterações efetuadas nos componentes não devem ser irregulares
- Responsabilidades similares devem ser agrupadas juntas
- Tamanho dos componentes: componentes complexos talvez precisem ser decompostos
Solução
Estruture os sistemas em grupos de componentes que formem camadas umas sobre as outras. Faça com que as camadas superiores utilizem os serviços somente das camadas abaixo (nunca das camadas acima). Tente não usar serviços que não sejam os da camada diretamente abaixo (não pule camadas, a menos que as camadas intermediárias somente adicionem componentes de acesso).
Abordagens Comuns
A divisão em camadas representa um agrupamento ordenado de funcionalidades, sendo que:
- a funcionalidade específica de aplicativo está localizada nas camadas superiores,
- a funcionalidade que abrange os domínios de aplicativos se encontra nas camadas intermediárias e
- a funcionalidade específica do ambiente de implantação está nas camadas inferiores.
O número e a composição das camadas dependem da complexidade do domínio do problema e do espaço para solução:
- Em geral, há apenas uma única camada específica de aplicativo.
- Nos domínios em que sistemas anteriores foram desenvolvidos ou sistemas de grande porte são compostos de sistemas interoperacionais menores, há uma grande necessidade de compartilhar as informações entre as equipes de design. Conseqüentemente, para maior clareza, é provável que a camada específica de negócios exista parcialmente e esteja estruturada em várias camadas.
- Os espaços para solução que são suportados por produtos de middleware e nos quais o software de sistema complexo desempenha um papel importante terão camadas inferiores bem desenvolvidas, talvez com várias camadas de middleware e software de sistema.
Exemplos
Camadas genéricas
Camadas de sistemas de negócios
Quatro camadas
- A camada superior, camada de aplicativo, contém serviços específicos de aplicativo.
- A camada seguinte (camada específica de negócios) contém componentes específicos de negócios, usados em diversos aplicativos.
- A camada de middleware contém componentes como construtores GUI, interfaces para sistemas de gerenciamento de banco de dados, serviços de sistemas operacionais que não dependem de plataforma e componentes OLE, como planilhas e editores de diagramas.
- A camada inferior (camada de software de sistema) contém componentes como sistemas operacionais, bancos de dados, interfaces para hardware específico, etc.
Diretrizes da divisão
- Visibilidade: Os subsistemas só podem depender de subsistemas na mesma camada e na camada inferior seguinte.
- Volatilidade:
- Nas camadas superiores, insira elementos que variam quando os requisitos de usuário são alterados.
- Nas camadas inferiores, insira elementos que variam quando a plataforma de implementação (hardware, idioma, sistema operacional, banco de dados, etc.) é alterada.
- Entre essas camadas, insira elementos que geralmente se aplicam a diversos tipos de sistemas e ambientes de implementação.
- Acrescente camadas quando partições adicionais nessas categorias amplas ajudarem a organizar o modelo.
- Generalidade: Elementos abstratos do modelo costumam ser inseridos em camadas inferiores no modelo. Se não forem específicos da implementação, ficarão geralmente próximos das camadas intermediárias.
- Número de Camadas: (não gosto desta diretriz, apresento por constar na literatura) Para um sistema pequeno, três camadas são suficientes. Para um sistema complexo, cinco a sete camadas costumam ser suficientes. Para qualquer grau de complexidade, o uso de mais de dez camadas deve ser visto com suspeita, que deverá aumentar com o número de camadas. Algumas regras práticas são: de 0 a 10 classes – 0 camadas; de 10 a 50 classes – 2 camadas; de 25 a 150 classes – 3 camadas; de 100 a 1000 classes – 4 camadas
Padrões de particionamento
Nas camadas superiores do sistema, partições adicionais podem ajudar a organizar o modelo. As seguintes diretrizes para particionamento apresentam questões distintas a serem consideradas:
- Organização do usuário: Os subsistemas podem ser organizados em linhas que refletem a organização da funcionalidade na organização de negócios
- Áreas de competência e/ou habilidades: É possível organizar subsistemas de modo que particionem responsabilidades de partes do modelo entre grupos distintos da organização de desenvolvimento. Em geral reflete a necessidade de especialização de habilidades durante o desenvolvimento e o suporte da tecnologia de infra-estrutura complexa. Exemplos: o gerenciamento de distribuição e rede, o gerenciamento de banco de dados, o gerenciamento de comunicação, o controle de processos, etc.
- Distribuição do sistema: Em qualquer uma das camadas do sistema, é possível particioná-las “horizontalmente” para refletir a distribuição física da funcionalidade. O particionamento para refletir a distribuição pode ajudar a visualizar a comunicação de rede que ocorrerá assim que o sistema for executado.
- Áreas de sigilo: Alguns aplicativos, principalmente aqueles que exigem autorização de segurança especial para serem desenvolvidos e/ou suportados, requerem partições adicionais nas linhas de privilégio de acesso à segurança.
- Áreas de variabilidade: A funcionalidade que tende a ser opcional e, portanto, liberada apenas em algumas variantes do sistema, deve ser organizada em subsistemas independentes que são desenvolvidos e apresentados sem depender da funcionalidade obrigatória do sistema.
Conclusões
Com estes direcionamentos fica claro de que aplicações, por mais simples que sejam, devem ser divididas por um conceito básico na análise orientada à objetos: divisão de responsabilidades.
Seguindo estas diretrizes tenho certeza que os projetos de software podem ser melhor organizados diminuindo complexidades, principalmente na manutenção de código e escalabilidade durante sua vida de utilização.
No comments:
Post a Comment