Антон Валюх - Использование паттерна mvvm в android

37

Upload: dataart

Post on 20-Mar-2017

1.987 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: Антон Валюх - Использование паттерна Mvvm в android
Page 2: Антон Валюх - Использование паттерна Mvvm в android

Спикер:

Тема:

Антон Валюх

Использование паттерна MVVM в Android

Page 3: Антон Валюх - Использование паттерна Mvvm в android

MVP

MVP (Model-View-Presenter) — шаблон проектирования, производный от MVC, который был разработан в основном для построения пользовательского интерфейса.

Используется для облегчения автоматического модульного тестирования и улучшения разделения логики от отображения. Основные принципы работы с шаблоном MVP, были подробно проанализированы в статье Мартина Фаулера «GUI Architectures» (2006).

http://martinfowler.com/eaaDev/uiArchs.html

Page 4: Антон Валюх - Использование паттерна Mvvm в android

MVP

View Presenter Model

user events updates model

state-change eventupdates view

View это интерфейс пользователя, который отображает данные и выполняет маршрутизацию пользовательских команд (событий) в Presenter.

Presenter управляет данными (Model) и представлением (View). Он извлекает данные из модели и форматирует их для отображения во View.

Model предоставляет данные для пользовательского интерфейса.

Page 5: Антон Валюх - Использование паттерна Mvvm в android

MVP

public interface SomeScreenView { void startLoading(); void stopLoading(); void mapDataItems(final Collection<DataItem> items);}

MVP позволяет создавать абстракцию представления. Для этого необходимо выделить интерфейс представления с определенным набором свойств и методов. 

Page 6: Антон Валюх - Использование паттерна Mvvm в android

MVP

public class SomeScreenPresenter extends Presenter { private SomeScreenView mView; public void setView(SomeScreenView view) { mView = view; } @Override public void initialize() { mView.startLoading(); mView.mapDataItems(...); mView.stopLoading(); }}

Presenter, получает ссылку на реализацию интерфейса, подписывается на события представления и по запросу изменяет модель.

Presenter взаимодействует с View путем использования специального интерфейса, который описывает абстракцию этого View.

Page 7: Антон Валюх - Использование паттерна Mvvm в android

MVP

@EActivity(R.layout.activity_some_screen)public class SomeScreenActivity extends Activity implements SomeScreenView { private SomeScreenPresenter mPresenter; @ViewById(R.id.drawer_layout) protected ProgressBar mProgressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPresenter = new SomeScreenPresenter(this); mPresenter.initialize(); }}

View взаимодействует напрямую с Presenter-ом, путем вызова соответствующих функций или событий экземпляра Presenter.

Page 8: Антон Валюх - Использование паттерна Mvvm в android

MVVM

Page 9: Антон Валюх - Использование паттерна Mvvm в android

MVVM

View ViewModel Model

UI eventsModel change

events

Update

ViewModel data

Property hanged events

Read

MVVM позволяет связывать элементы View со свойствами и событиями ViewModel. ViewModel — это абстракция представления. Свойства View совпадают со свойствами ViewModel/Model. При этом ViewModel не имеет ссылки на интерфейс представления.

Изменение состояния View-модели автоматически изменяет представление и наоборот. Для этого используется механизм связывания данных (Bindings).

Для MVVM характерна двухсторонняя коммуникация с представлением.

Page 10: Антон Валюх - Использование паттерна Mvvm в android

MVVM

• RoboBinding

• ngAndroid

• Bindroid

• Android Data Binding

Page 11: Антон Валюх - Использование паттерна Mvvm в android

RoboBinding

Представляет собой MVVM фреймворк для платформы Android.

• позволяет легко осуществить привязку (binding) атрибутов для любых пользовательских компонентов, сторонних компонентов или виджетов для Android. Как результат позволяет «выкинуть» много «ненужного кода» за счет использования бинов.

• не уменьшает производительность за счет использования генерации кода вместо рефлексии.

Page 12: Антон Валюх - Использование паттерна Mvvm в android

RoboBinding - установка

apply plugin: 'com.android.application'apply plugin: 'com.neenbedankt.android-apt'

apt("org.robobinding:codegen:$robobindingVersion") { exclude group: 'com.google.android', module: 'android'}

compile("org.robobinding:robobinding:$robobindingVersion") { exclude group: 'com.google.android', module: 'android'}

buildscript { dependencies { classpath 'com.android.tools.build:gradle:xxx' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' }}

Page 13: Антон Валюх - Использование паттерна Mvvm в android

RoboBinding - ViewModel

@PresentationModelpublic class SomeScreenViewModel implements HasPresentationModelmChangeSupport {

private PresentationModelChangeSupport mChangeSupport; private String mUserFirstName; private String mUserLastName;

public SomeScreenViewModel() { mChangeSupport = new PresentationModelChangeSupport(this); }

public String getUserFirstName() { return mUserFirstName; } public String getUserLastName() { return mUserLastName; } public String getUserFullName() { return mUserFirstName + " " + mUserLastName; }

public void setUserFirstName(String userFirstName){ mUserFirstName = userFirstName; } public void setUserLastName(String userLastName){ mUserLastName = userLastName; } public void updateUser() { mChangeSupport.firePropertyChange("userFullName"); } @Override public PresentationModelChangeSupport getPresentationModelmChangeSupport() { return mChangeSupport; }}

Page 14: Антон Валюх - Использование паттерна Mvvm в android

RoboBinding – Layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:bind="http://robobinding.org/android" android:orientation="vertical">

<TextView …… bind:text="{userFullName}"/> <EditText …… bind:text="${userFirstName}"/>

<EditText …… bind:text="${userLastName}"/> <Button …… bind:onClick="updateUser"/>

</LinearLayout>

Page 15: Антон Валюх - Использование паттерна Mvvm в android

RoboBinding - Activity

public class SomeScreenActivity extends Activity {

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SomeScreenViewModel presentationModel = new SomeScreenViewModel();

View rootView = Binders.inflateAndBindWithoutPreInitializingViews(this, R.layout.activity_some_screen, presentationModel);

setContentView(rootView); }

}

Page 16: Антон Валюх - Использование паттерна Mvvm в android

RoboBinding

Достоинства:- двунаправленное связывание- генерация кода- поддержка списков

Недостатки:- проблемы с библиотекой AppCompat- нет поддержки RecyclerView

Page 17: Антон Валюх - Использование паттерна Mvvm в android

ngAndroid

Основан на идеях JavaScript-фреймворка – AngularJS.

Page 18: Антон Валюх - Использование паттерна Mvvm в android

ngAndroid - установка

compile 'com.github.davityle:ngandroid:0.0.4'

Page 19: Антон Валюх - Использование паттерна Mvvm в android

ngAndroid - Model

public class Model { private String mUserFirstName; private String mUserLastName; private String mUserFullName; public String getUserFirstName() { return mUserFirstName; } public String getUserLastName() { return mUserLastName; } public String getUserFullName() { return mUserFullName; }

public void setUserFirstName(String userFirstName){ mUserFirstName = userFirstName; } public void setUserLastName(String userLastname){ mUserLastName = userLastname; } public void setUserFullName(String userFullName) { mUserFullName = userFullName; }}

Page 20: Антон Валюх - Использование паттерна Mvvm в android

ngAndroid - Layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:ng="http://schemas.android.com/apk/res-auto" android:orientation="vertical">

<TextView …… ng:ngModel="model.userFullName" <EditText …… ng:ngModel="model.userFirstName"/> <EditText …… ng:ngModel="model.userLastName"/>

<Button …… ng:ngClick="updateUser()"/> </LinearLayout>

Page 21: Антон Валюх - Использование паттерна Mvvm в android

ngAndroid - Activity

@NgScopepublic class SomeScreenActivity extends Activity {

@NgModel SomeScreenViewModel mScreenViewModel;

private final NgAndroid mNg = NgAndroid.getInstance();

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mNg.setContentView(this, R.layout.activity_some_screen); } protected void updateUser(){ String firstName = mScreenViewModel.getUserFirstName(); String lastName = mScreenViewModel.getUserLastName(); mScreenViewModel.setUserFullName(firstName + " " + lastName); }}

Page 22: Антон Валюх - Использование паттерна Mvvm в android

ngAndroid – а так же….

Поддерживаемые на данный момент angular директивы:

• NgModel• NgClick• NgLongClick• NgChange• NgDisabled• NgInvisible• NgGone• NgBlur• NgFocus

Page 23: Антон Валюх - Использование паттерна Mvvm в android

ngAndroid

Достоинства:- двунаправленное связывание- проект на стадии активной разработки

Недостатки:- нет поддержки списков / RecyclerView- используется рефлексия (обещают перейти на

генерацию кода)- проект на стадии активной разработки, поэтому

достаточно сырой

Page 24: Антон Валюх - Использование паттерна Mvvm в android

Bindroid

Bindroid реализация шаблона MVVM для Android приложений. Представляет собой библиотеку с открытым исходным кодом, основной целью которой является упрощение связывания UI и данных. В ее основе лежит шаблон Наблюдатель (Observer) для работы с моделями а так же набор методов для быстрого связывания этих объектов и интерфейсов пользователя.

Page 25: Антон Валюх - Использование паттерна Mvvm в android

Bindroid - Model

public class SomeScreenViewModel { private TrackableField<String> mUserFirstName = new TrackableField<String>(); private TrackableField<String> mUserLastName = new TrackableField<String>(); private TrackableField<String> mUserFullName = new TrackableField<String>("Here could be your advertising."); public String getUserFirstName() { return mUserFirstName.get(); } public void setUserFirstName(String firstName) { mUserFirstName.set(firstName);} public String getUserLastName() { return mUserLastName.get(); } public void setUserLastName(String lastName) { mUserLastName.set(lastName); } public String getUserFullName() { return mUserFullName.get(); } public void setUserFullName(String fullName) { mUserFullName.set(fullName); }}

Page 26: Антон Валюх - Использование паттерна Mvvm в android

Bindroid - Layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical">

<TextView …… android:id="@+id/text_user_fullname" <EditText …… android:id="@+id/edit_user_firstname"/> <EditText …… android:id="@+id/edit_user_lastname"/>

<Button …… android:onClick="updateUser"/> </LinearLayout>

Page 27: Антон Валюх - Использование паттерна Mvvm в android

Bindroid - Activity

public class SomeScreenActivity extends Activity {

SomeScreenViewModel mScreenViewModel = new SomeScreenViewModel();

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_some_screen); UiBinder.bind(new EditTextTextProperty(this.findViewById( R.id.edit_user_firstname)), mScreenViewModel, "userFirstName", BindingMode.TWO_WAY);

UiBinder.bind(new EditTextTextProperty(this.findViewById( R.id.edit_user_lastname)), mScreenViewModel, "userLastName", BindingMode.TWO_WAY);

UiBinder.bind(new TextViewTextProperty(this.findViewById(R.id.text_user_fullname)), mScreenViewModel, "userFullName", BindingMode.TWO_WAY);

} public void updateUser(View v){ String firstName = mScreenViewModel.getUserFirstName(); String lastName = mScreenViewModel.getUserLastName(); mScreenViewModel.setUserFullName(firstName + " " + lastName); }}

Page 28: Антон Валюх - Использование паттерна Mvvm в android

Bindroid

Достоинства:- двунаправленное связывание- поддерживает работу с библиотекой AppCompat

Недостатки:- нет поддержки генерации кода- нет проверки во временя компиляции- слишком много кода для связывания

Page 29: Антон Валюх - Использование паттерна Mvvm в android

Android Data Binding

- анонсирована на Google IO 15;- создана Google;- пока доступна только как beta.

Page 30: Антон Валюх - Использование паттерна Mvvm в android

Android Data Binding - установка

apply plugin: 'com.android.databinding'

dependencies { classpath 'com.android.tools.build:gradle:1.3.0-beta2' classpath 'com.android.databinding:dataBinder:1.0-rc0'}

Page 31: Антон Валюх - Использование паттерна Mvvm в android

Android Data Binding - Model

public class User { private String mFirstName; private String mLastName; private String mFullName;

public User(String firstName, String lastName) { mFirstName = firstName; mLastName = lastName; } public String getFirstName() { return mUserFirstName; } public String getLastName() { return mLastName; } public String getFullName() { return mFullName; } public void setFirstName(String userFirstName) { mUserFirstName = userFirstName; } public void setLastName(String userLastname){ mUserLastName = userLastname; } public void setFullName(String userFullName) { mUserFullName = userFullName; }

public void updateUser(View v){ mFullName = mFirstName + " " + mLastName; }}

Page 32: Антон Валюх - Использование паттерна Mvvm в android

Android Data Binding - Layout

<layout xmlns:android="http://schemas.android.com/apk/res/android">

<data> <variable name="user" type="com.example.User"/> </data> <LinearLayout ……>

<TextView …… android:text="{user.fullNameName}"/> <EditText …… android:text="@{user.firstName}"/> <EditText …… android:text="@{user.lastName}"/>

<Button …… android:onClick="updateUser"/>

</LinearLayout></layout>

Page 33: Антон Валюх - Использование паттерна Mvvm в android

Android Data Binding - Activity

public class SomeScreenActivity extends Activity {

private User mUser = new User("Anton", "Valiuh");

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);

binding.setUser(mUser); }}

Page 34: Антон Валюх - Использование паттерна Mvvm в android

Android Data Binding – а так же….

• Язык выражений android:text="@{String.format("Hello %s",viewModel.field )}" android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}“

• Импорты <import type="android.view.View" alias="SomeAlias"/>

... android:visibility="@{user.isAdult ? SomeAlias.VISIBLE : SomeAlias.GONE}“

• Поддержка ресурсов android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}“

• Поддержка коллекций android:text="@{list[index]}" android:text="@{map[`firstName`}“

• Возможность создавать кастомные бины.

И много чего еще.

Page 35: Антон Валюх - Использование паттерна Mvvm в android

Android Data Binding

Достоинства:- официальная библиотеки от Google- генерация кода- проверка во время компиляции- простота в использовании и расширении- новый Android стандарт

Недостатки:- нет поддержки двунаправленного связывания (пока еще)- нет поддержки IDE (пока еще)- много ложных ошибок в Android Studio (но все компилируется и запуска)

Page 36: Антон Валюх - Использование паттерна Mvvm в android

Ваши вопросы?

Page 37: Антон Валюх - Использование паттерна Mvvm в android

Благодарю за внимание!