Separação Modelo – Vista e Comunicação Ascendente O princípio mais importante do desenvolvimento orientado por objectos é a correta atribuição de responsabilidades numa aplicação. Um objecto deve fazer apenas uma coisa e deve-a fazer bem. Uma área onde a correta separação de responsabilidades é importante é na interacção entre a interface com o utilizador e a lógica de negócio. Durante o desenvolvimento de uma aplicação é normal os requisitos da interface com o utilizador mudarem sem haver necessidade de alterar o resto da aplicação, e também é normal os requisitos de negócio mudarem sem impacto na interface com o utilizador. Como podem as janelas obter informação para mostrar? 1 – Modelo de actualização do display “Polling ou Pull-from-above”, “Puxar-de-cima”. As janelas enviam mensagens aos objectos do domínio, pedindo informação que mostram. 2 – Mas efectuar o polling a cada segundo a muitos objectos, para descobrir apenas uma ou duas mudanças, não é eficiente. Quando há poucas mudanças nos objectos do domínio é mais eficiente serem os objectos do domínio cujo estado muda a comunicarem com as janelas para actualizar o display. Nestas situações usa-se o modelo de actualização do display “Push-from-below”, “Empurrar-de-baixo”. Mas devido à restrição imposta pelo Princípio da Separação Modelo Vista, é necessária uma comunicação indirecta entre os objectos de baixo nível e as janelas. Duas soluções: - usar o padrão Observer, referenciando o objecto GUI como um objecto que implementa uma interface tal como PropertyListener. - usar um objecto Facade UI, isto é, adicionando um objecto facade na camada UI, que recebe pedidos de baixo. Esta indirecção protege os objectos do domínio das possíveis variações da Interface. [Larman, 3.ª Edição, Capítulo 34 - Logical Architecture Refinement, 34.4 – ModelView Separation and “Upward Communication”, pág. 576] Colaboração entre Camadas Para packages que representam subsistemas, o padrão mais comum de acesso é o Facade. Um objecto público Facade define os serviços para o subsistema, e os clientes colaboram com o facade. O facade não deve expor muitas operações de baixo nível, apenas deve expor um pequeno número de operações de alto nível. O facade actua como mediador dos objectos do subsistema subjacente, os quais efectuam o trabalho. 1. 2. 3. 4. 5. Camada de Interacção com o Utilizador – UI Layer Camada da Aplicação – Application Layer Camada do Domínio – Domain Layer Camada da Lógica de Negócio – Business Logic Layer Camada de Amazenamento – Storage Layer A Arquitectura Clássica de 3 Camadas: Interface -1 Lógica da Aplicação -2, 3, 4 Armazenamento -5 Colaboração Ascendente com Observer O padrão Facade é normalmente usado para colaboração descendente da camada mais alta para a camada mais baixa. Quando a camada (mais baixa) do domínio necessita comunicar para cima com a camada UI, usa-se geralmente o padrão Observer (“Publish-Subscribe”). Padrão Observer Os objectos UI, na camada UI implementam uma interface tal como PropertyListener, e são subscritores e listeners de eventos provenientes de objectos nas camadas mais baixas. Os objectos das camadas mais baixas enviam mensagens directamente aos objectos UI, mas o acoplamento é efectuado para objectos vistos como implementadores de um interface, como por exemplo PropertyListener, e não vistos como objectos específicos UI. Acoplamento Desnecessário Embora se deva minimizar o acoplamento entre objectos, muitas vezes não causa problemas. No entanto é de evitar acoplamento desnecessário a objectos que podem mudar ou evoluir ao longo do desenvolvimento do projecto. Mas não se deve gastar tempo e dinheiro em encapsular o que é pouco provável de mudar, ou o que apresente um pequeno impacto se mudar. Por exemplo, ao construir uma aplicação em Java, o acesso a objectos das bibliotecas java não traz qualquer problema, porque esses objectos são muito estáveis.