• Nenhum resultado encontrado

Android Binding. Implementando o padrão de projeto MVVM com MVVM_. Saiba como criar um projeto utilizando o padrão de projeto MVVM no Android

N/A
N/A
Protected

Academic year: 2021

Share "Android Binding. Implementando o padrão de projeto MVVM com MVVM_. Saiba como criar um projeto utilizando o padrão de projeto MVVM no Android"

Copied!
8
0
0

Texto

(1)

MVVM_

Implementando o padrão

de projeto MVVM com

O padrão de projeto MVVM

O

MVVM (Model-View-ViewModel) foi divulgado pela primeira vez em 2005 por John Gossman, na época arquiteto da plataforma Silverlight da Micro-soft em seu blog. O mesmo se baseou fortemente no padrão de projeto Presentation Model (muito seme-lhante ao MVP − Model-View-Presenter), divulgado por Martin Fowler em 2004. Verifique o diagrama do padrão MVVM na figura 1.

Abaixo o papel de cada camada do MVVM:

view: a representação visual de elementos e

ações que farão a interface com o usuário.

viewmodel: uma classe responsável por conter

o binding (ligação) com os elementos da View. A des-crição real é que a mesma se trata do modelo da tela, representando o estado atual da mesma.

model: referente a um modelo de domínio,

re-presentando o estado atual do mesmo.

O grande diferencial que o MVVM adotou e que o destaca de outros padrões de projeto conhecidos como o MVC, é sua capacidade de separar a camada de apresentação (View) da lógica de apresentação (ViewModel), facilitando a aplicação de testes uni-tários na ViewModel. A ViewModel cria seu próprio

modelo de representação da View, acabando com os acessos diretos à camada Model. As camadas acabam ficando menos acopladas, facilitando a manutenção.

Quando proporcionamos a separação das cama-das, podemos separar as responsabilidades no de-senvolvimento de sistemas, assim decentralizamos as tarefas. Nesse modelo, as interfaces podem ser criadas por designers e o código por programadores.

Graças a sua flexibilidade, o padrão MVVM foi facilmente adaptado às plataformas modernas ba-seadas no modelo Event-Driven-Developer, como WPF (Windows Presentation Foundation), Silverligh e Android.

Saiba como criar um projeto

utilizando o padrão de projeto MVVM

no Android

Android

Binding

View ViewModel

Model Figura 1. Diagrama do padrão de projeto MVVM.

(2)

Em um tempo que os principais requisitos são o desenvolvimento de

softwares de forma cada vez mais rápida e produtiva e que ainda

sejam confiáveis e fáceis de manter, possuir uma boa plataforma de

projeto é um diferencial. Apesar do Android prover certas

facilida-des para o facilida-desenvolvedor, nativamente não disponibiliza algumas

implementações como padrão de projeto MVVM, basicamente

res-ponsável por simplificar a amarração entre design e código,

presen-te em outras plataformas como a Silverlight da Microsoft. Para que

possamos adaptar o Android na utilização deste padrão, temos que

nos utilizar de frameworks que no caso deste artigo será o Android

Binding.

Giuliano Bem Hur Firmino | giulianofirmino@yahoo.com.br Especialista em Engenharia de Software pelo Instituto da Computação da Unicamp e certificado pela Sun (SCJP). Atua na área de desenvolvimento de softwares há 11 anos. Com a plataforma JAVA nos ambientes Web, Mobile e Enterprise.

Padrões de apresentação

Abaixo, poderemos verificar os principais pa-drões de projeto voltados à apresentação utilizados no mercado e quais as diferenças comparados ao MVVM.

MVVM x MVC (Model-View-Controller)

O MVC é um padrão de projeto criado em 1979 por Trygve Reenskaug, inicialmente desenvolvido para Smaltalk. O mesmo surgiu com objetivo de me-lhorar a organização do projeto, separando acesso aos dados, regras de negócios e lógica de apresen-tação. Atualmente o mesmo é considerado uma “ar-quitetura padrão” no desenvolvimento de software. Confira o seu diagrama na figura 2.

O MVC se diferencia do MVVM, por conta do li-vre acesso da View a camada Model, o que o torna fortemente acoplado.

MVVM x MVP (Model-View-Presenter)

O MVP foi criado originalmente em 1990 pela Taligent, uma parceira da Apple, IBM e HP. É um padrão de projeto que facilita a automação de tes-tes unitários e separação de conceitos na camada de apresentação. Confira o seu diagrama na figura 3.

O MVP se diferencia do MVVM, por conta da pre-sença da interface que representa a View. Podemos por exemplo desenvolver uma tela em swing e outra em Android e utilizar o mesmo Presenter, bastando implementar a Interface que representa a View, nas diferentes plataformas. Isso não acontece no MVVM, pois o mesmo é amarrado à plataforma/framework.

observer

De acordo com a definição GoF, seu objetivo é “Definir uma dependência um-para-muitos entre

objetos para que quando um objeto mudar de esta-do, todos os seus dependentes sejam notificados e atualizados automaticamente”. Você pode observar o seu funcionamento no diagrama da figura 4.

MVVM x MVP x MVC

View Controller

Model

Figura 2. Diagrama do padrão de projeto MVC. Figura 3. Diagrama do padrão de projeto MVP.

View Presenter

(3)

Acoplamento entre View e Model Reutilização do código para N Views Parceria com o padrão Observer

MVVM Não Não Sim

MVP Não Sim Sim

MVC Sim Não Não

Sobre o Android Binding

Android Binding é um framework open-source desenvolvido para a plataforma Android que provê de maneira simples, binding de componentes visuais contidos em arquivos xML. Sua arquitetura foi criada principalmente para ajudar no desenvolvimento de aplicações utilizando o padrão de projeto MVVM.

Para se desenvolver aplicações visuais para An-droid, são necessários classes do tipo Activity, essas classes na arquitetura padrão, detêm muita das res-ponsabilidades do sistema, como controlar o fluxo da aplicação, entradas dos usuários, comunicação com a camada de negócio, entre outros. Ao utilizar o An-droid Binding a responsabilidade das classes Activity, são reduzidas a amarrar as camadas View e ViewMo-del, separando as tarefas e simplificando ainda mais o desenvolvimento para Android.

O projeto de exemplo

Para exemplificar a utilização do padrão de pro-jeto MVVM e algumas das funcionalidades presentes no framework AndroidBinding, vamos criar uma apli-cação completa na plataforma Android. Você ainda poderá conferir este projeto na íntegra, baixando o código-fonte do mesmo, no site da revista.

Essa aplicação é responsável por armazenar lis-tas de compras. Esse sistema é formado por três telas, conforme descrito abaixo.

Tela inicial: contendo todas as listas de

com-pras e os botões para Criar, Editar e Apagar uma lista, conforme mostrado na figura 5. Ao iniciar a tela, o sistema exibe todas as listas de compras cadastradas no banco de dados. Ao clicar em Criar, o sistema irá abrir a tela de edição de lista de compras, com uma nova lista. Clicando em Editar, o sistema irá carregar a tela de edição de lista de compras, com a lista sele-cionada, o botão “apagar” exclui a lista de compras do

banco de dados.

Tela de edição da lista de compras: contendo

o nome, lista de itens da compra, totalizador da com-pra e os botões de Adicionar, Editar e Excluir itens e Salvar e Cancelar as alterações da lista de compras. Conforme mostrado na figura 6. Ao clicar no botão adicionar o sistema abrirá a tela de edição de item da lista de compras, com um item novo. Clicando em Editar, o sistema irá carregar a tela de edição de item da lista de compras, com o item selecionado. O botão Excluir irá excluir o item em cache da lista. Só quando o usuário clicar em Salvar, a lista será incluída/alte-rada e seus respectivos itens serão todos excluídos do banco e adicionados novamente (isso facilita o pro-cesso, uma vez que teríamos que verificar item a item, se o mesmo, deve ser incluído, alterado ou excluído do banco de dados). Se o botão Cancelar for clicado, simplesmente o sistema ignora as alterações retor-nando a tela principal.

Tela de edição do item da lista de compras: Figura 4. Diagrama do padrão de projeto Observer.

<<interface>>

Observer <<interface>>Observable

+ notify() Observerlmpl1 Observerlmpl2 Observablelmpl + addObserver(Observer) + notifyObservers()

(4)

contendo nome, quantidade, valor unitário e valor total e os botões Salvar e Cancelar as alterações do item de compra. Conforme mostrado na figura 7, o

botão Salvar irá incluir o item no cache da lista e fará o sistema retornar a tela da Lista de Compras. Ao clicar em Cancelar o sistema ignora as alterações retornando a tela da Lista de Compras.

Veja o diagrama desse pequeno, mas funcional sistema na figura 8.

um detalhe peculiar de implementação do MVVM para a plataforma Android é a representação da camada View através de xmls. A View main_view. xml representa a tela inicial da aplicação, compra_ view.xml representa a tela de edição das Listas de Compras e item_compra_view.xml representa a tela de edição do Item da Lista de Compras.

Podemos observar que para cada View existe um respectivo ViewModel, isso ocorre porque cada tela possui um modelo específico de informações e ações. Já a camada Model, responsável por encapsu-lar o domínio do projeto, está representada por duas classes, CompraModel e ItemCompraModel.

Pré-requisitos

» Plugin do eclipse ADT

» SDK do Android com a versão 2.1

Preparação do ambiente

» Fazer checkout da última versão do projeto An-droid Binding, utilizando para isso uma ferra-menta cliente de SVN: http://android-binding. googlecode.com/svn.

» Criar um novo workspace.

» Importar o projeto AndroidBinding para o workspace.

Criando o projeto

» Clique no menu File, selecione New e clique em Other.

» Abra a aba Android e selecione Android Pro-ject. Clique no botão Next.

» Em Project Name, digite “ListaCompra”. Clique no botão Next.

Figura 7. Tela de edição do Item da Lista de Compras. Figura 6. Tela de edição da Lista de Compras.

MailViewModel CompraModel main_view.xml CompraViewModel ItemCompraModel compra_view.xml ItemCompraViewModel Item_compra_view.xml

(5)

» Selecione a versão do SDK a ser utilizada, no nosso caso a 2.1. Clique no botão Next.

» Em Package Name, digite “android.compra”. Clique no botão Finish.

» Após criar o projeto, acesse suas propriedades. Clique com o botão direito sobre o projeto e cli-que em Properties. Selecione a aba Android, na caixa Library clique em Add. Selecione o proje-to AndroidBinding e clique em ok.

Codificando

Ciclo de vida do Android Binding

O Android Binding tem seu próprio ciclo de vida e para o iniciarmos, devemos chamar o método init da classe Binder antes de começarmos a utilizar qual-quer recurso deste framework. Essa inicialização deve ser feita logo que a aplicação seja iniciada. Para isso devemos implementar o método onCreate da classe

Application (observe na Listagem 1 a classe que

es-tende Application).

Nativamente o android amarra as xMLs às clas-ses Activity, para que possamos prover um binding entre a camada View (xMLs) e a camada ViewModel, as classes Activity deverão estender BindingActivity herdando o método setAndBindRootView que deve ser chamado no evento onCreate preparando a fun-cionalidade para trabalhar no padrão MVVM (confor-me podemos ver nas Listagens 3, 4 e 5).

Na figura 9 podemos visualizar todo o ciclo de vida do Android Binding e na Listagem 2, como ficou o arquivo AndroidManifest.xml com a classe

Applica-tion e as classes Activity configuradas.

Listagem 1.

Inicializando o ciclo de vida do Android

Binding.

publicclass MainApplication extends Application {

@Override

publicvoidonCreate() { super.onCreate(); Binder.init(this); }

}

Listagem 2.

AndroidManifest.xml configurado com as

classes Activity.

<?xmlversion=”1.0” encoding=”utf-8”?>

<manifestxmlns:android=”http://schemas.android.com/

apk/res/android” package=”android.compra” android:versionCode=”1” android:versionName=”1.0”> <uses-sdkandroid:minSdkVersion=”7”/> <application android:icon=”@drawable/ic_launcher” android:label=”@string/app_name” android:name=”MainApplication”> <activity android:name=”MainActivity” android:label=”@string/app_name” android:noHistory=”true”> <intent-filter> <actionandroid:name=” android.intent.action.MAIN”/> <categoryandroid:name= “android.intent.category.LAUNCHER”/> </intent-filter> </activity> <activity android:name=”CompraActivity” android:label=”@string/lista_compras”

android:noHistory=”true”></activity>

<activity

android:name=”ItemCompraActivity”

android:label=”@string/item_lista_compra”

android:noHistory=”true”></activity>

</application>

</manifest>

Figura 9. Diagrama do fluxo de uso do Android Binding. Activity <<framework>> Android Biding ViewModel Application View bind init

(6)

Listagem 3.

Classe MainActivity.

publicclass MainActivity extends BindingActivity {

@Override

publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

this.setAndBindRootView(R.layout.main_view, newMainViewModel(this));

} }

Listagem 4

. Classe CompraActivity.

publicclass CompraActivity extends BindingActivity {

@Override

publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

//…

this.setAndBindRootView(R.layout.compra_view, newCompraViewModel(this, model)); }

}

Listagem 5.

Classe ItemCompraActivity.

publicclass ItemCompraActivity extends BindingActivity {

@Override

publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

//…

this.setAndBindRootView( R.layout.item_compra_view,

newItemCompraViewModel(this, model)); }

}

Criando os arquivos de layout (Views)

O próximo passo será criarmos as Views que são simplesmente layouts xML padrão do An-droid, com a adição do schema do Android Binding xmlns:binding=”http://www.gueei.com/android--binding/” que será responsável por marcar os ele-mentos visuais que serão amarrados com a ViewMo-del. Na Listagem 6 é exibido um dos arquivos, mais especificamente a tela de edição da lista de compras. Note que só são mostradas as principais proprieda-des do schema do Android Binding, “binding:text”, “binding:onClick”, “binding:itemSource” e “binding:itemTemplate”, no próximo tópico os mes-mos serão explicados com mais detalhes.

Listagem 6.

Tela de edição da lista de compras,

arquivo compra_view.xml.

<?xmlversion=”1.0” encoding=”utf-8”?>

<LinearLayoutxmlns:android=”http://schemas.android.

com/

apk/res/android”

xmlns:binding=”http://www.gueei.com/ android-binding/” ...>

<TextView ... android:text=”Nome”/>

<EditText ... binding:text=”nome”>

<requestFocus/>

</EditText>

<TextView ... android:text=”Itens”/>

<ListView ...

binding:itemSource=”lista”

binding:itemTemplate=”@layout/lista_item_compra”

/>

<TextView ... binding:text=”total”/>

<LinearLayout ... android:orientation=”vertical”>

<LinearLayout ...>

<Button ... binding:onClick=”adicionar”/>

<Button ... binding:onClick=”editar”/>

<Button ... binding:onClick=”excluir”/>

</LinearLayout>

<LinearLayout ...>

<Button ... binding:onClick=”salvar”/>

<Button ... binding:onClick=”cancelar”/>

</LinearLayout>

</LinearLayout>

</LinearLayout>

Implementando os arquivos ViewModel

Agora devemos criar os respectivos modelos das views anteriores. Esses atuam através de classes nor-mais, pertencentes à camada VIewModel. Nas Lista-gens 7 e 8 podemos observar alguns dos principais recursos do Android Binding que irá nos auxiliar a implementarmos o padrão de projeto MVVM, iremos estudar cada um deles.

stringobservable: refere à propriedade

“binding:text” da View. Este recurso se trata de um observador (implementação do padrão de projeto Observer), cujo o papel é amarrar um valor String a um elemento do tipo EditText. A alteração do conte-údo de objetos desta classe é refletida na tela.

Dependentobservable: também referente à

(7)

que o mesmo é acionado caso o valor de um ou mais campos seja alterado. Muito utilizado em campos calculados, como é o caso do campo total, da tela de edição de item da lista de compra que é a multiplica-ção entre quantidade e valor unitário.

Arraylistobservable: refere à propriedade

“binding:itemSource” da View. Este recurso também se trata de um observador, cujo papel é amarrar uma lista ao elemento do tipo ListView. As alterações das informações presentes nos objetos desta lista são re-fletidas na tela.

command: são ações que no caso do nosso

exemplo são acionadas através das propriedades “binding:onClick”.

Arraylistitem: se trata de uma Inner Class

(se-guindo o padrão do ViewModel) criada para repre-sentar uma template do elemento visual ListView, referente à propriedade “binding:itemTemplate”. Es-tes templaEs-tes são arquivos do tipo layout xML que representam os elementos que serão exibidos em cada linha do elemento ListView. Na Listagem 9 note que este arquivo de template adota o mesmo padrão das Views exibidas anteriormente, somente com uma diferença, como representam uma linha, podemos ter propriedades como “binding:onClick” no elemento LinerLayout, acionando os comandos presentes na Classe ArrayListItem.

O Android Binding apresenta ainda mais recur-sos que não serão discutidos neste artigo. Exemplos completos de utilização destes recursos podem ser obtidos na documentação presente no site do projeto (veja link nas referências, no final do artigo).

Listagem 7.

Classe CompraViewModel.

private CompraModel model;

private ArrayListItem itemSelecionado;

public StringObservable nome = newStringObservable();

public StringObservable total = newStringObservable();

publicfinal ArrayListObservable<ArrayListItem> lista = new ArrayListObservable<ArrayListItem>( ArrayListItem.class);

public Command adicionar = newCommand(){ publicvoidInvoke(View view, Object... args) { //…

} };

public Command editar = newCommand(){ publicvoidInvoke(View view, Object... args) { //…

} };

public Command excluir = newCommand(){ publicvoidInvoke(View view, Object... args) { //...

} };

public Command salvar = newCommand(){ publicvoidInvoke(View view, Object... args) { //…

} };

public Command cancelar = newCommand(){ publicvoidInvoke(View view, Object... args) { //…

} };

publicclass ArrayListItem {} }

Listagem 8.

Classe ItemCompraViewModel.

publicclass ItemCompraViewModel {

private ItemCompraModel model;

public StringObservable nome = newStringObservable();

public StringObservable quantidade = newStringObservable();

public StringObservable valorUnitario = newStringObservable();

publicfinal DependentObservable<String> total = new DependentObservable<String>( String.class, quantidade, valorUnitario){ @Override

public String calculateValue(Object... arg0) throws Exception {

//…

} };

public Command salvar = newCommand(){ publicvoidInvoke(View view, Object... args) { //…

} };

public Command cancelar = newCommand(){ publicvoidInvoke(View view, Object... args) { voltarCompraView();

} }; }

(8)

Listagem 9.

Template da ListView da tela inicial do sistema.

<?xmlversion=”1.0” encoding=”utf-8”?>

<LinearLayoutxmlns:android=”http://schemas.android.

com/apk/res/ android” xmlns:binding=”http://www.gueei.com/android-binding/” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:orientation=”horizontal” binding:onClick=”selecionar”> <TextView android:layout_width=”240dip” android:layout_height=”22dip” android:textSize=”20dip” android:gravity=”left” binding:text=”nome”/> <TextView android:layout_width=”80dip” android:layout_height=”22dip” android:textSize=”20dip” android:gravity=”right” binding:text=”total”/> </LinearLayout>

Implementando os arquivos Model

Por último, iremos implementar as classes refe-rentes à camada de domínio (Model). Na Listagem 10 é exibida uma das classes de domínio do sistema. Como o foco do artigo não é sobre acesso a banco de dados, não detalharemos a fundo estas classes, ficando somente a dica que estas, além de deterem o estado dos domínios, também são responsáveis por executar regras de negócios, presentes no nosso exemplo, em métodos como incluir, alterar e excluir.

Outro detalhe é que estas classes estendem Se-rializable, pois o Android serializa objetos comple-xos, ao serem passados como parâmetro de um Ac-tivity para outro. Veja um exemplo na Listagem 10.

Listagem 10.

Classe CompraModel.

publicclass CompraModel implements Serializable {

private Long codigo; private String nome;

private List<ItemCompraModel> itens;

publicCompraModel() {

this.itens = new ArrayList<ItemCompraModel>(); }

// Métodos gets e sets

public Double getTotal() { Double total = 0.00;

for (ItemCompraModel item : itens) { total += item.getTotal();

}

return total; }

publicstatic List<CompraModel> obterTodas() {/* Acesso ao banco de dados */}

publicstatic CompraModel obterPorCodigo( Long codigo) {/* Acesso ao banco de dados */}

publicvoidincluir() {/* Acesso ao banco de dados */}

publicvoidalterar() {/* Acesso ao banco de dados */}

publicvoidexcluir() {/* Acesso ao banco de dados */}

}

Considerações finais

Foram apresentados os principais conceitos no desenvolvimento de aplicações utilizando-se o pa-drão de projeto MVVM, com a ajuda do framework Android Binding. Pudemos observar que esse padrão de projeto simplifica muito o desenvolvimento, sepa-rando as camadas e facilitando a criação de testes. Por se tratar de um projeto relativamente novo, o Android Binding tem uma pequena defasagem de documenta-ção a qual pode ser encontrada de forma simplificada em http://code.google.com/p/android-binding/wiki/, mas por ser tratar de um projeto open-source o mes-mo pode ser explorado com facilidade.

Site oficial do Android Binding: http://code.google.com/p/ android-binding/

Artigo original de John Gossman sobre MVVM: http://blogs.msdn.com/b/johngossman/ archive/2005/10/08/478683.aspx

Artigo original de Martin Fowler sobre Presentation Model: http://martinfowler.com/eaaDev/

PresentationModel.html

Referências

Documentos relacionados

- Se o estagiário, ou alguém com contacto direto, tiver sintomas sugestivos de infeção respiratória (febre, tosse, expetoração e/ou falta de ar) NÃO DEVE frequentar

Reconhecimento de face utilizando banco de imagens monocromáticas e coloridas através dos métodos da análise do componente principal (PCA) e da Rede Neural Artificial (RNA)

Promovido pelo Sindifisco Nacio- nal em parceria com o Mosap (Mo- vimento Nacional de Aposentados e Pensionistas), o Encontro ocorreu no dia 20 de março, data em que também

• Capacitação e Transferência da metodologia do Sistema ISOR ® para atividades de Coaching e/ou Mentoring utilizando o método das 8 sessões;.. • Capacitação e Transferência

10.1.3 - Os candidatos poderão solicitar revisão, dirigida à Banca Examinadora, nos dias 15 e 16/01/2014, conforme orientação constante no endereço eletrônico

Mas, no caso de não existir a temporização poderá ocorrer desarmes indevidos durante oscilação de tensão no sistema, seja por curto-circuito próximo

[r]

Freud (1974) reflete sobre o brincar da criança e sinaliza que é “errado supor que a criança não leva esse mundo a sério; ao contrário, leva muito a sério sua brincadei- ra