codefest 2013. Никонов Г. — Как мы разрабатываем приложения...

Post on 28-Nov-2014

540 Views

Category:

Documents

6 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

Приложения для Windows Phone

Как мы это делаем

Григорий Никонов,Actis® Wunderman.

Обо мне

На данный момент руковожу разработкой мобильных приложений агентства Actis Wunderman, в котором тружусь с момента появления на свет агентства Actis, позже присоединившегося к сети Wunderman.

Ранее занимался разработкой, созданием и внедрением интернет-проектов.

Наши работы

Мы занимаемся разработкой приложений для ведущих платформ около трех лет. Вот, что мы сделали для Windows Phone:

•КиноПоиск

•Concert.ru

•ЛитРес

Несколько неназываемых проектов скоро должны быть опубликованы, тогда мы их назовём.

Наши работы: КиноПоиск

Наши работы: Concert.ru

Наши работы: ЛитРес

Мы – ленивые

И поэтому создали несколько инструментов, которые позволяют нам экономить время и усилия:

•Фреймворк работы с сущностями и коллекциями

•Фреймворк моделей представлений

•Фреймворк представлений для Windows Phone и других платформ

•T4-генераторы кода

Кроме того, сервер непрерывной интеграции и тесты позволяют нам не заботиться о проблемах внесения изменений в код и координировать совместную работу

Данные

Сценарии использования источников данных в мобильных приложениях, в порядке уменьшения частоты использования:

•Получить коллекцию заголовков данных

•Получить конкретную сущность

•Выполнить единичное действие с источником данных

•Отправить изменённую сущность

«Мобильность» платформы накладывает некоторые ограничения на возможность и целесообразность передачи больших объёмов данных

Данные

Данные можно разделить на две категории – сущности и коллекции сущностей

И сущности и коллекции сущностей бывают идентифицируемые и неидентифицируемые

Сущности

События изменения свойств:

ObservableObject

Обновление и клонирование:

XObject, XObject<T>

Ключи для идентификации объектов:

XKey

Коллекции

Интеллектуальное обновление:

XCollection<T>

Применение фильтров:

XFilteredCollection<T>

Объединение и разделение:

XCombinedCollection<T>, XSubRangeCollection<T>

Кэширование

Запросы как идентификация коллекций:

XQuery<T>

Применение фильтров:

XFilteredCollection<T>

Собственно кэш:

XCache<T>

Пример: Свойства

class Person : XObject{

string _name;XCollection<Person> _children;

public string Name{

get { return _name; }set { SetProperty( ref _name, value, “Name” ); }

}

public XCollection<Person> Children{

get { return _children; }set { SetProperty( ref _name, value,

“Children” ); }}

}

Пример: ProcessCopy

class Person : XObject{

protected override void ProcessCopy(XObject source, bool cloning, bool deepCloning )

{base.ProcessCopy( source, cloning,

deepCloning );

Person other = (Person) source;

_name = other._name;

ProcessCopyProperty(ref _children, other._children,cloning, deepCloning );

}}

Пример: Клонирование

Person person = new Person{

Name = “John”,Children = new XCollection<Person>

{new Person { Name = “Bob” }

}};

Person softClone = (Person) person.Clone( false );Person deepClone = (Person) person.Clone( true );

person.Children[0].Name = “Mary”;

softClone.Children[0].Name // “Mary”deepClone.Children[0].Name // “Bob”

Пример: Обновление

Person person1 = new Person { Name = “John” }Person person2 = new Person { Name = “Mary” }

person1.Update( person2 );

person1.Name // “Mary”

XCollection<Person> l1 = new XCollection<Person>() { … };XCollection<Person> l2 = new XCollection<Person>() { … };

var result = l1.Update( l2 );

Пример: Коллекции

XCollection<Person> l1 = new XCollection<Person>() { … };XCollection<Person> l2 = new XCollection<Person>() { … };

var softClone = l1.Clone( false );var deepClone = l1.Clone( true );

var result = l1.Update( l2 );

Пример: Хитрые коллекции

XCollection<Person> studentsOfClassA = …;XCollection<Person> studentsOfClassB = …;

var firstThreeStudentsOfClassA =new XSubRangeCollection( studentsOfClassA, 0, 3 );

var firstTwoStudentsOfClassB =new XSubRangeCollection( studentsOfClassB, 0, 2 );

var topStudents =new XCombinedCollection(

firstThreeStudentsOfClassA,firstTwoStudentsOfClassB );

Генератор сущностей

Поддержка XML/JSON сериализации

Демонстрация

Сгенерированные классы, содержащие ключевые элементы, необходимые для эффективной работы с данными:

•Правильное обновление данных

•Правильное клонирование данных

•Выборка с помощью ключей в коллекциях и кэше

Модели представлений

Предназначены для получения и преобразования данных, необходимых представлениям, а также для выполнения других действий над этими данными.

Наиболее частые операции в мобильных приложениях – загрузка данных (списки или отдельные сущности) для представления их пользователю.

Работа с источниками данных должна быть асинхронной – нельзя блокировать поток пользовательского интерфейса.

Необходимо учитывать возможность досрочного прекращения выполняемых операций – по разным причинам.

Сессии

Всё «управляемое» общение модели (модели представления) с внешним миром происходит в рамках сессии

Сессия содержит параметры, необходимые для доступа к данным

Сессия содержит жетон, используемый для прекращения асинхронных задач (CancellationToken)

Обработкой сессии занимается модель

Работа с сессией

Создание

var session = CreateSession().AddParameter( “userName”, “John” ).AddParameter( “age”, 48 );

Доступ к параметрам

var userName = session.Parameters.Get<string>( “userName” );var age = session.Parameters.Get<int>( “age” );var sex = session.Parameters.Get<string>( “sex”, “male” );

Обработка

await viewModel.Load( session );

Откуда она знает, что делать?

Виртуальные методы

ShouldLoadSessionLoadSession

Части

RegisterPartstring part,Func<Session, Task> processor,Func<Session, bool> checker,bool loadIfNoPartsSpecified

Типичная модель

Конструктор

Получает сервисы через DI

Регистрирует части

Создает команды

Методы обработки частей

Проверяют необходимость обработки сессии

Осуществляют доступ/обновление данных

Модель сущности

Использует расширенную сессию, которая включает в себя ключ, идентифицирующий объект: EntitySession

Регистрирует методы для части, связанной с обработкой сущности: ShouldLoadEntity и LoadEntity.

Объявляет свойство Entity

Типичная модель сущности

Конструктор

Получает сервисы

Создает команды

Метод LoadEntity

Загружает данные из внешнего источника или из кэша

Присваивает значение свойству Entity

INavigationService

Один из самых важных сервисов, доступных моделям

Определяет независимый от платформы способ навигации между видами

ns.Navigate( “PersonView”, Parameters.Create( “Id”, 1 ) );

Позволяет создавать и использовать команды навигации:

ViewDetails = new NavigationCommand(ns,“DetailedView” );

PersonSelected = new NavigationCommand<Person>(ns,“PersonView”,person => person.KeyParameter() );

Другие сервисы

IDataExchangeService

Информирование об обмене данными

IViewModelExceptionHandlingServiceIExceptionHandlingService

Унифицированная обработка исключений

Представления

PhoneApplication – наследник Application

Регистрация сервисов

Обработка ошибок уровня приложения

Page

Управление жизненным циклом

OnPageCreated, OnPageDestroyed,OnPageAsleep, OnPageAwaken, OnPageResurrected

Доступ к параметрам

ViewParameters

Контекст для связывания данных

CreateDataContext

Атрибутирование для навигации

[View( “UserView” )][ViewParameter( “userName”,

typeof( string ) )]

ViewModelPage<TViewModel>

Страница с созданной моделью

Начальная загрузка данных

CreateDataSession, CreateDataSessionAsyncOnDataLoadComplete, OnDataLoadFailed

Обработка нештатных ситуаций (FAS)

Управление областью жизни модели

Связывание данных в XAML

<TextBlock Text=“{Binding ViewModel.Title}”/>

EntityPage

Автоматически выбирает ключ из параметров и создает сессию для загрузки сущности.

Но это еще не всё!

Генератор классов-заглушек и частичных классов-представлений:

<View Name=“MainView”/><View Name=“FeedChannelView” Entity=“FeedChannel”/>

Во многих случаях файл View.xaml.cs не нужен, всё делается автомагически

Генератор константных имен представлений и параметров, а также методов для создания параметров навигации

Но и это еще не всё!

Декораторы страниц используются для выполнения однообразных действий со страницами, например для показа сообщений об ошибках, исчезновении сетевого подключения и т.п.

Встроенный механизм обработки страниц, для которых нужна аутентификация – параметр RequiresAuthentication атрибута [View()]

Вопросы?

Григорий Никонов,Actis® Wunderman

gregoryn@actis.ru(495) 234-0009http://www.actis.ru/

top related