Técnico

Refatorando o ModelLocator do Cairngorm – Parte II

Primeiramente, desculpas pela demora em liberar a segunda parte desse post. 🙂

Segundo, essa é apenas uma tentativa de instigar a comunidade Flex a refletir e debater mais sobre as soluções que adotam como boas práticas de programação no seu dia a dia.

Feitas as considerações iniciais, podemos prosseguir.

Muitos desenvolvedores já estão cansados de ouvir a respeito dos padrões DI (Injeção de Dependência) e IoC (Inversão de Controle). Desenvolvedores Flex, em especial, conhecem os benefícios desses padrões através da implementação do padrão Service Locator. O principal benefício tanto da DI quanto do Service Locator, é que ambos promovem o desacoplamento entre as partes, diferenciando-se somente na forma como são implementados.

Usando o padrão Service Locator, o locator esconde as dependências de outras implementações, mas você encontra certa dificuldade para encontrá-lo em seu código. Já a DI facilita a visualização das dependências do componente, uma vez que você pode simplesmente analisar o mecanismo de injeção, como o construtor, para entender seu funcionamento. É evidente que ambas são favoráveis ao desenvolvimento, e sua escolha deve estar sempre baseada no seu contexto: Se sua aplicação possui várias classes que usam um serviço, o uso do Service Locator pode ser mais favorável, uma vez que a dependência das classes com o locator pode não ser um grande problema.

Deixando as discussões sobre refatorar o Service Locator para outro post (e talvez até um possível refactoring no FrontController … rs), vamos agora definir a arquitetura da nossa aplicação, destacar pontos de destaque, comparando e destacando seus benefícios. Lembrando que o objetivo da aplicação é demonstrar como refatorar o ModelLocator do Cairngorm, de forma que ele se torne, finalmente, um ponto de acesso aos nossos modelos e não nosso modelo de fato.

Acho oportuno citar uma frase que li numa apresentação do Bore Wessel, na época consultor sênior do time de RIA da Adobe: “O Cairngorm oferece padrões sobre como você pode implementar uma dada funcionalidade, mas você não precisa segui-los, nem mesmo o programador precisa seguir as boas práticas de programação da orientação a objetos”. Na mesma apresentação, ele segue dizendo que a preferência dos consultores da Adobe é de fato pelo uso do padrão Presentaion Model, quando definindo uma arquitetura para as views.

Vamos ver abaixo como nosso projeto foi organizado:

Vamos destacar dois pontos chaves, que precisam de sua atenção:

O Domain model da aplicação (AgendaModel.as), o qual encontra-se sob o pacote br.com..model.domain.
Essa classe é resposável por estruturar os dados da aplicação e também definir seus comportamentos. Nesse exemplo, vamos trabalhar com um único Domain Model, porém aplicações de grande escala podem ter a necessidade de dividir a responsabilidade em mais classes Domain Models. Aplicações modularizadas, por exemplo, porem ter um Domain Model para cada um dos seus módulos.

O Domain Model da aplicação é instanciado pelo nosso ModelLocator, conforme abaixo:

public static function getInstance():ModelLocator
{
if(instance == null)
{
instance = new ModelLocator();

// Os modelos são instanciados quando
// nosso ModelLocator é instanciado
instance.agendaModel = new AgendaModel();
}

return instance ;
}

Os Presentation Models que estão sob o pacote br.com..model.presentation.
As classes Presentation Model possuem uma super classe (AbstractPM.as) que define seus comportamentos comuns. Aqui existe um importante detalhe de implementação: A super classe herda de EventDispatcher, pois nossas views não disparam mais events ou Cairngorm events, passando essa responsabilidade aos Presentations Models, desacoplando as views do Cairngorm. Dessa forma, as views da aplicação não possuem mais referências à propriedades do ModelLocator, e a dependência agora passa a ser com seu respectivo Presentaion Model.

Os Presentation Models das views internas são inicializados pelo Presentation Model principal da aplicação e possuem uma referência ao Domain Model da aplicação:

// Domain Model da aplicação
public var agendaModel:AgendaModel;
// Presentation Model da View ContatosView
public var contatosModel:ContatosModel;
public function AgendaPresentationModel(appModel:AgendaModel)
{
agendaModel = appModel;

// Presentation Model de uma view interna
// Repare que estamos injetando o Domain Model
contatosModel = new ContatosModel(agendaModel);
}

Outro ponto importante que merece destaque é o fato dos Presentation Models atualizarem nosso modelo diretamente, tirando essa responsabilidade dos commands.

public function result(data:Object):void
{
// Método setter no Presentation Model
contatosModel.contactsCollection = new ArrayCollection(data.result as Array);
}

O modelo agora é atualizado através da chamada de um método do Presentation Model, e não através de uma propriedade no ModelLocator.

Para os interessados em entender melhor o padrão Presentation Model, recomendo a leitura do blog do Paul Williams, onde há uma série de artigos interessantes a esse respeito e que foram importantes fontes de referência na construção desse post.

Veja abaixo um diagrama que exemplifica como as classes de Presentation Model e Domain Model relacionam-se com as views da aplicação nessa nova arquitetura:

No próximo post, o código completo de uma aplicação utilizando a arquitetura e os padrões citados acima, refatorando totalmente o ModelLocator do Cairngorm.

Prometo ser mais rápido. 🙂

Até a próxima pessoal!

13 Comments

  • DClick Blog disse:

    […] aqui a segunda parte desse […]

  • Anderson disse:

    Previsão para a próxima parte do artigo?

    []’s

  • Pablo Souza disse:

    Olá Anderson,

    Estou preparando nessa semana algo relacionado ao iPhone,
    mas na semana que vem libero a próxima parte sim.

    Fica à vontade se quiser discutir algo à respeito.

    Um Abraço!

  • Anderson disse:

    Ok! Blz…

    Vamos lá! rs

    Antes eu tinha a view da minha aplicação (APPView.mxml) que instanciava um componente (CView) e também continha uma referência do model (CModel).

    [Bindable]
    private var cm:CModel = new CModel();

    Pelo o que eu pude entender, o que faço agora é instanciar meus Presentation Models dentro do Presentation Model da view principal (mantive ele bindable), correto?

    Ficaria assim:

    Entendi direito? rs

  • Anderson disse:

    Eita… engoliram os trechos que continham tags! oO

  • Anderson disse:

    Ok! Blz…

    Vamos lá! rs

    Antes eu tinha a view da minha aplicação (APPView.mxml) que instanciava um componente (CView) e também continha uma referência do model (CModel).

    [script]
    [Bindable]
    private var cm:CModel = new CModel();

    [mxml]
    [view:CView cm=”{cm}”/]

    Pelo o que eu pude entender, o que faço agora é instanciar meus Presentation Models dentro do Presentation Model da view principal (mantive ele bindable), correto?

    Ficaria assim:
    [view:CView cm=”{ModelLocator.getInstance().presentationModel.loginForm}”/]

    Entendi direito? rs

  • Pablo Souza disse:

    Olá Anderson. Exatamente!

    Esse (a view principal da aplicação) deveria ser o único lugar onde você recuperaria a instância do ModelLocator, diminuindo assim sua dependência, e à partir daí você injeta os presentation model (modelo) das views que estão abaixo da view principal.

    Estou finalizando a última parte, espero postar ainda hoje ou no máximo no fim de semana.

    Um abraço!

  • DClick Blog disse:

    […] visto no post anterior, vamos hoje liberar o código-fonte completo da refatoração para que vocês possam entender melhor […]

  • […] visto no post anterior, vamos hoje liberar o código-fonte completo da refatoração para que vocês possam entender […]

  • Estou refatorando o meu ModelLocator, só estava esperando alguns embasamentos teóricos para convencer minha turma.

    Eu sempre disse que o nosso ModelLocator demorava mais para abrir do que nossa aplicação. Nosso ModelLocator parece um maracanã lotado de VOs e outras “gambis” do view.

    Abraço meu jovem, espero que você publique mais dicas.

  • Alexandre dos Santos Matos disse:

    Você ainda já leu este artigo?: http://www.dehats.com/drupal/?q=node/48

  • Muito boa a explicação e comentários sobre a representação do Modelo Cairngorm. Estou começando a estudar essas práticas e pretendo me aprofundar no Flex. Vc está de parabens pela explanação.

  • […] visto no post anterior, vamos hoje liberar o código-fonte completo da refatoração para que vocês possam entender […]

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Compartilhe isso: