Спасибо, что скачали книгу в бесплатной электронной библиотеке BooksCafe.Net
Все книги автора
Эта же книга в других форматах
Приятного чтения!
- Об авторе
- Предисловие
- Благодарности
- От издательства
- ГЛАВА 1
- ГЛАВА 2
- ГЛАВА 3
- Введение
- Как проектировалась .NET Compact Framework
- .NET Compact Framework как подмножество платформы для настольных компьютеров
- Управляемый код и собственный код
- Исполнительный механизм
- Библиотеки управляемого кода
- Вынесение полезной отладочной и проектной информации в необязательные компоненты
- Средства подключения к базам данных SQL СЕ/SQL
- Элементы, отсутствующие в первой версии .NET Compact Framework
- Как запускается и выполняется код
- Управление памятью и сборка мусора
- Резюме
- ГЛАВА 4
- Введение
- Трудности постоянного и временного характера, с которыми приходится сталкиваться при разработке программного обеспечения
- Разработка программ является итеративным процессом, который, тем не менее, также должен подчиняться определенным правилам
- Детали ничего не стоят, если общая картина неверна
- Решайте задачи в определенной очередности; не бойтесь при необходимости возвращаться назад
- Шаг 0: прежде чем приступать к работе, определите сферу применения вашего приложения
- Шаг 1: начните с анализа проблем производительности и никогда не упускайте их из виду
- Шаг 2: спроектируйте подходящий пользовательский интерфейс
- Шаг 3: выберите подходящие модели данных и памяти
- Шаг 4: выберите подходящую модель коммуникации и модель ввода-вывода
- При необходимости вернитесь к шагам 0, 1, 2 и 3
- Шаг 5: пакетирование приложения для его установки
- Резюме
- ГЛАВА 5
- ГЛАВА 6
- ГЛАВА 7
- Введение
- Важность планомерного подхода
- Определите обязательные характеристики сценариев рабочих сеансов пользователя
- Определите контрольные точки разработки, критерии завершения которых ориентированы на достижение высокой производительности
- Время от времени критически пересматривайте написанный код
- Определите модель памяти для вашего приложения
- Как можно чаще контролируйте показатели, характеризующие работу вашего приложения
- Программа для измерения характеристик кода
- Выполняйте тестирование с использованием реальных объемов данных
- Тестируйте приложения в предельных режимах
- Своевременно предпринимайте меры по поддержанию высокой производительности приложения (со временем ситуация будет только ухудшаться!)
- Определение задач, решение которых необходимо для достижения высокой производительности
- Накладные расходы по обработке исключений
- Резюме
- ГЛАВА 8
- Определение модели памяти для приложения
- Управление памятью на макроскопическом "уровне приложения"
- Управление памятью на микроскопическом "уровне алгоритма"
- Пишите аккуратные алгоритмы: не сорите!
- Пишите экономные алгоритмы: разумно расходуйте память и повторно используйте объекты
- Повторно используйте размещенные в памяти объекты при любом удобном случае
- Избегайте размещения в памяти лишних объектов
- Анализ описанных выше шагов последовательной оптимизации
- Уделяйте особое внимание тому, как используются строки в ваших алгоритмах
- Резюме
- ГЛАВА 9
- Введение: когда и как следует использовать многопоточное выполнение
- Многозадачность и многопоточность в современных операционных системах
- В каких случаях следует использовать фоновые потоки
- Рекомендации по использованию потоков в мобильных приложениях
- Назначайте обслуживание пользовательского интерфейса основному потоку
- Стремитесь поддерживать способность пользовательского интерфейса к отклику на высоком уровне
- Начинайте с создания однопоточного приложения
- В простых случаях пытайтесь обойтись без многопоточного выполнения, используя курсоры ожидания
- Рассмотрите возможность использования фоновых потоков, если выполнение задачи требует длительного или неопределенного времени
- Максимально упрощайте многопоточный код и документируйте его для повышения надежности
- Рассмотрите возможность предварительного выполнения некоторой работы, осуществляемой кодом
- Пример использования фонового потока для выполнения отдельной задачи
- Потоки и пользовательский интерфейс
- Резюме
- ГЛАВА 10
- Введение: работа с XML
- XML или не XML?
- Сравнение XML с другими текстовыми форматами
- Различные способы работы с XML
- Простой пример, иллюстрирующий применение модели XML DOM и однонаправленного чтения-записи XML-документов
- Повышение производительности приложения перекладыванием работы на другие программы
- Резюме
- ГЛАВА 11
- Введение
- Стратегии проектирования высокопроизводительных пользовательских интерфейсов
- Использование встроенных средств повышения производительности
- Выполняйте тесты с использованием реальных объемов данных, которые будут отображаться в вашем приложении
- Отсроченный выбор — это благо! Откладывайте, откладывайте, откладывайте…
- Будьте внимательны, когда работаете с кодом, управляемым событиями
- Не допускайте, чтобы пользователю оставалось лишь догадываться о ходе выполнения приложения
- Выбор подходящих форматов и размеров растровых изображений
- Стратегии проектирования высокопроизводительного графического кода
- Способы интеграции графики с кодом пользовательского интерфейса
- Где рисовать — на экране или вне экрана?
- Определите собственный процесс визуализации
- Отсрочка — зло, используйте предварительные вычисления
- Кэшируйте часто используемые ресурсы
- Старайтесь избегать распределения памяти для объектов при выполнении повторяющихся или непрерывно продолжающихся операций рисования
- Резюме
- ГЛАВА 12
- Итоговые замечания по поводу производительности
- Производительность и управление памятью
- Производительность и многопоточное выполнение
- Производительность и уровни абстракции API-интерфейсов
- Связь производительности с организацией пользовательского интерфейса и работы с графикой
- Старайтесь постоянно информировать пользователя о ходе выполнения приложения
- Заключительные замечания и рекомендации
- ГЛАВА 13
- Мыслите категориями устройств!
- Один размер для всего не годится
- Одна рука или две?
- Возрастание роли навигационных средств при уменьшении экранного пространства
- Списки или вкладки?
- Пользовательские интерфейсы мобильных телефонов и важность соблюдения единообразия в использовании клавиш
- Сенсорные экраны и важность использования крупных кнопок
- Оптимизируйте ввод обычных данных
- Убедитесь в том, что для механизмов автоматизированного ввода предусмотрены параллельные механизмы ввода вручную
- Тестирование на эмуляторах и физических устройствах
- Проектируйте код пользовательского интерфейса мобильного приложения таким образом, чтобы его можно было легко тестировать и модифицировать
- Разработка улучшенных пользовательских интерфейсов средствами .NET Compact Framework
- Резюме
- ГЛАВА 14
- ГЛАВА 15
- Введение в технологии связи с помощью мобильных приложений
- Написание кодов программ для работы с мобильными сетями
- Не допускайте того, чтобы работа приложения всецело зависела от возможности подключения к сети
- Не допускайте того, чтобы поток пользовательского интерфейса блокировался на длительное время
- Работайте на самом высоком уровне абстракции, который соответствует вашим потребностям
- Всегда исходите из того, что связь может быть нарушена в любой момент
- Имитация сбоев связи с целью тестирования отказоустойчивости приложения
- Информируйте пользователя о ходе выполнения процесса синхронизации данных
- Исходите из того, что скорость передачи данных и длительность задержек могут меняться
- Внедряйте необходимые коммуникационные средства безопасности уже на ранних стадиях проектирования приложения
- Передача данных и выбор сети
- Принудительная перекачка информации на устройства
- Web-службы
- Резюме
- ГЛАВА 16
- ГЛАВА 17
- ПРИЛОЖЕНИЕ А
- ПРИЛОЖЕНИЕ Б
- Почему именно VB.NET и С#?
- Примеры к главе 5 (конечные автоматы)
- Примеры к главе 7 (производительность: введение)
- Примеры к главе 8 (производительность и память)
- Примеры к главе 9 (производительность и многопоточное выполнение)
- Примеры к главе 10 (производительность и XML)
- Примеры к главе 11 (производительность и графика)
- Примеры к главе 13 (проектирование пользовательского интерфейса)
- Примеры к главе 14 (данные)
- Примеры к главе 15 (передача данных)
- Сноски
Эту книгу я посвящаю своим учителям, как формальным, так и неформальным, но в первую очередь — родителям, Эйр (Aire) и Уильяму Салмре (William Salmre). Если мне и удалось взглянуть на кое-что по-новому и изложить свои мысли с пользой для дела, так это только благодаря доброте и терпению тех, кто не пожалел времени на то, чтобы провести меня вверх по склону горы и указать правильное направление. Спасибо вам всем.
Благодарности издательства
Издательский дом "Вильямс" благодарит Ерофеева Сергея и Кущенко Сергея за большой вклад в подготовку издания книги.
"Несмотря на сугубо практическую направленность этой книги, она не только помогает вам повысить свой профессиональный уровень как программиста, но и стимулирует творческое воображение и пробуждает желание сразу же взяться за создание нового, доселе неизвестного программного обеспечения для мобильных устройств."Когда эта книга появится перед читателями, они смогут сами оценить, насколько мне удалось приблизиться к реализации этой дерзкой мечты.
"Скажите, пожалуйста, как мне выйти отсюда?"
"Все зависит от того, куда тебе надо выйти ", — ответил Кот.Льюис Кэрролл, Алиса в стране чудес(Encarta 2004, Quotations)
НА ЗАМЕТКУТехнология компании Microsoft, предназначенная для разработки Web-приложений, носит название ASP.NET (Active Server Pages .NET). ASP.NET предлагает "мобильные элементы управления" ASP.NET, предназначенные для мобильных устройств. Visual Studio .NET 2003 предоставляет пользователям возможность создавать мобильные ASP.NET-приложения. На рис. 1.1 показано диалоговое окно Visual Studio для создания нового проекта ASP.NET Mobile Web Application.
Существует множество технологий, которые могут быть использованы при разработке Web-приложений, ориентированных на мобильные устройства. Кроме элементов управления технологии Microsoft ASP.NET для мобильных устройств, существуют и другие Web-технологии, поддерживающие разработку мобильных приложений. Для этих технологий существуют свои стратегии создания мобильных Web-приложений. Если вы уже привыкли работать с какой-то определенной Web-технологией, то вполне вероятно, что доступно и соответствующее расширение этой технологии, ориентированное на мобильные устройства.
Инструменты разработки на С++ для мобильных устройств
Во время написания данной книги компания Microsoft предлагала свободно распространяемый инструментальный набор средств для разработчиков устройств на языках C/C++ под названием eVC++. eVC++ — это аббревиатура от Embedded Visual С++. Этот продукт, который можно бесплатно загрузить с Web-сайта Microsoft, позволяет разработчикам создавать собственный код на языках C/C++ для устройств, работающих под управлением операционных систем Windows СЕ, Pocket PC и Microsoft Windows Mobile 2003 Software for Smartphone (ради краткости при дальнейших ссылках на последний из названных программных продуктов я буду использовать его сокращенное название — Microsoft Smartphone). В основу этой среды разработки была положена среда Visual Studio 6.0 С++, являющаяся предшественницей Visual Studio .NET. Согласно планам Microsoft последующие версии Visual Studio .NET (начиная с выпуска "Whidbey" в 2005 году) будут обеспечивать поддержку разработки собственных кодов C/C++ для устройств, в результате произойдет слияние обеих указанных сред в одну среду.
При разработке приложений для Windows ХР Embedded можно использовать ту же среду Visual Studio .NET, что и для настольных компьютеров и серверов.
Созданием сред для разработки приложений в собственных кодах занимаются и другие компании, в том числе MetroWorks и WindRiver. Существует также множество инструментальных средств командной строки, часть которых является бесплатной, тогда как за остальные надо платить. Типичные продукты поставляются в виде отдельных пакетов, предназначенных для различных целевых сред. Так, существуют отдельные среды разработки для Windows СЕ, Symbian Operating System, а также для LINUX, FreeBSD, Palm OS и так далее.
Инструменты разработки приложений для мобильных устройств характеризуются различными уровнями поддержки стандартов ANSI C/C++. Если вы хотите обеспечить переносимость кода или библиотек, придерживайтесь следующих рекомендаций:
• Тщательно выясняйте уровень поддержки стандартов, который обеспечивается используемыми вами компиляторами, обращая особое внимание на такие тонкие вещи, как структурная обработка исключений. Различные компиляторы предоставляют различные уровни поддержки таких, например, средств, как обработка исключений, а возможно, и таких вещей, как операции с вещественными числами или стандартная битовая ширина целых чисел.
• Обзаведитесь хорошим руководством по программированию, содержащим подробные описания всех средств компилятора и библиотек программ, которые вы будете использовать в своих приложениях. Убедитесь в том, что эти средства и библиотеки поддерживаются всеми компиляторами, которые вы планируете использовать для различных целевых процессоров или операционных систем.
• Рассмотрите возможность использования "наименьшего общего знаменателя" для всей совокупности возможных средств, например, ограничьтесь применением только языка С (в смысле — откажитесь от С++) или же используйте лишь какое-то отдельное простое подмножество средств С++. Благодаря этому вы сможете быть уверены в том, что присутствие и поддержка выбранных вами языковых средств будут в равной степени обеспечиваться широким кругом компиляторов.
• Как можно чаще и начиная уже с ранних стадий разработки, тестируйте приложение на каждом компиляторе/платформе, для работы с которыми оно запланировано. Качество кода, обеспечиваемое различными компиляторами C/C++, не обязательно одинаково, и некоторые их них могут содержать ошибки, которые могут быть выявлены только в процессе выполнения или отладки программы. В целом, компиляторы C/C++ для мобильных устройств используются далеко не так широко, как компиляторы для настольных компьютеров и серверов, работающих на процессорах семейства х86. Как следствие, число разработчиков, рискующих испытать свои силы на поприще генерации кодов для них, не так уж и велико. Как показала практика, чем менее широко используется какой-либо программный продукт, тем больше скрытых ошибок в нем содержится и тем больше ограничений ему свойственно. Не утруждая себя частым тестированием кодов на протяжении всего периода разработки с использованием для этого всей совокупности компиляторов и платформ, для выполнения на которых предназначено приложение, вы заведомо готовите для себя неприятные сюрпризы в будущем!
• Тщательно ознакомьтесь с описанными в соответствующих лицензионных соглашениях ограничениями, касающимися использования применяемых вами компиляторов библиотек и инструментальных средств. Если вы создаете приложение, предназначенное для коммерческого использования, изучите лицензионные соглашения всех без исключения компиляторов, библиотек исходных кодов и библиотек времени выполнения, а также средств компоновки, которые вами используются. Каким бы утомительным ни было чтение этих документов, лучше быть хорошо осведомленным об этих ограничениях уже с самого начала, чем переделывать всю работу или переходить на другой компилятор на более поздних стадиях производственного цикла. Смена компилятора может казаться легкой, но повозиться вам придется немало, и вдобавок это отнимет много времени. Все сказанное выше справедливо в отношении любого программного обеспечения разработчика, но в отношении средств разработки приложений для мобильных устройств это справедливо вдвойне из-за огромного разнообразия специализированных инструментальных средств, сопровождаемых лицензионными соглашениями самых различных видов, включая EULA (end-user license agreement — лицензионное соглашение с конечным пользователем), ограничения, касающиеся лицензионных платежей, ограничения, касающиеся защиты прав на интеллектуальную собственность, например, GPL (general public license — общедоступная лицензия), LGPL (lesser general public license — общедоступная лицензия с ограничениями), FreeBSD и тому подобное.
Caveat emptor[1]; Пусть программист будет бдителен! Никто никого не запугивает; это только призыв к тому, чтобы, делая свой выбор, вы поступали осмотрительно.
Разработка приложений для мобильных устройств с использованием собственных кодов не является чем-то необычным и вполне может соответствовать вашим потребностям, но решение об этом вы должны принимать осознанно, понимая причины, побуждающие вас к такому выбору. Если при создании мобильного приложения вы решаете прибегнуть к написанию собственных кодов, убедитесь в том, что для этого имеются веские причины, и не пожалейте времени на то, чтобы заранее продумать, какие возможности компиляторов C/C++ вам могут для этого понадобиться и какие усилия вам придется приложить для преодоления возникающих при этом проблем разработки и отладки. Разрабатывать мобильные приложения на основе собственного кода намного сложнее, чем для настольных компьютеров или серверов. Чтобы добиться в этом успеха, вы должны быть вооружены ясным пониманием целей и знаниями инструментальных средств, которые собираетесь для этого использовать.
Плавающая запятая: что собой представляет число?
Исполнительный механизм .NET Compact Framework и библиотеки времени выполнения имеют встроенную поддержку операций с плавающей запятой. Это следует особо подчеркнуть, так как не каждая среда выполнения мобильных устройств может похвастаться этим. Понимание этого играет очень важную роль, если до того, как приступить к работе с мобильными устройствами, вы занимались разработкой программ для настольных компьютеров или серверов.
Например, для Java J2ME CLDC (Common Limited Device Configuration) версии 1.0 поддержка операций с плавающей запятой не требуется, чего нельзя сказать о версии J2ME CLDC 1.1. Java MIDP 2.0 (Mobile Information Device Profile) требует только поддержки CLDC 1.0. Если вы ориентируетесь на мобильные устройства со средой выполнения J2ME, выясните, какую версию CLDC поддерживает эта среда.
Большинство многофункциональных мобильных приложений в той или иной форме требуют выполнения вычислений с десятичными числами. Хотя и существуют способы имитации некоторых операций с плавающей запятой путем выполнения целочисленных операций с фиксированной запятой, они могут делать вычисления громоздкими и не обеспечивают достаточной гибкости, необходимой для удовлетворения повышенных запросов.
Определяя требования к среде выполнения своего мобильного приложения, обратите особое внимание на наличие поддержки математических функций, причем не только тех, которые предназначены для выполнения операций с плавающей точкой, но и тех, которые используются для обработки величин, представляющих валюту, дату и время. Нелишне также удостовериться в том, что обеспечивается поддержка и таких более сложных библиотечных функций, как тригонометрические и экспоненциальные функции. В .NET Compact Framework все эти средства поддерживаются.
Преимуществом сред выполнения, в которых поддержка операций с плавающей запятой отсутствует, является то, что они занимают меньше места в памяти и способны выполняться в более простом окружении. Их большим недостатком является ограниченность функциональных возможностей, предлагаемых разработчикам приложений. Тщательно проанализируйте свои потребности и выберите среду выполнения и целевые устройства, которые обладают всеми необходимыми для вас показателями функциональности и гибкости.
Интеллект – это дар быстрого проникновения в суть вещей, который следует отличать от обычных способностей, означающих просто умение действовать со знанием дела по отношению к тому, суть чего уже понята.А.Н. Уайтхед (А.N. Whitehead, 1861-1947), английский математик и философ(Encarta 2004, Quotations)
Более пристальный взгляд на мобильные Web-браузеры
Интересным примером многофункциональных клиентских приложений, выполняющихся на мобильных устройствах, являются мобильные Web-браузеры. Целесообразно сравнить между собой мобильные Web-браузеры и их настольные аналоги, чтобы выяснить, в чем состоит суть различий между ними. Благодаря этому мы получим в свое распоряжение неплохие метафоры для анализа того, как будут вести себя приложения для настольных компьютеров при их переносе на мобильные устройства и какие изменения необходимо в них внести, чтобы работать с ними в мобильных условиях было действительно удобно
В настоящее время Internet-браузеры предлагаются многими мобильными устройствами, однако по способу их использования браузеры этого типа отличаются от их аналогов, устанавливаемых на настольных компьютерах.
Несмотря на то что в их основе лежит одна и та же технология (оба типа браузеров обеспечивают визуализацию HTML-разметки при отображении документов), способы взаимодействия с ними пользователей заметно различаются между собой. Браузеры настольных компьютеров предназначены для доступа к как можно более широкому кругу Web-сайтов, а также для загрузки и отображения сложных документов. Задача же мобильных Internet-браузеров состоит в том, чтобы обеспечивать доступ к Web-сайтам, ориентированным на мобильные устройства, и загрузку документов с одновременным извлечением из них лишь наиболее существенной информации. Типичные мобильные браузеры работают одним из двух способов они либо 1) загружают содержимое, предназначенное специально для мобильных устройств, которое отличается упрощенными схемами компоновки страниц, меньшими размерами фотографий и изображений и приспособлено для просмотра в небольших окнах, либо 2) загружают обычное Web- содержимое, но пытаются вычленить из него и отобразить для пользователя лишь наиболее существенную его часть.
Создание оптимальных условий для работы в Web на мобильных устройствах требует координации взаимодействия устройства с сервером
Следует отметить, что извлечение лишь наиболее существенной части содержимого типичных HTML-страниц с сохранением возможности приемлемого представления документов на мобильных устройствах является сложной проблемой. Учитывая огромное разнообразие возможных схем компоновки страниц с помощью HTML, а также тот факт, что наряду с основной информацией страницы заполняются второстепенным содержимым и рекламой, очень трудно определить, какая именно информация является наиболее существенной, и разместить эту информацию на небольшом экране мобильного устройства. Вместо того чтобы возлагать всю нагрузку на устройство, очень часто можно добиться лучших результатов, перекладывая решение большинства проблем на сервер. Часто такие популярные Web-сайты, как MSNBC или ВВС, предлагают отдельные версии содержимого, рассчитанные на мобильные устройства. Для решения этой задачи на двух упомянутых сайтах используются различные подходы, каждый из которых заслуживает внимания:
• http://www.msnbc.com/news/MobileChannel/mmc.asp. Этот Web-сайт автоматически подстраивает свой ответ под возможности браузера, выполняющего запрос. Результаты, получаемые при доступе к Web-сайту с обычного браузера настольного компьютера и браузера мобильного устройства, значительно различаются между собой.
• http://news.bbc.co.uk/text_only.stm. На этом сайте ВВС для представления Web-содержимого используются изображения с низким разрешением и ограниченное форматирование, что обеспечивает возможность эффективного просмотра содержимого на мобильных устройствах.
Задача отображения HTML-содержимого на мобильных устройствах может быть решена гораздо эффективнее, если сервер принимает участие в решении проблем, испытываемых устройством, и предоставляет упрощенное представление данных. Преодоление проблем, с которыми приходится сталкиваться приложениям на мобильных устройствах, за счет создания дополнительных специализированных служб на сервере — неплохая идея не только для Web-приложений, но и вообще для всех приложений, которым требуется доступ к данным, находящимся на сервере. Если для упрощения проблем разработки приложений, с которыми приходится сталкиваться в случае мобильных устройств, некоторую часть работы можно переложить на сервер, то в большинстве случаев этим надо обязательно воспользоваться.
Кроме того, в отличие от адресной строки браузеров настольных компьютеров, которая всегда на виду и используется довольно часто, адресная строка браузеров мобильных устройств во многих случаях остается скрытой, и ею пользуются гораздо реже. Из-за небольших размеров экрана и ограниченных возможностей механизма ввода, а также вследствие того, что на ввод URL-адресов уходит больше времени, а сама адресная строка занимает драгоценное экранное пространство, в случае мобильных устройств она менее употребительна. Добавьте к этому также тот факт, что значительную часть обычного Web-содержимого воспроизвести на мобильных устройствах приемлемым образом не удается. Все эти факторы заметно сужают возможности устройств в отношении полностью свободной навигации по адресам Web-сайтов.
Ничто из вышесказанного не должно создавать у вас впечатления, будто разработка Web-приложений для мобильных устройств и бесполезна, и неинтересна — это абсолютно не так! Существует немало отличных мобильных Web-приложений, предлагающих пользователю множество удобных возможностей при доступе к Web-ресурсам. В настоящее время, когда появились такие технологии разработки Web-приложений на стороне сервера, как ASP.NET Mobile Controls. Web-разработчикам стало легче создавать "мобильные представления" уже существующего Web-содержимого. Средства Web-просмотра для мобильных приложений всегда будут "приложениями-приманками", однако их эксклюзивность отличается от той, которая свойственна их аналогам для настольных компьютеров.
Т9 — прекрасный пример остроумного технического решения, позволяющего преодолеть ограничения, свойственные мобильным устройствам
Редактор T9 позволяет быстро вводить текст на мобильных телефонах, имеющих стандартную 12-клавишную клавиатуру. До появления T9 пользователи, вводя текстовые предложения, должны были старательно нажимать на клавиши с цифрами от 1 до 9 вплоть до 4 раз, чтобы добиться ввода нужной буквы. В табл. 2.1 указаны суммарные количества нажатий, необходимые для ввода простого текста "text message" до и после появления T9.
Двенадцать клавиатурных нажатий вместо двадцати двух соответствуют 40-процентной экономии количества нажатий. На практике T9 позволяет сэкономить еще больше времени. Поскольку вам больше не надо выдерживать длительность пауз, подтверждающих конкретный ввод в тех случаях, когда вы хотите ввести две последовательные буквы, представленные одной и той же клавишей.
Например, как r, так и s представлены на клавиатуре клавишей с цифрой 7. Если вы хотите ввести слово cars, вам придется выждать одну секунду после ввода r, чтобы программное обеспечение распознало окончание ввода этой буквы и переместило точку вставки в позицию следующей буквы, которая будет вводиться. Каждый, кто хотя бы однажды попробовал пользоваться обоими способами ввода в течение нескольких дней, уже никогда не вернется к старому способу, существовавшему до появления редактора T9.
Как это все работает? Статистика! Когда вы нажимаете клавиши 8, 3 и 9, программное обеспечение просматривает свой словарь и определяет, что единственными наиболее вероятными словами, которые вы могли вводить, являются слова vex и text, в связи с чем вам и предлагаются оба эти варианта. Когда вы нажимаете последнюю клавишу 8, программное обеспечение обнаруживает, что единственным из хранящихся в его словаре словом, согласующимся с набранной комбинацией, является слово text, которое вам и предлагается. Поддерживая словарь, содержащий слова и ключевые комбинации на вашем национальном языке, программное обеспечение может значительно повысить скорость написания коротких сообщений. Если вам необходимо выйти за пределы словарного запаса словаря, вы можете дополнить его вводом "неизвестных" слов, используя старый механизм ввода.
Годится ли такой способ для написания романа "Война и мир" с помощью мобильного телефона? Разумеется, нет, но он прекрасно подходит для ввода предложения "Только что закончил чтение романа 'Война и мир' — очень длинная книга!" и отправки его своему другу.
Редактор Т9 отлично иллюстрирует идею "думающего телефона" и способы решения проблем, которые проявляются при вводе типичной информации в мобильные устройства. Эта конструктивная идея учит многому. Ключевой посыл можно было бы сформулировать так: "Не бросайтесь решать общие проблемы; решайте конкретные проблемы, с которыми сталкиваются ваши пользователи, а далее — оптимизируйте, оптимизируйте и еще раз оптимизируйте!"
Требуемая буква | Нажатия клавиш до появления Т9 | Нажатия клавиш после появления Т9 |
---|---|---|
Т | 8, = t | 8, = t |
Е | 3,3, = d,e | 3, = е |
X | 9,9, = w,x | 9, = х |
T | 8, = t | 8, = t |
<пробел> | 1, = пробел | 1, = пробел |
M | 6, = m | 6, = m |
E | 3,3 = d,e | 3, = e |
S | 7,7,7,7, = p,q,r,s | 7, = s |
S | 7,7,7,7, = p,q,r,s | 7, = s |
А | 2, = а | 2, = а |
G | 4, = g | 4, = g |
E | 3,3 = d,e | 3, = e |
Общее количество нажатий | 22 | 12 |
Некоторые простые подсчеты, касающиеся размеров памяти
Объем ОЗУ современных многофункциональных мобильных устройств достигает 64 Мбайт. ОЗУ такого объема часто разделяются на программное ОЗУ и виртуальную файловую систему. Предположим, что 32 Мбайт такого ОЗУ приходится на файловую систему, предназначенную для хранения всех долговременных данных, с которыми вы работаете (такими данными могут быть фотографии, документы, музыка или другая информация). При этом в совместном распоряжении операционной системы и приложений остается 32 Мбайт. Допустим, что одновременно выполняются пять приложений (не столь уж редкая ситуация), каждое из которых использует примерно одинаковый объем ОЗУ, а сама операционная система использует те же ресурсы, что и отдельное приложение. В результате этого на каждое приложение приходится примерно 5-6 Мбайт ОЗУ. Хотя этот объем памяти и значителен, он далеко не бесконечен. Несколько крупных цифровых фотографий, перенесенных в память, израсходуют большую часть ОЗУ. Многие мобильные устройства располагают значительно меньшими рабочими объемами ОЗУ, а количество одновременно запускаемых приложений в реальных случаях может превышать то, которое мы использовали выше в качестве примера. Доступный на устройстве объем ОЗУ устанавливает абсолютный предел, превышение которого невозможно ни при каких обстоятельствах. Если имеющаяся физическая память устройства истощена, объекты не будут перемещаться в страничный файл, как это было бы в случае настольных компьютеров. Вероятнее всего, приложение израсходует всю доступную память и закончится аварийно.
Несколько мегабайт доступного рабочего пространства — это не так уж плохо при условии их эффективного использования, аналогично тому, как однокомнатная квартира на Манхэттене способна предоставить довольно много свободного места, если не забивать ее разным хламом. Стоит только перестать контролировать заполнение квартиры вещами, как очень быстро будет достигнуто критическое состояние, при котором в комнату больше ничего нельзя будет внести, и в ней останется ровно столько места, чтобы его едва хватало для перемещения в пределах квартиры. Будучи набитой лишними вещами, ваша комната станет бесполезной. Аналогичные соображения применимы и в случае мобильных устройств.
Проектирование — это сознательные усилия, направленные на установление разумного порядка.Виктор Папанек (Victor Papanek) (американец австрийского происхождения, дизайнер, преподаватель, писатель. 1925-1998)(Encarta 2004, Quotations)
Чем объясняется присвоение первому выпуску NET Compact Framework номера версии 1.1, а не 1.0?
Дотошный читатель мог заметить, что при ссылках на первый выпуск .NET Compact Framework в качестве номера версии используется не номер 1.0, а номер 1.1. На то имеются свои основания.
Первый выпуск .NET Compact Framework проектировался так, чтобы обеспечивалась его совместимость с версией 1.1 .NET Framework для настольных компьютеров и серверов, и предполагался к поставке одновременно с ней. Версия 1.0 .NET Framework поставлялась в 2002 году вместе с Visual Studio.NET 2002. Версия 1.1 .NET Framework и NET Compact Framework поставлялись вместе с Visual Studio .NET 2003. В согласии со смыслом номеров версий, номер 1.1 соответствует младшему выпуску продукта, функциональность которого обновлена по сравнению с версией 1.0.
По причинам, обусловленным совместимостью версий на уровне двоичных кодов и рыночными соображениями, было решено синхронизировать номера версий .NET Framework и .NET Compact Framework. Таким образом, версию 1.1 .NET Compact Framework можно рассматривать как совместимое на уровне двоичных кодов подмножество функциональности, предоставляемой версией 1.1 выпуска .NET Framework, предназначенной для настольных компьютеров и серверов.
Заранее приносим свои извинения за возможные недоразумения по этому поводу.
При работе с наборами данных DataSet, хранящимися в памяти, разработчики имеют возможность выполнять над ними целый ряд операций, включая следующие:В чем состоит разница между ADO и ADO.NET?
На протяжении последних 10-15 лет компания Microsoft предложила ряд различных библиотек объектов для доступа к данным, каждая из которых улучшала предшествовавшую модель. До появления ориентированной на использование управляемого кода технологии ADO NET применялась технология ADO название которой является аббревиатурой от ActiveX Data Objects (объекты данных ActiveX), и которая предназначалась главным образом для того, чтобы предоставить возможность обращаться к информации, хранящейся в базах данных, разработчикам на Visual Basic. В настоящее время все предыдущие модели (вместе с их многочисленными загадочными трехбуквенными акронимами наподобие DAO, RDO, ADO и номерами различных версий — прошу прощения, если я что-то перепутал!) вытеснены ADO NET.
В то время как предыдущими технологиями доступа к данным, такими как ADO, предлагались объекты RowSet, каждый из которых представлял одиночную таблицу данных с курсором, указывающим на текущую строку, в ADO.NET предлагаются объекты DataSet, представляющие наборы связанных таблиц, хранящихся в памяти вместе с межтабличными ссылками на объекты.
В ADO.NET данные представляются не в виде изолированной таблицы с курсором, обеспечивающим перемещение между строками, а в виде хранящейся в памяти схемы таблиц, навигация между которыми осуществляется с использованием объектно-ориентированных механизмов. В ADO.NET не существует понятия курсора текущей строки, поскольку данные явным образом отделены от любых подключений к базе данных, для которых мог бы потребоваться курсор. Для связывания объектов ADO.NET DataSet с внутренними источниками данных в ADO.NET используются объекты DataReader. Объекты DataReader предоставляют лишь возможность однонаправленного считывания данных из источника данных. Эти объекты используются внутренним образом для заполнения данными объектов ADO.NET DataSet.
Что такое "тип"?
На заметку! "Типом" являются любые данные, с которыми может работать программист. Это можно сформулировать и иначе, сказав, что типами являются любые типы данных и классы. Все является типом, включая целые и десятичные числа, другие скалярные величины, строки и классы. Любая "сущность", которой вы можете манипулировать внутри кода, является экземпляром типа. Классы являются специальными типами в том смысле, что они содержат не только данные, но и код, и поддерживают такие объектно-ориентированные свойства, как наследование.
На заметку! После загрузки определений классов и других типов в память, их верификации и компиляции эти данные размещаются в распределенной памяти точно так же, как и любые другие данные, которые разработчики распределяют в своих приложениях. Рассмотрим пример. Предположим, вы создаете объект ArrayList:
System.Collection.ArrayList aList = new System.Collection.ArrayList();
При этом выполняются следующие операции:
1. Вышеприведенный код представляется в вашем приложении на промежуточном языке IL. Этот IL-код подвергается JIT-компиляции во время выполнения непосредственно перед тем, как выполняться в первый раз. Этот код помещается в распределенную память.
2. По окончании JIT-компиляции кода исполнительный механизм пытается определить, загружена ли информация о типе System.Collections.Array в память; если это не так, выполняется распределение памяти для этого типа, а также загрузка и связывание определения с классом ArrayList.
3. Во время выполнения приведенного выше фактического кода должен быть выполнен конструктор объекта ArrayList. Если соответствующий код еще не загружался и не подвергался JIT-компиляции, осуществляется распределение памяти для кода конструктора и JIT-компиляция этого кода. Выполняется загрузка кода, его верификация и JIT-компиляция, и память, распределенная для кода этого конструктора, связывается с конструктором класса ArrayList.
То же самое относится и к любому другому загружаемому типу или вызываемому методу; если необходимая работа по их загрузке не была до этого выполнена, они загружаются и компилируются по мере необходимости, и используемая для этого память связывается с типом.
Описанное распределение и отслеживание памяти играет очень важную роль. Как далее будет показано, к данным о коде и определениях классов, как и к любым другим объектам, могут применяться операции сборки мусора.
Фигура | Описание |
---|---|
Темно-серые овалы | Используемые в настоящее время объекты (например, объект Obj12 на рис. 3.2). |
Белые овалы | Пассивные объекты. Эти объекты (например, объект Obj6 на рис. 3.2) являются "мусором", к которому у приложения больше нет доступа и от которого можно избавиться с целью высвобождения дополнительной памяти. |
Темно-серые прямоугольники | Описания классов и типов, которые были загружены в память по той причине, что к типам осуществлял доступ выполняющийся код. |
Внутренние прямоугольники | Код, содержащийся в классах. (Код целиком находится внутри класса.) |
Темно-серые внутренние прямоугольники | Код, подвергнутый JIТ-компиляции, поскольку метод был вызван хотя бы один раз (например, код Code1 класса ClassXYZ на рис.3.2). |
Светло-серые внутренние прямоугольники | Код, который еще не подвергался JIТ-компиляции. По сравнению с прямоугольниками JIТ-компилированного кода эти прямоугольники имеют меньшие размеры, ибо еще не скомпилированные методы (например, метод Code4 класса XYZ на рис. 3.2) занимают в памяти очень мало места. |
Из словаря Merriam-Webster
Основная запись: meth• od• ol• о• gy (методология)
Функция: существительное
Форма(ы) с окончаниями: мн. -gies
Этимология: нов. лат. methodologia, от лат. methodus + -logia -logy
Дата: 1800
1: Совокупность методов, правил и допущений, используемых в определенной дисциплине: конкретная процедура или набор процедур.
2: Анализ принципов и процедур, применяемых при проведении исследований в определенной области.(www.m-w.com, 2004)
НА ЗАМЕТКУ
Данная тема великолепно исследуется и обсуждается в книге The Mythical Man Month (Мифический человеко-месяц) Фредерика Брукса (Frederick Brooks). Каждый, кто хочет получить солидную подготовку в области общей методологии разработки программного обеспечения, должен обязательно прочесть эту книгу.
Любой достаточно сложный проект по разработке мобильного программного обеспечения нуждается в хорошем наборе методологий, способных справляться со свойственными данному виду разработки трудностями постоянного характера. Должен существовать процесс, позволяющий определять трудные проблемы и убеждаться в том, что они решаются наиболее подходящим для этого способом. Технология компонентов позволяет справиться с одним специфическим типом проблем разработки программного обеспечения. Однако для решения других проблем, например, тех, которые связаны с обеспечением необходимой производительности приложений, проектированием эффективных пользовательских интерфейсов или созданием надежных каналов связи для мобильных устройств, потребуются дополнительные методологии. Умение распознавать проблемы постоянного характера и знание способов их преодоления является отличительным признаком хорошего руководителя группы разработчиков.Две ситуации, благоприятные с точки зрения применения методологии разбивки на компоненты
Двумя областями, в которых использование компонентов предлагает эффективные способы решения сложных задач и значительно упрощает работу с этими технологиями, являются XML и криптография.
Синтаксический анализ XML-выражений является примером непростой технической задачи, для решения которой очень хорошо подходит методология повторного использования компонентов. Число разработчиков, самостоятельно создающих собственные XML-анализаторы для своих приложений, весьма невелико лишь по той простой причине, что спроектировать и реализовать высокопроизводительный XML-анализатор, отличающийся высокой степенью надежности и универсальностью, очень нелегко. Если бы все те, кому необходимо использовать в своих приложениях XML, должны были создавать собственные XML-анализаторы, то последние страдали бы всевозможными мелкими огрехами и неувязками. Это нанесло бы непоправимый ущерб самой возможности организации взаимодействия между различными платформами, лежащей в основе XML. Исключая случаи чисто академических упражнений в проектировании алгоритмов (а XML предоставляет для этого действительно благодатную почву), написание собственного XML-анализатора было бы глупой затеей; вам никогда не удастся выполнить эту работу так же хорошо, как ее могут сделать те люди, перед которыми поставлена единственная задача: написать и протестировать такой анализатор. Вместо того чтобы заставлять каждого разработчика программного обеспечения тратить время на написание собственных специальных программ синтаксического разбора XML-выражений, методология проектирования, рекомендует применять готовые универсальные компоненты, прошедшие тщательное тестирование. В результате разработок, выполненных на чрезвычайно строгом уровне проектирования алгоритмов и тестирования, были созданы несколько XML-анализаторов, основанных как на собственном, так и на управляемом коде. Эти несколько компонентов повторно используются многими разработчиками приложений, желающими применять XML. В этом и состоит суть методологического подхода к решению изначально трудной задачи создания надежного XML-анализатора.
Другим замечательным примером применения методологии повторного использования компонентов, где она оказывается более эффективной по сравнению с пользовательскими вариантами реализации, может служить криптография. Проектирование криптографических алгоритмов является своего рода сложным искусством. Вступая в определенное противоречие с ярко выраженным аспектом своей специфичности, криптографические функциональные средства с каждым днем приобретают все большее значение для разработчиков, создающих самые рядовые приложения. Давно доказано — лучшим способом создания незащищенного приложения является написание собственных криптографических алгоритмов. Если только вашей целью не является проведение исследований в области криптографии, то вы должны знать, что устоявшаяся инженерная практика программирования категорически рекомендует не заниматься созданием собственных криптографических систем. Проектирование, реализация и сопровождение криптографической системы, отвечающей требованиям надежности, живучести и быстродействия, — работа не из легких. Было бы крайне неразумно и чревато многими отрицательными последствиями, если бы все, кто нуждается в функциональных средствах криптографии, самостоятельно создавали криптографические системы для своих приложений. Итак, здесь мы также сталкиваемся с неизбежными проблемами проектирования алгоритма, решение которых более совершенные инструменты облегчить для нас не в состоянии. Но вместо того, чтобы поднимать руки вверх, признавая свое поражение: "Да, это действительно трудная задача, и с этим ничего не поделаешь", следует обратиться к методологии программных разработок, основанной на разбиении сложных алгоритмических задач общего характера на отдельные компоненты, а также к методологии, в соответствии с которой все участники рабочей группы должны следовать согласованному подходу, основанному на использовании компонентов.
Дополнительным преимуществом методологии, предполагающей использование готовых, берущихся "прямо с полки" компонент для решения проблем подобного рода, является снижение затрат на сопровождение программных продуктов. При обнаружении каких-либо изъянов в компонентах (а таковые всегда найдутся) они корректируются централизованным образом, а не по отдельности для каждого из многочисленных разрозненных вариантов реализации.
Эволюция подходов к разработке программного обеспечения на протяжении ряда лет
Каждый успешный этап развития вычислительных средств характеризовался своими специфическими проблемами и соответствующими методологиями, позволяющими добиваться успеха. Эти методологии базировались и продолжают базироваться как на самых современных из имеющихся инструментальных средствах разработки, так и на специфических видах разрабатываемых решений.
На первых порах вычислительные ресурсы, например, память, регистры или тактовая частота процессоров были весьма ограниченными, и поэтому требование написания как можно более компактных и эффективных алгоритмов носило императивный характер. Эти цели являются актуальными и на сегодняшний день, но теперь они уравновешиваются долговременными преимуществами, которые сулит написание легких в обслуживании кодов, допускающих возможность их повторного использования. На данном этапе основной целью является не просто написание как можно более эффективного кода, а написание наиболее эффективного кода, отличающегося ясностью, надежностью и легкостью сопровождения.
Пакетная обработка
В эпоху пакетных вычислений (то есть во времена, предшествовавшие появлению диалогового программного обеспечения) безраздельно царствовали алгоритмы. Тогда было возможно, и это имело действительно существенное значение, указать как входные, так и ожидаемые выходные данные системы еще до написания кода. В силу того, что модель применения программных продуктов описывалась схемой ввод→обработка→вывод, много времени тратилось на разработку центрального алгоритма, а главной задача проектирования заключалась в максимальной экономии дискового пространства и памяти. У этой модели есть свои достоинства, и сегодня она по-прежнему является идеалом, к которому следует стремиться при разработке отдельных процедур, предназначенных для обработки информации в пакетном режиме (например, при проектировании алгоритмов сортировки). Такой подход целесообразно применять при проектировании отдельных функций, но не сложных систем, обеспечивающих интерактивное взаимодействие с пользователем. Этот период можно назвать эрой "блок-схем".
Серверная обработка без сохранения состояний
При построении надежных серверных приложений, отвечающих на запросы, роль Святого Грааля играет "отсутствие состояния". Ваш код получает запрос, обрабатывает его, а затем возвращает результат, не нуждаясь в сохранении состояния на протяжении периода времени между двумя последовательными запросами. Все это очень напоминает пакетную обработку, поскольку в данном случае также используется модель, описываемая схемой ввод→обработка→вывод. Разумеется, современные сложные Web- приложения (например, система покупательских тележек на Web-сайте Amazon) должны сохранять свое состояние в течение промежутков времени между двумя последовательными запросами, а этого легче всего достигнуть осуществляя управление состояниями на основе существенно централизованного механизма инкапсуляции, обеспечивающего выполнение как можно большего объема кода без сохранения состояния
Интерактивные вычисления, управляемые событиями
Управляемые событиями вычисления (event-driven computing) представляют вычислительную модель, в которой приложение находится в состоянии долговременного обмена информацией с конечным пользователем. Выполнение кода осуществляется в ответ на действия и запросы конечного пользователя; задача приложения заключается в обеспечении соответствующей реакции на то, что делает пользователь. В отличие от пакетных приложений интерактивные (диалоговые) приложения не имеют определенного фиксированного периода завершения и продолжают обрабатывать новые события, запускаемые пользователем, до тех пор, пока пользователь не решит прервать рабочий сеанс. Эту модель программирования обычно называют "управляемой событиями", поскольку в результате действий пользователя вырабатываются дискретные события (например, события щелчка мыши, выбора элемента списка или закрытия окна), на которые должно реагировать разрабатываемое приложение. При построении удачного интерактивного приложения, управляемого событиями, очень многое зависит от того, насколько тщательно продумана модель управления состояниями.
Неудачное описание | Удачное описание |
---|---|
Приложение для обслуживания банковских операций | Приложение для обслуживания банковских операций |
"Обеспечить для пользователей мобильных устройств доступность Web-функциональности приложения MyBankFoos, предназначенного для мобильных банковских услуг, как в автономном, так и в сетевом режимах работы." В этом описании ни слова не сказано о том, какие функциональные возможности являются наиболее важными. Возможность проверки состояния нужного счета? Оплата счетов? Хронология операций по переводу денежных средств? Смена обслуживающих банков? Денежные переводы? Операции в местах продажи? Заемные и залоговые условия при покупке автомобиля? Каковы те основные операции, в выполнении которых при помощи мобильного устройства больше всего будет нуждаться пользователь? | "1. Пользователи должны иметь возможность получать доступ к своим банковским счетам посредством не более пяти нажатий клавиш мобильного телефона, выполняемых одной рукой. 2. Пользователи должны иметь возможность совершать покупки и получать соответствующие подтверждения от торговых автоматов, используя инфракрасный порт устройства, с помощью не более трех клавиатурных нажатий." Мы идентифицировали два ключевых сценария, которые хотели бы сделать доступными для пользователей. |
Опросы общественного мнения | Опросы общественного мнения |
"Обеспечить замену бумаге и дощечке с зажимом при проведении опросов общественного мнения и избавиться от занесения данных опроса вручную." Какие вопросы будут задаваться? Когда будет выполняться синхронизация данных? | "Приложение должно предоставить пользователям возможность сбора информации в ходе опросов общественного мнения с помощью устройства Pocket PC. Вопросы будут предусматривать либо выбор одного из готовых вариантов ответа, либо простой цифровой ввод, а ответы будут кэшироваться на устройстве и отправляться на сервер после помещения устройства в лоток ПК. Опрос может содержать до 20 вопросов, а результаты, содержащие вплоть до 1000 ответов, должны храниться на устройстве. Ввод текста вручную не требуется. Мы указали, какие виды вопросов должно обрабатывать приложение, а также каким образом будет осуществляться синхронизация устройства. (Здесь следует обратить внимание на то, что при составлении списка сценариев мы не заботились о том, какой именно способ сохранения результатов на устройстве будет использоваться или каков будет конкретный механизм синхронизации для работающего сценария — это важно только для нашей реализации, но не для конечного пользователя.) Мы указали также, чего не требуем от приложения (например, от него не требуется обработка свободного текста). |
Инвентарный учет | Инвентарный учет |
"Версия системы учета товара, ориентированная на настольные компьютеры, будет сделана доступной для подключенных к сети и автономных мобильных устройств." Простой перенос функциональности Web-приложений и приложений, рассчитанных на настольные компьютеры, почти никогда не приводит к удовлетворительным результатам. | "Приложение предназначено для использования на складах в режиме периодического доступа в сеть WI-Fi. Должна быть обеспечена возможность автономного режима работы с хранящимися на устройстве данными учета товаров, охватывающими вплоть до 5000 наименований. Идентификаторы товарных единиц должны сканироваться с помощью устройств для считывания штрих-кодов. Учетные записи о товарных единицах могут включаться в инвентарный список и исключаться из него. Устройства синхронизируются с использованием сети Wi-Fi, когда этого пожелает пользователь. Для обновления информации может быть затребован активный доступ к серверной базе данных. Ключевой сценарий: произвести сканирование при помощи устройства для считывания штрих-кодов и указать нажатием клавиши вид операции с инвентарным списком — добавление или исключение учетной записи. Произвести считывание порядкового номера покупки для его связывания с учетной записью о товарной единице. Ключевое требование — в случае невозможности считывания штрих-кода пользователь должен иметь возможность быстро ввести необходимую цифровую информацию вручную с помощью сенсорного экрана и пера. Для повышения надежности учета информация о неудачных попытках считывания штрих-кодов в процессе эксплуатации приложения должна заноситься в журнал." Мы указали, в чем состоит суть ключевых требований, а также выписали основной сценарий, в соответствии с которым будет эксплуатироваться приложение. |
Игровые/обучающие приложения | Игровые/обучающие приложения |
"Создать мобильное приложение для изучения слов иностранного языка." Какая емкость словаря потребуется? Каким образом будет осуществляться процесс обучения в целом? | "Приложение является игрой, предназначенной для проверки того, насколько хорошо пользователь знает слова иностранного языка. Пользователям предлагаются вопросы, предлагающие выбрать из набора предложенных вариантов правильный перевод слова путем касания экрана. В устройстве может храниться до 1000 различных иностранных слов. В устройстве также должны храниться примеры предложений с изучаемыми словами." Обучающая программа описана довольно полно. Потребуется дальнейшее исследование того, как должна работать игра, но мы уже определили высокоуровневую модель ввода-вывода и емкость словаря. |
Приложение для заказа авиабилетов | Приложение для заказа авиабилетов |
"Приложение должно обеспечить сохранение и обработку в мобильном телефоне всей пользовательской информации о рейсах и сделать эту информацию доступной для работы в автономном режиме." В этом описании мало говорится о том, что будет делать приложение, и каким образом пользователь будет работать с ним. | "Пользователь должен иметь возможность получения доступа к сохраняемой в устройстве информации, относящейся к электронному заказу билетов. Информация, которую сможет получать пользователь мобильного телефона, включает в себя номер заказа, номер рейса, время вылета и данные об аэропортах вылета и назначения, причем для получения доступа к этой информации должно требоваться не более трех клавиатурных нажатий. Должен быть обеспечен быстрый вызов и передача этой информации работнику, занимающемуся резервированием посадочных мест." |
Пример разработки пользовательского интерфейса с учетом обеспечения высокой производительности
Как ActiveSync, так и Internet Explorer для Pocket PC и интеллектуальных телефонов предлагают элементы пользовательского интерфейса, назначение которых состоит в том, чтобы информировать пользователей о состоянии выполнения инициированных ими асинхронных запросов. Благодаря этому пользовательский интерфейс сохраняет свою интерактивность, и у пользователя не возникает чувства потери контакта с приложением.
Для синхронизации календарной информации с сервером Exchange Server приложению ActiveSync может требоваться телефонный звонок или иная форма операции соединения, на выполнение которой уходит длительное время. В процессе выполнения такой операции пользовательский интерфейс устройства отображает пояснительный текст, информирующий пользователя о текущем состоянии попытки создания соединения. Таким текстом может быть "Набор номера...", "Соединение с сервером", "Синхронизация расписания", "Загружено 12 из 20" и тому подобное. Такие несложные уведомляющие элементы пользовательского интерфейса не дают никакого выигрыша в производительности, но зато сохраняют в пользователе уверенность в том, что полезная для него работа продолжает выполняться, и удерживают его от попыток отмены запроса из-за того, что ответ на него затягивается.
Браузер Pocket Internet Explorer также может нуждаться в соединении с источниками данных, поиске IP-адресов URL и выполнении других задач в процессе загрузки Web-страниц. При выполнении подобных затяжных задач заголовок окна браузера обновляется постоянно отображая текст, информирующий пользователя о состоянии соединения. Кроме того, при загрузке Web-содержимого отображается анимация флага Windows. Оба указанных действия информируют пользователя о том, что выполнение операции продолжается.
В обоих случаях пользовательский интерфейс сохраняет свою интерактивность, а пользователям предоставляется возможность отменить операцию, если они того захотят. Наличие возможности в любой момент прекратить выполнение операции поддерживает в пользователе чувство уверенности в сохранении контроля над ситуацией, а непрерывное получение им информации о состоянии выполнения операции уменьшает вероятность того, что он ее отменит. Конечно, было бы лучше, если бы такие операции выполнялись мгновенно, но в тех случаях, когда это невозможно, следующее наилучшее решение заключается в поддержании интерактивности пользовательского интерфейса и непрерывном информировании пользователя о развитии ситуации.
state [`stAt]
Функция: существительное
Использование: часто в качестве определения
Этимология: средневек. англ. stat, от устар. фр. и лат.; устар. фр. estat, от лат. status, между stare и stand — ближе к STAND
Дата: 13 столетие
1а: режим или условие нахождения <в состоянии готовности> b (1): настроение ума или темперамент <во взвинченном состоянии> (2) пребывание в необычном напряжении или волнении
2а: период или стадия физического существования чего-либо(www.m-w.com, 2004)
ma-chine [mashEn]
сущ. (мн. ma-chines)
Использование: часто в качестве определения
1. механическое устройство: устройство с движущимися частями, часто приводимое в действие электричеством и используемое для выполнения некоторой работы, особенно той, которую иначе надо было бы выполнять вручную
стиральная машина(Encarta 2004, Quotations)
Состояние | Внешний ввод | Следующее состояние |
---|---|---|
StartScreen | Пользователь выбрал вариант "Next Question" | AskQuestion |
StartScreen | Пользователь выбрал вариант "Correct Answer" | Запрещенный переход! |
StartScreen | Пользователь выбрал вариант "Incorrect Answer" | Запрещенный переход! |
StartScreen | Пользователь выбрал вариант "End Game" | Запрещенный переход! |
AskQuestion | Пользователь выбрал вариант "Next Question" | Запрещенный переход! |
AskQuestion | Пользователь выбрал вариант "Correct Answer" | CongratulateUser |
AskQuestion | Пользователь выбрал вариант "Incorrect Answer" | ScoldUser |
AskQuestion | Пользователь выбрал вариант "End Game" | Запрещенный переход! |
CongratulateUser | Пользователь выбрал вариант "Next Question" | AskQuestion |
CongratulateUser | Пользователь выбрал вариант "Correct Answer" | Запрещенный переход! |
CongratulateUser | Пользователь выбрал вариант "Incorrect Answer" | Запрещенный переход! |
CongratulateUser | Пользователь выбрал вариант "End Game" | StartScreen |
ScoldUser | Пользователь выбрал вариант "Next Question" | AskQuestion |
ScoldUser | Пользователь выбрал вариант "Correct Answer" | Запрещенный переход! |
ScoldUser | Пользователь выбрал вариант "Incorrect Answer" | Запрещенный переход! |
ScoldUser | Пользователь выбрал вариант "End Game" | StartScreen |
В листинге 5.1 представлен код, реализующий определенный выше конечный автомат. Этот код соответствует диаграмме переходов, представленной в табл. 5.1 и на рис. 5.1. Обратите внимание на то, что в приведенной ниже функции участки кода, соответствующие различным изменениям состояний, содержат вызовы функций, отключенные с помощью символов комментариев. Эти функциональные вызовы представляют ту часть работы, которая должна быть выполнена для соответствующего изменения состояния, и отключены символами комментариев с той целью, чтобы приведенный ниже код можно было компилировать как независимый блок; реализация вызываемых функций остается за вами. Для определения текущего варианта изменения состояния удобно использовать блок операторов switch/case.НА ЗАМЕТКУ
Я решил привести в таблице все возможные перестановки переменных, указанных в столбцах "Состояние" и "Внешний ввод", чтобы проиллюстрировать тот факт, что не любое изменение состояния разрешено. Переходы между состояниями, указанными в строках, для которых в столбце "Следующее состояние" содержится пояснение "Запрещенный переход!", недопустимы в нашем приложении. Если приложение пытается каким-либо образом осуществить такое изменение состояния, значит, в логике его выполнения присутствуют ошибки. В случае если предпринимается попытка выполнения недействительного перехода, логика конечного автомата должна возбуждать исключение или, по крайней мере, использовать оператор ASSERT в режиме отладки. Явная идентификация запрещенных переходов между состояниями облегчает отладку приложений.
Отдаете ли вы себе в этом отчет или нет, но значительная доля кода вашего приложения всегда будет связана с управлением его состояниями. Как бы то ни было, вам придется иметь дело с задачами подобного рода, и только вам решать, выбрать ли явный подход к управлению состояниями приложения или же остановиться на модели неявного управления. Явное управление состояниями имеет ряд существенных преимуществ, не самым последним из которых является то, что такой подход заставляет вас более тщательно продумывать схемы функционирования вашего приложения.Постойте-ка! Но ведь речь идет о мобильных приложениях. Разве размер их кода не должен быть меньше размера кода настольных приложений?
Краткий ответ на этот вопрос звучит так: "Нет, не должен". Ваш код вовсе не должен быть меньше по размеру, чем аналогичный код для настольных компьютеров — он должен быть лучше! Среди разработчиков мобильных приложений бытует ошибочная точка зрения, согласно которой при написании кода лучше не разбивать его на отдельные функции, а стараться поместить в любую заданную функцию как можно больше кода и как можно чаще использовать встроенный код. Такой подход противоречит устоявшимся принципам проектирования. Назовем эту тенденцию "оптимизацией под микроскопом".
Оптимизация более высокого порядка реализуются не на микроскопическом уровне, а на макроуровне. Проекты, в которых широко используется инкапсуляция, предоставляют гораздо больше возможностей для макрооптимизации. Имея единственный набор функций, предназначенных для управления приложением, вам будет легче работать со структурой приложения и тем самым оптимизировать ее. Чтобы обеспечить высокую производительность приложения, вам придется возвращаться к уже пройденным стадиям проекта, анализировать их и при необходимости изменять первоначальные предпосылки, которые, как выяснилось впоследствии, оказались неверными. В этом отношении централизованный подход к управлению состояниями приложения принесет вам гораздо больше пользы, чем распределенный специализированный подход.
Существуют и такие ситуации, в которых действительно имеет смысл затратить усилия на оптимизацию отдельных алгоритмов и вынести код за пределы функций, сделав его встроенным. Это, например, может оказаться целесообразным в случае кода, выполняющего интенсивную многократную обработку крупных наборов данных в циклах. При необходимости можно систематически выявлять такие ситуации и принимать соответствующие меры. Однако для конечных автоматов, работающих на уровне приложения, которые вызываются при переходе приложения из одного режима выполнения операций или отображения пользовательского интерфейса в другой, такие ситуации не характерны; указанные изменения обычно осуществляются с низкой частотой и не встречаются внутри плотных циклов.
Наконец, гораздо проще взять инкапсулированный код и вставить его в вызывающую функцию, чем пытаться преобразовать произвольный фрагмент кода к инкапсулированному виду, чтобы повысить эффективность работы с ним. Это вам подтвердит каждый, кому хотя бы раз приходилось заниматься упорядочением кода типа "спагетти", написанного другими разработчиками, приводя его к более удобной в работе инкапсулированной форме!
В силу описанных причин при разработке программного обеспечения для мобильных устройств удачная структура кода играет, по крайней мере, не меньшую роль, чем в случае настольных компьютеров. Использование конечных автоматов облегчает эффективную организацию кода, что в свою очередь способствует созданию замечательных приложений.
Стиль программирования: использование операторов goto и полных путей доступа в пространствах имен
Следует дать некоторые пояснения относительно двух аспектов стиля программирования, принятого во всех примерах кодов, приводимых в данной книге.
Использование операторов goto
Вопрос о том, следует ли считать использование операторов goto в программах допустимым или же его необходимо рассматривать как признак плохого стиля программирования, является в определенной мере дискуссионным. Применимость операторов goto выступает предметом споров постольку, поскольку осуществляемая с их помощью передача управления противоречит принципам, лежащим в основе использования операторов условного перехода (if/then) и операторов циклов.
Лично я принадлежу к лагерю тех, кто считает использование операторов goto в программах вполне допустимым при условии выполнения следующих требований:
1) Им соответствует передача управления только в прямом направлении.
2) Они способствуют повышению удобочитаемости интересующих нас участков кода. Применение операторов goto может считаться непозволительным лишь в том случае, если это затрудняет понимание логики передачи управления в выполняющейся программе. Примером неудачного использования операторов goto может служить передача управления в различных направлениях, поскольку результатом этого является создание сложной системы замысловатых переходов внутри функций и трудности в отслеживании их логики; несомненно, любой из нас возражал бы против подобного использования этого оператора.
Использование полных путей доступа в пространствах имен
Возможны два способа указания типов переменных в программах:
1) В теле программы можно указывать полный путь доступа. Например, оператор System.Threading.Thread newThread; объявляет переменную newThread типа System.Threading.Thread. Достоинством таких подробных объявлений является простота их применения.
2) В начале файла с текстом программы можно задавать использование определенного пространства имен, применяя для этого ключевое слово using языка C# или ключевое слово Imports языка Visual Basic .NET. Например, если в начале файла с программой на языке C# содержится оператор using SystemThreading;, то переменная System.Threading.Thread может быть объявлена просто как Thread newThread; без указания ее полного имени.
С функциональной точки зрения оба способа являются эквивалентными. Разработчикам, знакомым с использованием пространств имен, последний способ может предоставлять дополнительные удобства в работе. Разработчикам же, которые только осваивают это понятие, легче будет использовать первый из этих способов, поскольку он точно описывает логическую принадлежность каждого класса или типа. Учитывая тот факт, что не все читатели данной книги могут быть одинаково хорошо знакомы с пространствами имен .NET, я решил везде использовать более подробный синтаксис.
На заметку! Прежде чем вы сможете использовать те или иные классы и типы в своей программе, вы должны указать, к каким сборкам (assembly), они относятся. Очень важно, чтобы вы понимали, что ключевые слова using и Imports являются всего лишь удобным синтаксическим средством и не отменяют необходимости включения ссылки на сборку. Чтобы компилятору стали известны типы, содержащиеся в сборке, вы должны явно включить соответствующую ссылку в свою программу. В Visual Studio .NET список сборок можно просмотреть с помощью элемента управления TreeView в окне проводника решений Solution Explorer. Как правило, предварительно сконфигурированные часто используемые ссылки автоматически включаются во вновь создаваемые проекты.
НА ЗАМЕТКУ
Чтобы не усложнять пример, количество правил, используемых в функции управления переходом, было сознательно выбрано небольшим. В случае фактической реализации количество правил целесообразно увеличить, например, разрешая только допустимые переходы между состояниями, и вырабатывая исключения в непредвиденных ситуациях. Наличие жестких правил, регламентирующих возможность изменения состояния, оказывается очень полезным при поиске трудно обнаруживаемых ошибок, обусловленных выполнением кода сразу несколькими потоками. В подобных ситуациях процесс выполнения усложняется, так что введение надежных правил, осуществление проверок с помощью операторов ASSERT и генерация исключений значительно облегчат вам поиск тонких ошибок, избавив от возможной многочасовой работы по их устранению.
Руби Гольдберг (Rube Goldberg) (1883-1970) — художник-карикатурист, рисовавший механизмы, предназначенные, несмотря на всю фантастичность своей конструкции, для выполнения самых обычных операций. Каждый из этих механизмов представлял собой завораживающее сплетение всевозможных рычагов, шкивов и пружин и снабжался забавным описанием принципов его работы. Вам следовало бы очень внимательно ознакомиться с запутанным внутренним устройством этих механизмов, чтобы впоследствии никогда не допускать ничего подобного при разработке своих приложений для мобильных устройств. Стремитесь к простоте и действуйте всегда целенаправленно!Иво Салмре(чтобы получить представление о механизмах Руби Гольдберга, посетите Web-сайт http://www.rube-goldberg.com/)
Поиск информации в Web с помощью мобильных устройств имеет свои особенности
Мне не раз приходилось слышать оценку, согласно которой в течение всего лишь нескольких лет число мобильных устройств, имеющих доступ к Internet, превысит аналогичное число настольных компьютеров. Возможно, так оно и будет, но было бы неправильно считать, что способы использования Internet в обоих случаях будут одинаковыми. Стоит поговорить о том, почему это так.
Ранее мы уже указывали на то, что в мобильных Web-бpayзepax адресная строка часто по умолчанию является скрытой. В случае настольных компьютеров такое поведение можно было бы считать упущением, но в случае мобильных устройств критерии оценки другие. На то есть две причины: 1) в случае мобильных устройств быстро вводить длинные URL-адреса обычно бывает непросто, и если имена Web-сайтов приходится задавать с указанием всех входящих в них символов то и редактор T9 не в состоянии ускорить эту процедуру, и 2) в силу требований к размерам изображений и компоновке экрана большая часть Web-содержимого плохо приспособлена для отображения на мобильных устройствах.
По этой причине работа в Web с помощью мобильных устройств осуществляется с использованием списка наиболее часто посещаемых мобильных Web-сайтов, причем приходится проверять, чтобы ссылки, которые могут встречаться на этих стартовых страницах, также указывали на полезное содержимое, способное нормально отображаться на экране мобильного устройства.
Именно поэтому ведется работа по выделению в Internet отдельного домена высшего уровня (например, .mobile, а не .com), предоставляющего содержимое специально для мобильных устройств. Мобильные устройства вскоре станут очень важными участниками деятельности в Internet, но использоваться в работе они будут не так, как браузеры современных настольных компьютеров. Ближайшее будущее обещает нам много интересного, поскольку можно ожидать появления в Web множества новшеств, специфических для мобильных устройств, а не простого переформулирования идей программного обеспечения, разработанного для настольных компьютеров.
per• form• ance [pr fáwrmns] производительность: эффективность выполнения кем-то или чем-то определенной работы(Encarta 2004, Dictionary)
Наилучший способ удерживать курс — это не сбиваться с него. Если вы оступились — остановитесь, сделайте шаг назад и продолжите движение в нужном направлении.Автор данной главы
Строгое соблюдение критериев завершения контрольных точек в той части, которая касается поддержания высокой производительности приложения, играет чрезвычайно важную роль по той простой причине, что добиться существенного улучшения производительности впоследствии без кардинального пересмотра проекта обычно оказывается невозможным. Типичные оправдания, подобные такому: "Главное сейчас — это завершить разработку готового варианта работоспособного кода к намеченному сроку, а проблемами производительности можно будет заняться и позже, при прохождении последующих контрольных точек", не выдерживают никакой критики. Справляться с проблемами производительности на более поздних стадиях производственного цикла всегда сложнее, поскольку с увеличением объема написанного кода зависимости между его отдельными частями только усиливаются, и это делает внесение необходимых изменений в проект все более затруднительным. Если кто-то говорит: "Проблемами производительности и их устранением мы займемся позже", то истинный смысл этого таков: "Мы не понимаем сути проблем производительности, с которыми столкнулись, и пока не можем сказать, каким образом собираемся устранять их в будущем. To, что мы создаем сейчас, — это прототип, который, как бы то ни было, может быть подготовлен к поставке; чтобы создать действительно завершенную версию приложения, нам, вероятно, придется переписать значительную часть кода".Несколько слов о прохождении контрольных точек
Очень важно, чтобы проект не хромал на контрольных точках и проходил их твердо и уверенно, а члены группы были едины в своих действиях и по завершении этапа испытывали чувство гордости за проделанную работу. Всегда существует искушение заняться проблемами производительности "когда-нибудь потом", поскольку их решение непосредственно не венчается созданием каких-либо новых инструментальных средств или возможностей; ни в коем случае не поддавайтесь этому соблазну! Как неоднократно доказано на практике, гораздо лучше пройти контрольную точку, пусть и с нарушением установленных сроков, но строго выполнив все необходимые требования, чем быстро ее проскочить, ограничившись компромиссными решениями.
Ослабление критериев завершения этапов нисколько не ускорит вашего приближения к конечной цели. Если вы видите, что график работ нарушается, то можете выбрать один из трех возможных вариантов дальнейших действий:
1. Отказ от разработки некоторых из возможностей продукта для сосредоточения всех усилий на реализации тех возможностей, которые остаются. Если вы решите поступить именно таким образом, то лучше всего сделать это как можно раньше, чтобы разработка остальных возможностей была выполнена на высоком уровне. Отказ от части возможностей приложения на более поздних этапах будет очень болезненно восприниматься теми, кто разрабатывал соответствующие части кода, и конечными пользователями, которые рассчитывали на эти возможности, а также неблагоприятно скажется на разработке оставшейся части продукта, поскольку на ее структуру могли влиять зависимости, которые теперь оказались ненужными. Поскольку отказ от разработки части запланированных возможностей всегда дается очень трудно, это должно делаться корректно, начинаться как можно раньше и осуществляться в условиях уверенного руководства действиями группы.
2. Продление графика выполнения работ до более реалистических сроков в соответствии с текущей оценкой состояния проекта. По мере продвижения работы над проектом будут выявляться ранее неизвестные факты, которые позволят вам точнее спрогнозировать срок окончания работ. Если график выполнения контрольной точки должен быть продлен (с соответствующим продлением графика выполнения остальных работ), делайте это решительно, устанавливая реальные сроки. Конечным результатом должен стать график, реальность выполнения которого ни у кого не будет вызывать сомнений.
3. Нахождение более оптимальных способов распределения рабочей нагрузки среди членов группы. Включение в группу разработчиков на промежуточных этапах выполнения проекта дополнительных участников, не знакомых с тем, что уже сделано, редко когда приводит к желаемому эффекту. Вместо этого можно попытаться более оптимальным образом распределить работу среди имеющихся участников группы. Аналогично двум предыдущим пунктам, при принятии решений, касающихся распределения рабочей нагрузки среди участников, важную роль играют реалистическая оценка ситуации, а также энергичность и решительность осуществления руководства группой. Лучше быстро утвердить болезненный процесс перераспределения обязанностей одним решением, чем делать это по частям в несколько приемов.
Получение информации об основных показателях производительности в .NET Compact Framework
В .NET Compact Framework версии 1.1 имеется встроенный механизм, позволяющий быстро получать "черновую" метрику работы приложений на основе управляемого кода в этой среде. Упомянутый механизм обеспечивает получение показателей производительности приложения в целом и по завершении выполнения приложения выводит соответствующий текстовый файл. В этом текстовом файле содержатся следующие данные:
• Суммарное время выполнения
• Количество объектов, размещенных в памяти в процессе выполнения кода.
• Количество операций по сборке мусора, произведенных в процессе выполнения кода.
• Количество сгенерированных исключений. (Накладные расходы, связанные с обработкой исключений, возбуждаемых часто и без крайней на то необходимости внутри циклов, могут оказаться весьма существенными )
Поскольку полученные показатели характеризуют работу программы на уровне приложения, их целесообразно использовать в тех случаях, когда вы сравниваете два различных алгоритма или настраиваете определенный алгоритм. Тестируемые алгоритмы следует выделить в собственные исполняемые файлы. Исполняемые файлы должны содержать как можно меньше лишнего кода, чтобы основная часть производимых вычислений приходилась на тестируемые алгоритмы. Исключите из кода любые другие формы или код, которые могут приводить к загрузке, JIT-компиляции и выполнению нежелательных компонентов, если таковые имеются.
Технические рекомендации относительно того, как активизировать генерацию рассматриваемых показателей времени выполнения, содержатся в статье "Developing Well Performing .NET Compact Framework Applications" ("Разработка высокопроизводительных приложений .NET Compact Framework") на Web-сайте http://msdn.microsoft.com.
На момент написания данной книги указанная статья располагалась по следующему URL-адресу:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/netcfperf.asp
Кроме того, в этой статье рассматриваются различные способы оценки функциональности кода на основании сравнительного анализа показателей производительности; этот материал также заслуживает прочтения.
HA ЗАМЕТКУ
В документации по .NET Compact Framework утверждается, что интервал значений свойства .TickCount не может быть меньше 500 мс (0,5 секунды). Я обнаружил, что на практике достигается несколько лучшее разрешение (менее 100 мс, или 0,1 секунды), чем указанное. Вам придется немного поэкспериментировать самостоятельно. Если окажется, что вам необходим счетчик с более высоким разрешением, можете видоизменить приведенный выше код, включив в него системные вызовы операционной системы, управляющей собственным кодом, для получения доступа к низкоуровневым системным счетчикам. В большинстве случае возможностей приведенного выше кода вам должно быть вполне достаточно, а в силу своей простоты он оказывается удобным для использования в тех случаях, когда измерения требуется выполнить быстро.
Советы относительно повышения надежности результатов измерений
1. Вы можете пользоваться эмпирическим правилом, в соответствии с которым чем больше длительность события, которую вы измеряете, тем меньше относительная ошибка. Поэтому, если вы сравниваете два алгоритма, для выполнения которых требуется примерно 0,5 секунды, лучше выполнить каждый из них по 10 раз и разделить полученные результаты на 10.
2. Повторяйте каждый эксперимент несколько раз, убеждаясь в том, что получаемые результаты оказываются в достаточной степени близкими друг к другу.
3. Если вы сравниваете эффективность двух алгоритмов, выполните каждый из них несколько раз и отбросьте первые из полученных для каждого из них результатов измерений, если они значительно отличаются от результатов последующих измерений. Вполне возможно, что во время первоначального выполнения кода вашим приложением выполняется загрузка и компиляция библиотек, связанных различными зависимостями. Если оба алгоритма имеют аналогичные зависимости, то загрузка и JIT-компиляция этого кода отразится на результатах первого измерения. Время, необходимое для JIT-компиляции кода, среди сравниваемых результатов учитываться, как правило, не должно.
4. Чтобы при сравнении эффективности двух различных алгоритмов получить наилучшие результаты, заново запускайте приложение в промежутках между тестами. Повторный запуск приложения сбросит весь предварительно скомпилированный и находящийся в кэш-памяти код, тем самым предоставляя вам общее начало отсчета для каждого теста.
Почти во всех случаях измерения временных промежутков не могут быть идеальными, они могут быть лишь в достаточной степени надежными. Важно лишь следить за тем, чтобы величина измеряемых показателей превышала уровень шумов, которые всегда присутствуют. Независимо от того, что именно вы пытаетесь измерить, всегда можно найти способы, позволяющие отладить методику измерений таким образом, чтобы получаемые результаты были надежными.
■ Повышение производительности — это всего лишь тонкая настройка алгоритмов, которые мною уже написаны. В очередной раз неверно. Хотя улучшением отдельных алгоритмов иногда и можно добиться заметного выигрыша в производительности, в остальных случаях для этого может потребоваться существенная переделка проекта. Если только качество написанного вами кода не является совершенно ужасным, наибольший выигрыш в производительности вам может принести не оптимизация алгоритмов, которые вами уже написаны, а фундаментальная реструктуризация модели данных и пользовательского интерфейса вашего приложения, способная резко улучшить производительность. Очень важно не упустить тот момент, когда возникает необходимость в пересмотре фундаментальных положений проекта и поиске конструктивных альтернатив.НА ЗАМЕТКУ
Важно подчеркнуть что из всего вышесказанного вовсе не следует, будто вы должны потратить бесчисленное количество часов на шлифование абсолютно всех алгоритмов; такой подход также не даст ничего хорошего и приведет к созданию без нужды оптимизированного на микроскопическом уровне кода, который очень трудно поддерживать. Одни части вашего приложения играют большую роль, чем другие, и ваша задача состоит в том, чтобы оценить и измерить, какие из них имеют первостепенное значение, и именно на них сконцентрировать основные усилия. Это говорит о том, насколько важно понимать, что для каждого вида обработки данных, независимо от того, идет ли речь о строках, массивах, коллекциях, размещении объектов и типов, алгоритмах сортировки, обычных типах данных или операциях, имеются свои эффективные приемы программирования, и вы должны выработать в себе привычку к написанию только высококачественного кода (или, по крайней мере, кода, качество которого не является очевидно низким!). Всегда старайтесь писать только код высокого качества и измеряйте соответствующие показатели для различных частей приложения, чтобы выяснить, какие из них являются критичными для обеспечения высокой производительности. После того, как вы надлежащим образом выполните основную работу, поддерживая качество кода на хорошем уровне, можете потратить свое драгоценное время на дополнительную оптимизацию наиболее важных частей приложения.
В качестве одной из целей разработки всегда указывайте обязательное подтверждение получения команд пользователя, даже если они не могут быть немедленно обработаны. Обычно любая задержка с таким подтверждением, превышающая 0,5 секунды, вызывает у конечного пользователя чувство раздражения. При возникновении задержки ответа пользователи часто пытаются повторить команду, что может стать причиной еще большего раздражения, если вторая команда переводит приложение в нежелательное состояние или оно начинает работать не так, как ожидается.Ответная реакция устройства и пульты дистанционного управления домашней электронной техникой
Для различных типов устройств предусматриваются различные виды ответной реакции. Быстрая, безошибочная и информативная обратная связь с пользователем является отличительным признаком хорошо спроектированного мобильного устройства.
Проведем мысленный эксперимент, обратившись в качестве примера к телевизионному пульту дистанционного управления. Хорошие пульты часто обеспечивают несколько разновидностей обратной связи. Во-первых, вы должны ощущать физическое сопротивление кнопок нажатию; каждому, кому приходилось пользоваться дистанционным пультом управления, не имеющим дискретных физических кнопок, знакомо чувство неуверенности, возникающему при нажатии так называемых "программных" кнопок. Во-вторых, в ответ на нажатие какой-либо кнопки дистанционные пульты часто подсвечиваются, указывая на то, что они приняли запрос и пытаются отреагировать на ваш ввод. В-третьих, непосредственной визуальной ответной реакцией телевизионного приемника на получение команды от пульта является вывод на экран шкалы регулятора громкости, цифры или любого другого визуального подтверждения. Если в любом из перечисленных случаев задержка ответной реакции превышает 0,5 секунды, то из-за недостаточно быстрой обратной связи работа пульта кажется замедленной. Эта задержка называется задержкой реакции, и если она наблюдается, то у пользователя немедленно возникает ощущение, что ему попался бракованный пульт. Это вовсе не означает, что пользователь требует, чтобы результаты выполнения отданной команды всегда проявлялись немедленно (хотя это всегда радует); главное, что отличает хороший пульт от плохого, — это немедленное извещение пользователя о том, что его команда принята
Аналогичные моменты должны учитываться вами и при проектировании приложений. Часто для организации хорошей обратной связи требуется всего лишь добавить в приложение немного кода и чуть-чуть его приукрасить, но это оказывает огромный положительный эффект на пользовательское восприятие устройства и его оценку качества приложения.
Количество итераций | Время выполнения с возбуждением исключений (с) | Время выполнения без возбуждения исключений (с) | Во сколько раз быстрее работает алгоритм без возбуждения исключений |
---|---|---|---|
10000 | 0,006 | 2,202 | 367 |
10000 | 0,006 | 2,201 | 367 |
100000 | 0,061 | 22,716 | 372 |
100000 | 0,055 | 22,834 | 415 |
100000 | 0,055 | 22,995 | 418 |
Представленный в листинге 7.4 код следует включить в форму проекта для Pocket PC. Для сборки и запуска приложения необходимо выполнить следующие действия:НА ЗАМЕТКУ
Следует отметить, что поскольку обработка исключений входит в состав базовых средств времени выполнения и отладки .NET Compact Framework и Visual Studio .NET, то производительность приложения может в заметной степени меняться в зависимости от двух обстоятельств
1. Производительность кода, генерирующего исключения, может значительно ухудшаться, если программа выполняется с подключенным отладчиком. Это объясняется тем, что в этом случае среда уведомляется о возбуждении исключений, даже если они перехватываются кодом приложения. Это означает, что алгоритмы, выполнение которых сопровождается возбуждением многочисленных исключений, при подключенном отладчике будут работать очень медленно! Вы не должны забывать об этом на стадиях проектирования и разработки приложения; возбуждение множества исключений может замедлить разработку. Обычно поведение среды разработки не должно вынуждать вас к изменению способа написания кода, но в данном случае вы должны включить в документ проекта дополнительный пункт, в соответствии с которым следует избегать многократного возбуждения исключений в часто выполняемых циклах.
2. Различия в производительности кода, использующего обработку исключений, при его выполнении на эмуляторах и физических устройствах весьма заметны. Чтобы получить наиболее точные данные о том, каким образом возбуждение и обработка исключений влияют на производительность вашего приложения, соответствующие тесты должны выполняться на физических устройствах при отключенном отладчике.
"Человеческая голова подобна комнате, в которой необходимо держать только те вещи, которые вам непосредственно нужны, а все остальные — убирать подальше в чулан, откуда их можно будет в любой момент достать, когда они понадобятся."Артур Конан-Дойль(Encarta 2004, Quotations)
Перед вами, как перед проектировщиком мобильного приложения, не стоит задача найти способы, позволяющие использовать всю свободную память вплоть до некоторой пороговой величины, при превышении которой производительность начинает резко ухудшаться. Вместо этого вы должны стремиться к тому, чтобы у вас всегда оставался некоторый резервный запас свободной памяти (резерв безопасности), оставляющий простор для маневров, что будет гарантией эффективного выполнения вашего приложения в самых различных ситуациях. Необходимость такого подхода диктуется тем, что в типичных условиях ваше приложение не имеет возможности полностью контролировать всю установленную на устройстве память; память находится в совместном распоряжении операционной системы и всех приложений, которые могут одновременно выполняться пользователем. Если какое-то приложение распределяет и удерживает лишние объемы памяти, то от этого будет страдать производительность всех приложений. Не занимайте больше памяти, нежели требуется, и освобождайте те ее излишки, непосредственная необходимость в которых отпалаБудут ли меня преследовать те же проблемы, если я пишу приложение на основе собственного кода?
В отличие от сред выполнения управляемого кода (.NET Compact Framework, Java и так далее), при разработке приложений в собственных кодах сборка мусора не используется. Однако это вовсе не означает, что в этом случае вам удается соскочить с крючка; напротив — нагрузка на стадии проектирования, вероятнее всего, только увеличится! При выполнении на настольных компьютерах приложения, основанные на собственных кодах, пользуются всеми преимуществами, которые неявно предоставляет операционная система, осуществляя обмен страницами ОЗУ с дисковым файлом подкачки. В результате этого, хотя выполнение приложения и может замедляться, оно при любых условиях сохраняет свою работоспособность. Если же ваше мобильное приложение превысит допустимые пределы расхода памяти, то оно просто-напросто исчерпает все ее резервы и завершится сбоем. Отсюда следует, что при разработке мобильных приложений, основанных на собственных кодах, разработчик должен заранее предпринять меры, позволяющие избежать возникновения подобных ситуаций. Кроме того, алгоритмы на основе собственного кода, которые без особой на то необходимости распределяют и освобождают память лишь потому, что были неудачно спроектированы, будут вынуждены бороться с проблемами фрагментации памяти, что также приведет к снижению производительности. В то время как среды времени выполнения управляемого кода могут справляться с фрагментацией памяти за счет ее уплотнения в процессе сборки мусора, в случае собственных кодов аналогичные встроенные возможности отсутствуют. А это означает, что вы должны сами продумать детальную схему управления памятью и самостоятельно ее реализовать.
Хранить в памяти неиспользуемые объекты слишком расточительно, поскольку они занимают место, которое можно было бы использовать с большей эффективностью для активных составляющих вашего приложения. С другой стороны, было бы слишком легкомысленно освобождать память от объектов сразу же после того, как непосредственная необходимость в них исчезла.Не решатся ли обсуждаемые проблемы сами по себе с приходом мобильных устройств "следующего поколения"?
Добавочная память стоит денег, увеличивает тепловыделение, потребляет электроэнергию и занимает в устройстве дополнительное место. Со временем ситуация в отношении каждого из этих факторов будет только улучшаться, но с ними всегда надо будет считаться. В соответствии с законом Мура, согласно которому каждое очередное поколение вычислительных устройств будет предоставлять нам все более широкие возможности при меньшей стоимости, для мобильных устройств всегда будет характерна ярко выраженная тенденция к снижению стоимости, уменьшению размеров и увеличению продолжительности непрерывной работы после однократной зарядки батарей.
Большинство современных мобильных устройств уже располагают вполне приличными объемами памяти, обеспечивающими решение широкого круга задач, но этой памятью необходимо распоряжаться благоразумно. Очень часто плохие привычки, приобретенные в процессе проектирования приложений для настольных компьютеров, переносятся и на работу с мобильными устройствами. Это приводит к отсутствию строгого подхода к распределению памяти в алгоритмах и неэффективному управлению памятью, допускающему хранение в памяти ресурсов, которые больше не используются.
Ранее в этой книге мы уже использовали аналогию, в которой позволили себе сравнить современные настольные компьютеры с большими особняками в сельской местности, а мобильные устройства — с шикарно выглядящими, но небольшими городскими квартирами. Очень важно, чтобы вы никогда не забывали об этом образном примере, иллюстрирующем суть "размерных ограничений". Вы можете реализовать на мобильном устройстве почти все, что хотите, но вам не удастся сделать это сразу или немедленно завладеть всей памятью. Вы должны располагать набором определенных правил, регламентирующих то, какие вещи должны находиться в квартире, а какие должны быть вынесены из нее.
Последующие поколения мобильных устройств будут гораздо мощнее, и будут располагать большими объемами памяти, но от них все равно будет требоваться еще большее. Продуманные стратегии управления памятью будут по-прежнему оставаться ключевым фактором создания отличных мобильных приложений.
Являются ли растровые изображения "пользовательскими" данными или "служебными" данными приложения?
Поскольку данные растровых изображений представляют загруженные в память и готовые для использования в графике приложения изображения, они могут занимать много места. Держать растровые данные больших изображений может оказаться дорогим удовольствием, и поэтому следует уделить должное внимание тому, когда их следует загружать в память, а когда — освобождать память от них.
Некоторые типы растровых изображений являются пользовательскими данными. Например, если приложение предназначено для обслуживания сделок по продаже недвижимости и загружает в память изображения домов, то каждая фотография является уникальной и соответствует пользовательским данным, относящимся к данному объекту недвижимости. Наряду с адресом этого дома и его ценой она загружается вместе с остальной информацией об объекте. To же самое можно сказать об изображениях используемых в медицине, которые прилагаются к карточке пациента; каждое изображение связывается с пользовательскими данными.
Некоторые типы растровых данных являются служебными данными приложения. Растровые изображения, используемые для создания кнопок с привлекательным внешним видом, хранящиеся в кэш-памяти фоновые изображения, стандартные заготовки графических диаграмм — все эти объекты являются служебными данными приложения, поскольку они никак конкретно не связаны с теми данными, с которыми работает пользователь. К этой же категории следовало бы отнести и типовое растровое изображение человеческого тела, которое может использоваться в медицинском приложении для указания очагов болезни. Все эти ресурсы являются общими, и они не связаны ни с какими конкретными данными. Одни формы могут использовать эти ресурсы, другие — могут не использовать; данные изображений могут загружаться, а могут и игнорироваться в зависимости от режима работы приложения и не зависят от того, с каким именно набором данных работает пользователь
Некоторые типы растровых изображений могут быть отнесены к любой из двух названных категорий. Если у вас есть приложение для торговли недвижимостью, которое может отображать три разновидности изображений поэтажного плана в зависимости от того, какие пользовательские данные загружены, или медицинское приложение, в котором имеется шесть различных разновидностей изображений человеческого тела, соответствующих различным комбинациям пола, размеров и веса то перечисленные изображения можно рассматривать либо в качестве служебных данных приложения, либо в качестве пользовательских данных. Аналогично, если в вашей игре имеются растровые изображения для всех персонажей на экране, и эти изображения меняют свой внешний вид по мере перехода пользователя на более высокие игровые уровни, то одинаково убедительные аргументы могут быть выдвинуты и в пользу того, что данные изображения относятся к служебным данным приложения, и в пользу того, что они относятся к пользовательским данным. В подобных случаях вы должны выбирать для ресурсов ту модель памяти, которая больше всего подходит для вашего приложения. Помещайте изображения рассматриваемой разновидности в ту схему управления памятью, которая наилучшим образом соответствует вашим запросам.
Использование интерфейса IDisposable и освобождение дорогостоящих неуправляемых ресурсов в .NET Compact Framework
Если объект больше не используется, код вашего приложения может освободить его, удалив все ссылки, которые на него указывают. Занимаемая объектом память будет восстановлена, когда во время очередной сборки мусора (обычно это происходит тогда когда приложению необходимо распределить память) среда выполнения обнаружит, что на данный объект не указывает ни одна ссылка. Обычно такая схема вас будет вполне устраивать, но из нее следует, что удаление объектов из памяти может откладываться на неопределенное время и производиться лишь тогда, когда острая необходимость в дополнительной памяти заставит систему произвести сборку мусора. Поскольку мы не можем точно сказать, когда именно это произойдет, а, следовательно, и судить о том, когда именно будет удален объект, о времени жизни такого объекта в памяти говорят как о "недетерминированном". Недетерминированность очистки памяти от ненужных объектов является обычной проблемой систем управления памятью, использующих сборку мусора. Поэтому, как правило, следует избегать использования в логике приложения кода, выполнение которого связывается с вызовом деструктора объекта поскольку в этом случае приложение не может явно контролировать, когда именно будет выполнен такой код.
Проблемы могут возникать также в тех случаях, когда освобождаемый за ненадобностью объект представляет такой "дорогостоящий неуправляемый ресурс", как соединение с базой данных, файловый дескриптор или некоторый графический ресурс. До тех пор, пока объект не будет удален из памяти во время сборки мусора, неуправляемый ресурс, который он представляет, будет удерживаться приложением. Это может отрицательно сказываться на производительности системы как в отношении клиентского устройства, так и в отношении ресурсов сервера удерживаемых клиентом.
Для того чтобы справиться с этой проблемой, в .NET Compact Framework предусмотрена схема позволяющая коду явно освобождать базовый ресурс, удерживаемый объектом. Для всех объектов, которые представляют дорогостоящие ресурсы, предусмотрен метод Dispose(). Определение этого метода содержится в интерфейсе IDisposable; классы, поддерживающие детерминированный отказ от своих ресурсов, реализуют этот интерфейс и, таким образом, включают в себя метод Dispose().
Если объект имеет метод Dispose(), то вы всегда можете вызвать этот метод, если необходимость в использовании данного объекта в приложении отпала. Метод Dispose() должен вызываться тогда, когда вы собираетесь удалить любые переменные ссылки на него, чтобы предоставить сборщику мусора возможность удалить этот объект из памяти. Тем самым гарантируется, что дорогостоящий объект, представляемый ресурсом, будет немедленно освобожден. Как и в других ситуациях, имеющих отношение к управлению памятью, если в случае приложений для настольных компьютеров такой подход является просто плодотворным, то в случае мобильных приложений, испытывающих дефицит системных ресурсов (таких, например, как дескрипторы операционной системы). ею применение жизненно необходимо.
Точно так же, проектируя класс, который представляет дорогостоящий ресурс, вы должны реализовать интерфейс IDisposable, тем самым предоставляя коду, использующему этот класс, возможность детерминированного освобождения удерживаемых данным классом ресурсов. Для подробного ознакомления с деталями надлежащей реализации этого свойства обратитесь к той части документации .NET Compact Framework, в которой описывается метод IDisposable.Dispose().
На заметку! В языке C# введено специальное ключевое слово, упрощающее вызов метода Dispose() в тех случаях, когда область использования ресурса ограничивается блоком кода функции. Вместо обязательного явного вызова метода .Dispose() можно объявить соответствующую переменную с помощью ключевого слова using.
Например:
using(System.Drawing.Graphics myGfx = System.Drawing.Graphics.FromImage(myImage)) {
//Выполнение всей необходимой работы с помощью функции myGfx…
} // Метод myGfx.Dispose() вызывается здесь автоматически…
В случае использования такого объявления метод Dispose() вызывается автоматически при выходе за пределы области видимости переменной. Ключевое слово using очень удобно использовать в тех случаях, когда переменная существует только внутри некоторого блока кода.
Используя кэширование, руководствуйтесь здравым смыслом
Если предполагается многократное использование одних и тех же ресурсов внутри функции, то вызов функции (или свойства) кэшированного доступа всякий раз, когда требуется данный ресурс, является неэффективным. В подобных случаях лучше вызвать эту функцию один раз и хранить ресурс в локальной переменной в течение всего времени, пока в данном ресурсе будет существовать необходимость. Тем самым вы получаете выигрыш от того, что используете глобально кэшированный ресурс, а не создаете и уничтожаете ресурс внутри функции, и повышаете эффективность вычислений, поскольку избавляетесь от лишних вызовов функции в своем алгоритме. Здравый смысл подскажет вам, когда такой подход является оправданным.
"Структуры" и .NET Compact Framework
Во многих случаях, если вы хотите инкапсулировать некоторые простые данные, то для локальных переменных внутри функций гораздо эффективнее использовать не объекты, а структуры. Структура — это просто удобный способ сгруппировать в одном пакете взаимосвязанные данные, а не передавать их в виде отдельных переменных.
Структуры обладают более простыми свойствами по сравнению с объектами, но могут "упаковываться" в объекты и передаваться внутри программы так же, как они, если в этом возникает необходимость. Использование структур предоставляет определенные удобства и может привести к некоторому увеличению производительности (по сравнению с вариантом, когда используются объекты), но поскольку они выглядят, а во многих случаях и действуют подобно объектам и могут заключаться в объекты-оболочки, необходимо тщательно взвешивать, когда их следует использовать, чтобы избежать дополнительных накладных расходов и не создать лишнего мусора. В сомнительных случаях тестируйте алгоритмы, используя как отдельные переменные (например, базовые типы, подобные int, string, double), так и структуры, чтобы сравнить производительность приложения в обоих случаях и убедиться в том, что она остается примерно одинаковой.
Более подробную информацию по этому вопросу вы можете получить, обратившись к разделам справочной документации .NET Compact Framework, посвященным типам значений ("value types") и структурам ("struct"). Ниже приводится пример с объявлениями структуры и класса:
//Примечание. В VB.NET это был бы тип (type), а не структура (struct)
//Это структура
struct MyRect_Type {
public int x;
public int у;
}
//Это класс
class MyRect_Class {
public int x;
public int у;
}
//Код примера
class TestClass {
public void foo() {
//Требуется распределять как объект
MyRect_Class myRectClass = new MyRect_Class();
myRectClass.x = 1;
myRectClass.y = 2;
//Этот оператор распределяет новый объект
myRectClass = new MyRect_Class();
//Можно объявить как скалярный тип
MyRect_Type myRectType;
myRectType.x = 1;
myRectType.y = 2;
//Этот оператор обнуляет значения в структуре, но не
//распределяет память для нового объекта!
myRectType = new MyRect_Type();
}
Предшествующий код оставляет возможности для внесения дальнейших улучшений
Предыдущий подход все еще демонстрирует значительную напрасную трату ресурсов, поскольку мы постоянно размещаем и освобождаем строки. Если мы собираемся создать код, обеспечивающий высокую производительность, то от создания лишних строковых объектов следует избавиться.
Порядковый номер теста | Неэкономное распределение памяти | Незначительное уменьшение объема распределяемой памяти | Значительное уменьшение объема распределяемой памяти |
---|---|---|---|
1 | 12,65 | 12,2 | 8,925 |
2 | 12,775 | 12,35 | 8,55 |
3 | 12,575 | 12,25 | 8,225 |
4 | 12,625 | 12,525 | 8,575 |
Среднее | 12,65625 | 12,33125 | 8,56875 |
Экономия времени по сравнению с базовым уровнем | 0% | 2,57% | 32,30% |
Порядковый номер теста | Неэкономное распределение памяти | Незначительное уменьшение объема распределяемой памяти | Значительное уменьшение объема распределяемой памяти |
---|---|---|---|
1 | 30,609 | 30,151 | 20,484 |
2 | 30,538 | 30,016 | 20,362 |
3 | 30,517 | 30,195 | 20,377 |
4 | 30,457 | 30,316 | 20,429 |
Среднее | 30,53025 | 30,1695 | 20,413 |
Экономия времени по сравнению с базовым уровнем | 0% | 1,18% | 33,14% |
Порядковый номер теста | Неэкономное распределение памяти для строк | Использование класса StringBuilder |
---|---|---|
1 | 25,475 | 0,85 |
2 | 25,225 | 0,925 |
3 | 24,5 | 0,875 |
Среднее | 25,07 | 0.88 |
Экономия времени по сравнению с базовым уровнем | 0% | 96,5% |
Порядковый номер теста | Неэкономное распределение памяти для строк | Использование класса StringBuilder |
---|---|---|
1 | 22,502 | 6,257 |
2 | 22,34 | 6,346 |
3 | 22,378 | 6,35 |
Среднее | 22,41 | 6,32 |
Экономия времени по сравнению с базовым уровнем | 0% | 71,8% |
Время пожирает все.Овидий (43 до н.э.–17 н.э.), римский поэт(Encarta 2004, Quotations)
Что можно сказать об оборудовании, поддерживающем несколько процессоров?
На многих серверах и некоторых настольных компьютерах устанавливаются несколько микропроцессоров. "Многоядерные" ("multicore") системы с дополнительными микропроцессорами становятся все более распространенными; такие микропроцессоры размещаются на одном кристалле и предоставляют многие из тех преимуществ, которые обеспечиваются наличием нескольких физически независимых процессоров. Многопроцессорные системы обеспечивают возможность подлинно одновременного выполнения кода.
Нет ничего невероятного в том, что в будущем эта тенденция коснется и мобильных устройств. В то время как факторы стоимости и энергопотребления тормозят появление на мобильных устройствах нескольких физических центральных процессоров, возможность использования многоядерных процессоров несколько снижает остроту этих проблем. Тем не менее, эффективное использование мультипроцессоров требует специальной поддержки со стороны операционной системы — задача далеко не тривиальная. До настоящего времени поддержка нескольких микропроцессоров не стояла на повестке дня для большинства операционных систем мобильных устройств; вместо этого указанные операционные системы были ориентированы на компактность и эффективность, а не на возможности параллельного выполнения вычислений на нескольких процессорах.
Тем не менее, иногда задают вопрос: "Если на вычислительном устройстве установлено несколько процессоров, то стоит ли использовать в приложении несколько потоков для ускорения вычислений?" На этот вопрос следует ответить так же, как и при проектировании приложений для однопроцессорных устройств: "Вероятно, не стоит. Использовать несколько потоков следует тогда, когда это делается в интересах асинхронного выполнения некоторых операций". Даже в случае многопроцессорных систем, на которых установлена операционная система, поддерживающая параллельные вычисления, многопоточное выполнение еще не является гарантией лучшей производительности. На то есть две причины:
1. Кроме вашего приложения, операционная система почти всегда выполняет другие процессы, а также заботится о собственных нуждах и осуществляет учет использования ресурсов задачами, например, управляет низкоуровневыми драйверами устройств и планирует задачи. Это означает, что ваше приложение не может рассчитывать на то, что в любой момент времени всеми процессорами, установленными на устройстве, будут распоряжаться только его потоки. Введение дополнительного процесса или потока просто создает "еще один рот", который операционная система, уже и так разделяющая свои вычислительные ресурсы между различными многочисленными задачами, должна накормить. Без получения от операционной системы специального разрешения на выделение процессора определенному потоку выполнения ваше приложение просто создает дополнительный запрос на использование доступных процессорных ресурсов.
2. Практическое проектирование надежных алгоритмов параллельных вычислений представляет собой непростую задачу. Разбиение вычислений на ряд независимых ветвей выполнения и их эффективная координация весьма затруднительны и являются предметом непрекращающихся исследований. Если несколько потоков выполняют различные части одной и той же задачи, то существует значительный риск того, что они где-то пересекутся, пытаясь одновременно получить доступ к одной и той же области памяти или стремясь использовать некоторый ресурс, не допускающий параллельного доступа.
Параллельное выполнение лучше всего применять тогда, когда параллельные задачи не могут мешать друг другу. Именно поэтому серверы нередко только выигрывают от использования нескольких процессоров; серверы часто обслуживают множество независимых и не вступающих между собой в конфликт клиентских запросов. Серверы, располагающие несколькими процессорами, способны параллельно отвечать на многочисленные запросы, одновременно поступающие от разных клиентов. Параллельные задачи, выполнение которых запрашивается, часто связаны только с операциями чтения или изменением данных, которые не перекрываются между собой. Оба вида задач хорошо соответствуют идее параллельных вычислений. Приложения, выполняющиеся на таких серверах, часто располагают пулами потоков, или потоковыми пулами, используемыми для диспетчеризации поступающих запросов.
Приложения с многофункциональными клиентскими пользовательскими интерфейсами обычно не относятся к категории тех, для которых разделение работы на параллельно выполняющиеся части легко осуществить, поскольку такие приложения обычно используются для того, чтобы предоставить возможность одному пользователю работать с набором взаимосвязанных данных и элементами пользовательского интерфейса. Задача приложения, ориентированного на настольные компьютеры, как правило, состоит также в том, чтобы как можно эффективнее реагировать на запросы пользователя, а не служить многим пользователям, соперничающим между собой за разделение процессорного времени между независимыми параллельными задачами.
Если в приложении имеются операции, которые могут выиграть от выполнения в асинхронном режиме, то использование нескольких потоков может оказаться целесообразным независимо от количества установленных процессоров. Основной вопрос заключается в том, стоят ли преимущества асинхронного выполнения тех затрат, с которыми будет связано дополнительное усложнение вашего приложения. Наличие нескольких процессоров на клиентских вычислительных устройствах означает наличие дополнительных рабочих рук, что способствует повышению общей производительности устройства. В случае "толстых" клиентов рассматривать эти процессоры как выделенные ресурсы, которые могут назначаться различным частям вашего приложения, имеет смысл лишь в редких случаях.
НА ЗАМЕТКУСоздать новый поток для выполнения фоновой обработки или использовать встроенную поддержку потокового пула значительно проще, чем спроектировать собственный нестандартный потоковый пул и организовать управление им. С использования этих подходов я и рекомендовал бы вам начинать, если требуется фоновая обработка. Единственный недостаток явного создания нового потока для выполнения фоновой задачи — это дополнительные накладные расходы, обусловленные созданием и разрушением потоков по запросу. В большинстве случае этот эффект будет пренебрежимо малым, но простота решения делает этот выбор оправданным. Лишь в тех случаях, когда вы твердо уверены в том, что подход, основанный на создании потоков только тогда, когда это действительно необходимо, не в состоянии удовлетворить ваши запросы, следует проанализировать возможность применения подхода, связанного с использованием собственного потокового пула. Начинайте с самого простого и привлекайте более сложные средства лишь тогда, когда необходимость этого для вас является совершенно очевидной.
В версии NET Framework для настольных компьютеров имеется встроенная поддержка потоковых пулов. В этой модели для передачи выполнения работы ожидающему потоковому пулу используются "асинхронные делегаты". В версии 1 1 .NET Compact Framework поддержка универсальных асинхронных делегатов отсутствует.
Программисты на С/С++ могут рассматривать делегаты как аналоги указателей на функции. Программисты на LISP могут считать их аналогичными оболочкам. Делегаты позволяют задать привязку к методу определенного объекта и впоследствии вызвать этот метод, не ссылаясь на объект или имя конкретного метода. .NET Compact Framework обеспечивает поддержку делегатов. Асинхронные делегаты позволяют выполнять в асинхронном режиме методы, с которыми они связаны, с использованием потока из пула фоновых потоков. Указанный потоковый пул управляется средой времени выполнения. Асинхронные делегаты являются превосходным средством абстрагирования, поскольку освобождают разработчика от необходимости самостоятельного проектирования и тестирования собственных механизмов управления потоковыми пулами. Поскольку .NET Compact Framework с самого начала предназначалась для выполнения на устройствах с ограниченными ресурсами, взаимодействие между потоками для передачи параметров, что требуется при использовании асинхронных делегатов общего назначения, проектным решением для версии 1.1 не предусматривалось. Если вы хотите поддерживать потоковый пул, используя .NET Compact Framework, и выполнять фоновые задачи с использованием управляемых потоков, то можете это осуществить путем явного вызова метода System.Threading.ThreadPool.QueueUserWorkItem().
Вместо поддержки универсальных асинхронных делегатов в NET Compact Framework предусмотрена встроенная поддержка выполнения некоторых часто запрашиваемых задач в асинхронном режиме. В отношении таких задач, как создание HTTP-запроса данных с Web- сервера, поддержка асинхронного режима в .NET Compact Framework и .NET Framework совпадает. Кроме того, поддерживается класс System.Threading.Timer, обеспечивающий выполнение делегатов таймера фоновыми потоками. (Управляет этими потоками среда времени выполнения.) Таким образом, несмотря на то. что универсальные асинхронные делегаты в версии 1.1 NET Compact Framework не поддерживаются, в этой версии реализована поддержка конкретных асинхронных вызовов для большинства наиболее распространенных задач.
Заблаговременное прогнозирование потребностей пользователя
Заблаговременное выполнение части работы, в которой заинтересован пользователь, может требовать от вас определенного мастерства, но и положительный эффект от этого может оказаться значительным. Если этот подход реализован так, как следует, то пользователям почти никогда не представится случая по достоинству оценить, какая громадная работа для этого вами проделана; точно так же здоровый человек почти никогда не обращает внимания на то, как работает его сердце.
В качестве хорошего примера можно привести программу для просмотра изображений в Windows XP. Окно этой программы появляется сразу же после того, как вы дважды щелкнете мышью на имени файла изображения в окне проводника. В результате этого изображение загружается и отображается на экране. Одновременно с этим, но незаметно для пользователя и без какой-либо инициативы с его стороны, после вывода на экран первого изображения на фоне загружается также изображение, файл которого размещен в каталоге вслед за первым. Если следующим действием пользователя, которое можно считать наиболее вероятным, будет щелчок на кнопке Next Image (Следующее изображение) в программе для просмотра изображений, то следующая фотография незамедлительно появится на экране без видимой задержки. В случае современных крупных цифровых фотографий, загрузка, распаковка и масштабирование которых требуют значительного времени, это не такое уж и малое достижение. Описанная заблаговременная загрузка производится в основном только для изображений, которые располагаются следующими в списке файлов каталога изображений. Если вы щелкнете на кнопке Previous Image (Предыдущее изображение), то, вероятнее всего, увидите на экране сообщение "Generating preview" ("Генерируется изображение предварительного просмотра"), появляющееся на короткое время на экране при загрузке фотографии по требованию. Переходы в обратном направлении используются менее часто и поэтому не оптимизируются. Поскольку для цифровых изображений могут требоваться значительные ресурсы памяти, осуществление предварительной загрузки большого количества изображений в предвидении того, что пользователь может захотеть их просмотреть, на сегодняшний день вызывает затруднения. Аналогичным образом, то же самое сообщение "Generating preview" будет появляться на экране, если вы выполните ряд быстрых последовательных щелчков на кнопке Next Image, требующих загрузки очередных изображений; это объясняется тем, что вы требуете большего, чем позволяют возможности средств опережающего просмотра в отношении загрузки следующих фотографий. В большинстве случаев, прежде чем переходить к следующей фотографии, текущую фотографию рассматривают хотя бы в течение одной-двух секунд, и именно для такого сценария и была предусмотрена оптимизация.
Оптимизация загрузки изображений программой просмотра основывается на вполне разумных предположениях:
1. В большинстве случае порядок просмотра фотографий соответствует продвижению по списку в прямом направлении.
2. Обычно каждую фотографию рассматривают достаточно долго для того, чтобы система успела выполнить фоновую загрузку следующей фотографии.
Независимо от того, используется ли в программе просмотра изображений Windows XP фоновый поток для решения этой задачи или не используется (мне это неизвестно), она демонстрирует пример разумного применения асинхронной обработки для оптимизации рабочего процесса в случае наиболее распространенных действий. Прекрасная работа!
НА ЗАМЕТКУЧтобы создать и запустить указанное приложение, выполните следующие действия:
Если вы используете Visual Studio .NET 2003, то вам необходимо загрузить SDK для Windows Mobile 2003-based Smartphones. Visual Studio NET 2003 поставлялась с "коробочным" вариантом средств разработки приложений для Pocket PC, но не для Smartphone. Поскольку SDK для Smartphone поставлялся после выхода Visual Studio .NET 2003, его следует загрузить и установить поверх Visual Studio .NET. Пакет SDK можно бесплатно загрузить с Web- сайта компании Microsoft (см. приложение А). Этот SDK включает в себя компоненты, необходимые для проектирования пользовательских интерфейсов Smartphone, а также эмулятор Smartphone, позволяющий выполнять приложения, даже если вы не располагаете физическим устройством Smartphone.
Чем XMLReader и XMLWriter отличаются от SAX?
В .NET Framework и .NET Compact Framework реализован подход, основанный на использовании программного курсора, при котором алгоритмы конечного разработчика отдают объекту XMLReader команды относительно перемещения курсора в прямом направлении и синтаксического анализа очередных элементов XML-данных, однако это не единственный из подходов, в которых используется однонаправленная обработка XML- данных. Другим популярным подходом аналогичного рода является модель SAX (Simple API for XML Model — простой API-интерфейс для работы с XML). В то время как при работе с XMLReader используется подход на основе программного курсора, предоставляющий программисту возможность выбирать, как и когда перемещаться курсору в прямом направлении, SAX представляет собой модель, основанную на событиях, в которой механизм синтаксического анализа выполняет проход по всему XML-документу (также только в прямом направлении) и генерирует события, которые код конечного разработчика может обрабатывать для исследования содержимого XML-документа в ходе его анализа. Модель XMLReader основана на "извлечении" данных, то есть код приложения извлекает очередную порцию XML-данных, которые необходимо обработать. Модель SAX основана на "выталкивании" данных, то есть порции XML-данных передаются событиям, которые обрабатываются кодом приложения. Обе модели преследуют одну и ту же цель, а именно — облегчить быстрое выполнение синтаксического анализа XML-документов при низких накладных расходах. Выбор между моделями SAX и XMLReader/XMLWriter определяется личными предпочтениями и доступностью соответствующих средств на платформе, с которой вы работаете. Приведенные в данном разделе рекомендации в равной степени справедливы для обеих моделей.
Почему в версии 1.1 .NET Compact Framework не поддерживаются XSLT и XPath?
При проектировании .NET Compact Framework ставилась цель найти разумный компромисс между двумя проектными ограничениями. Необходимость сведения к минимуму размера NET Compact Framework (объем установленного на устройстве программного обеспечения не должен был превышать 2 Мбайт) вступала в противоречие со стремлением предоставить разработчикам как можно более широкие функциональные возможности. В процессе поиска компромиссных решений степень полезности тех или иных средств и необходимость в них тщательно взвешивались с точки зрения соответствующего увеличения размера .NET Compact Framework. Исходя из этих соображений и было решено, что в первом выпуске NET Compact Framework средства XPath и XSLT поддерживаться не будут.
XPath — это язык запросов, используемый для проведения поиска в XML-документах. Этот язык предоставляет очень широкие возможности поиска, но отличается сложностью, и для его эффективного использования требуется значительная вычислительная мощность. XSLT — это технология преобразования дерева XML-документа в новый документ в соответствии с определенными правилами; эту технологию часто применяют для преобразования XML-данных в HTML-документы. Для его эффективного функционирования также требуются значительные вычислительные ресурсы.
Полезность обоих указанных средств совершенно очевидна, и каждому разработчику хотелось бы иметь их в своем распоряжении, но было ли бы уместным их применение в случае мобильных приложений, выполняющихся на устройствах в условиях дефицита ресурсов? Поддержка XSLT и XPath лишь привела бы к напрасному увеличению размера .NET Compact Framework, поскольку предоставляемые разработчику функциональные возможности не могли бы эффективно использоваться во многих задачах, для которых они предназначены. Именно из этих соображений и было решено не включать поддержку XPath и XSLT в версию 1.1 .NET Compact Framework.
Не исключено, что поддержка этих средств появится в последующих версиях .NET Compact Framework; в частности, существует настоятельная потребность в поддержке XPath. Однако разработчикам следует хорошенько подумать о том, с какими трудностями им придется столкнуться, если они решатся на использование пусть и ценных, но весьма требовательных в отношении необходимых вычислительных ресурсов библиотек. Обычно считается, что встроенные средства среды выполнения должны нормально функционировать при любых обстоятельствах, однако это далеко не так. Вспомните данные ранее в этой главе рекомендации относительно необходимости тщательно взвешивать достоинства и недостатки удобного, но требующего использования обширной информации о состоянии подхода, основанного на модели XML DOM, и более сложного, но менее зависимого от состояния подхода, основанного на однонаправленном доступе к данным с помощью объектов XMLReader и XMLWriter; руководствуйтесь этими же советами и тогда, когда возникает проблема выбора зависящей от состояния или требовательной к ресурсам библиотеки. Вы можете использовать такую библиотеку, но всегда оценивайте, с какими дополнительными расходами это будет сопряжено, и проводите соответствующие измерения.
М-р Брэддок: "Скажи-ка мне, ради чего тогда надо было так тяжко трудиться последние четыре года?"
Бенджамин Брэддок: "Ты меня достал…""Выпускник" (The Graduate) (1967)
Элен Робинсон: "Я не хочу, чтобы ты брался за что- либо без четко составленного плана"."Выпускник" (1967)
Использование элементов управления TreeView и ListView среды .NET Compact Framework для повышения производительности приложений
Элементы управления TreeView и ListView используются для отображения наборов взаимосвязанных данных в пользовательских интерфейсах. Поскольку эти элементы управления работают с наборами данных, часто возникает необходимость в добавлении к ним или удалении из них сразу целых групп элементов данных. Для обоих элементов управления предусмотрены высокопроизводительные методы, позволяющие эффективно решать подобные задачи.
• .BeginUpdate()/EndUpdate(). Оба эти метода присутствуют как в TreeView, так и в ListView, и предназначены для приостановки и возобновления автоматической перерисовки элемента управления на экране. Вызов метода BeginUpdate() указывает на то, что элемент управления не должен автоматически перерисовываться всякий раз, когда в него добавляются или из него удаляются элементы данных, тогда как вызов метода EndUpdate() восстанавливает режим автоматической перерисовки элемента управления. Выполнение необязательных операций перерисовки экрана может отрицательно сказываться на производительности приложения. Если в процессе работы вашего приложения возникает необходимость в помещении в элемент управления или исключении из него многочисленных данных, то соответствующий участок кода целесообразно окружить парой вызовов BeginUpdate() и EndUpdate().
• .AddRange(). Для коллекции узлов элемента управления TreeView предусмотрен метод AddRange() (например, treeView1.Nodes.AddRange()), обеспечивающий групповое добавление узлов в TreeView. Такой "пакетный" режим обработки является гораздо более предпочтительным по сравнению с простым итеративным добавлением каждого узла по отдельности.
Используя эти эффективные встроенные механизмы, вы можете добиться существенного выигрыша в отношении как производительности, так и бесперебойности работы пользовательского интерфейса. Если с каким-либо элементом управления приходится работать особенно часто, то стоит просмотреть список его свойств и методов, чтобы выяснить, не найдутся ли среди них такие, использование которых позволит увеличить производительность.
Представленный в листинге 11.1 код состоит из набора обработчиков событий для различных кнопок, которые имеются на вашей форме. Фактические имена используемых функций будут происходить от имен, присвоенных соответствующим кнопкам. В своем коде я использовал для кнопок следующие имена: UnOptimizedFill, UnOptimizedClear, UseBeginEndUpdateForFill, UseBeginEndUpdateForClear и FillArrayBeforeAttachingToTree. Если вы используете заданные по умолчанию имена, которые предложит вам Visual Studio .NET, то у вас будут кнопки с именами button1, button2, button3, button4 и button5 и функции обработчиков событий с другими именами, которые надо будет соответственно изменить.Visual Studio .NET автоматически создаст и свяжет с кнопкой пустой обработчик событий
Все, что вы должны для этого сделать — это дважды щелкнуть на кнопке формы. Имя добавленной функции будет состоять из имени элемента управления (например, button1) и суффикса _Click. Visual Studio выполнит следующее: 1) создаст для вас функцию обработчика событий, 2) запишет код в функцию InitializeComponent() формы, предназначенную для подключения только что созданного обработчика события щелчка, и 3) откроет окно редактора кода, чтобы вы могли ввести в нем код для обработчика события. При желании вы можете назвать кнопку по-другому, изменив свойство Name в окне Properties (окно справа на рис. 11.1). Целесообразно сделать это до двойного щелчка на кнопке с целью создания и подключения обработчика события, поскольку функция обработчика создается с использованием текущего имени элемента управления. Если имя элемента управления будет изменено уже после создания этой функции, обработчик по-прежнему останется связанным с ним должным образом, но его имя не будет согласовываться с новым именем элемента управления. Обеспечить совпадение имен в этом случае вам придется вручную; сделать это не составляет особого труда, но для этого вам придется выполнить лишнюю работу.
Номер теста | Не оптимизированный подход | Использование методов BeginUpdate()/EndUpdate() | Использование массива |
---|---|---|---|
1 | 40,785 | 12,484 | 10,388 |
2 | 40,533 | 12,322 | 10,419 |
3 | 40,878 | 13,343 | 11,686 |
Среднее | 40,732 | 12,716 | 10,831 |
Экономия времени по сравнению с базовым значением | Базовое значение (0%) | 68,78% | 73,41% |
Номер теста | Не оптимизированный подход | Использование методов BeginUpdate()/EndUpdate() |
---|---|---|
1 | 18,791 | 8,656 |
2 | 15,910 | 8,964 |
3 | 16,821 | 8,516 |
Среднее | 17,174 | 8,712 |
Экономия времени по сравнению с базовым значением | Базовое значение (0 %) | 49,27 % |
.NET Compact Framework: не все поддерживаемые обработчики прерываний предоставляются конструктором форм Visual Studio .NET
Платформа .NET Compact Framework поддерживает подмножество управляющих событий платформы .NET Compact Framework, ориентированной на настольные компьютеры. Следует отметить, что одно лишь наличие в .NET Compact Framework сигнатуры какого-либо события еще не является гарантией того, что это событие может быть возбуждено во время выполнения. Могут существовать специфические условия совместимости или причины, связанные со свойствами объектного наследования, в силу которых определение события необходимо было связать с элементом управления, но само событие запускаться во время выполнения в .NET Compact Framework не будет. Единственный способ прояснения подобных ситуаций состоит в том, чтобы подключить событие к элементу управления и посмотреть, будет ли оно запущено во время выполнения. Эта ситуация дополнительно осложняется тем фактом, что не все события, поддерживаемые платформой .NET Compact Framework, отражаются в графической среде проектирования Visual Studio .NET. Среди поддерживаемых событий имеются и такие, которые не фигурируют в списке событий C# в панели свойств или в выпадающем списке событий Visual Basic .NET в редакторе кода.
События, отображаемые в среде проектирования, должны поддерживаться платформой .NET Compact Framework, но имеется ряд дополнительных событий, которые .NET Compact Framework поддерживает, но не отображает. Причиной такого поведения явилась недостаточная координация работ над этим проектом: группа, работающая над средствами проектирования, и группа, работающая над средой выполнения, не смогли идеально организовать взаимодействие между собой! (Надеюсь, что в процессе дальнейшего усовершенствования платформы подобная ситуация уже не повторится.) Большинство обычных событий отображаются в окне конструктора форм, но некоторые специфические события могут требовать подключения их к форме вручную. Сделать это несложно, но для этого надо хотя бы немного знать о том, как осуществляется подключение обработчиков событий.
Если вы хотите использовать событие, которое поддерживается в .NET Compact Framework, но не предлагается в качестве доступного в среде проектирования Visual Studio .NET, вам придется вручную вставить одну строку кода в функцию InitializeComponent() формы, содержащей данный элемент управления. Функцию InitializeComponent() вы найдете в обычно скрытом или свернутом разделе "Windows Form Designer-Generated Code" редактора кода класса.
Добавление обработчика событий BeforeExpand в элемент управления TreeView иллюстрирует приведенный ниже фрагмент кода:
#region Windows Form Designer generated code
private void InitializeComponent()
… строки кода для других элементов управления …
//
// treeView1
//
this.treeView1.ImageIndex = -1;
this.treeView1.Location = new System.Drawing.Point(72, 48);
this.treeView1.Name = "treeView1";
this.treeView1.SelectedImageIndex = -1;
this.treeView1.Size = new System.Drawing.Size(168, 176);
this.treeView1.TabIndex = 0;
//ОДНОСТРОЧНЫЙ КОД ДЛЯ ПОДКЛЮЧЕНИЯ СОБЫТИЯ, КОТОРЫЙ ВЫ ДОЛЖНЫ ВСТАВИТЬ
this.treeView1.BeforeExpand += new.System.Windows.Forms.TreeViewCancelEventHandler(this.TreeView1BeforeExpand);
… строки кода для других элементов управления …
Представленный выше код подключает обработчик события BeforeExpand элемента управления treeView1. Функция обработчика события должна иметь специальную сигнатуру. В данном случае она имеет следующий вид:
private void TreeView1BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e) {}
Неплохим способом обеспечения автоматической генерации обоих вышеприведенных фрагментов кода является использование проекта Windows Application для настольных компьютеров. В Visual Studio .NET проекты для настольных компьютеров поддерживают графический способ создания и подключения всех поддерживаемых обработчиков прерываний. Сгенерированный при этом код вы далее можете скопировать и вставить в соответствующие части своего проекта .NET Compact Framework.
Заслуживает рассмотрения и слегка видоизмененный вариант описанной выше стратегии. Поскольку конструктор форм автоматически вставляет и удаляет код внутри функции InitializeComponent(), существует вероятность того, что он добавит свой код поверх добавленного вами кода. Чтобы этого избежать, может оказаться целесообразным создать собственную функцию (например, MyInitializeComponent()), чтобы вставить в нее свой код, выполняющий все действия по инициализации, и вызвать эту функцию в коде конструктора формы сразу же после вызова InitializeComponent(). Благодаря этому вы сможете быть уверены в том, что ваш код не будет случайно удален конструктором форм.
НА ЗАМЕТКУ
При выполнении приложения на платформе .NET Compact Framework 1.1 в случае установки значения свойства Text элемента управления TextBox программным путем событие TextChanged в действительности запускается дважды.
Выполнение того же кода на настольном компьютере сопровождается только однократным запуском указанного события. Вероятно, поведение последующих версий NET Compact Framework будет изменено таким образом, чтобы оно совпадало с поведением .NET Framework (однократный запуск события). События — коварная вещь. Будьте очень внимательны в своих предположениях относительно того как и когда запускаются события.
Уменьшение размера файла: достижение баланса между степенью сжатия и разрешением изображения
Для уменьшения размеров файлов цифровых изображений используют три способа:
1. Снижение разрешения. Суть этого способа заключается в уменьшении фактического количества пикселей, составляющих изображение. Если в Windows XP войти в программу Paint, выбрать в меню Рисунок пункт Растянуть/наклонить и уменьшить изображение до 50% его первоначальной ширины, то количество пикселей в изображении уменьшится наполовину. Уменьшив далее изображение до 50% его первоначальной высоты, вы еще раз уменьшите его разрешение в два раза. Теперь количество пикселей в полученном изображении будет составлять 25% от первоначального (0,5×0,5 = 0,25). Уменьшение количества пиксельных данных, подлежащих сохранению, означает уменьшение общего размера изображения.
2. Выбор наиболее подходящего формата файлов. Различные разновидности распространенных файловых форматов отличаются друг от друга своей способностью сжимать различные изображения. Одни форматы хорошо подходят для фотографий (множество цветовых оттенков, мало резких границ), другие больше всего пригодны для сохранения компьютерной графики (резкие границы изображений, небольшое количество цветовых оттенков). В некоторых форматах сжатие изображений вообще не применяется. Выбор наиболее подходящего формата позволит обеспечить наилучшее качество изображения при минимальном размере.
Некоторые файловые форматы обеспечивают дополнительную возможность выбора глубины цвета сохраняемого изображения. Глубина цвета представляет собой количество битов, используемых для описания изображения. Если можно обойтись меньшим количеством цветов, то выбор меньшей глубины цвета позволит уменьшить размер файла.
3. Увеличение степени сжатия. Во многих случаях алгоритмы сжатия с потерей качества предоставляют возможность выбора приемлемой степени сжатия, обеспечивающей получение изображений желаемого качества.
Чтобы добиться снижения размера файла изображения, начните с разрешения. Уменьшите размер изображения, приведя его в соответствие с размерами экрана вашего устройства; благодаря этому вы сможете избавиться от ненужных данных. Далее, выберите подходящий формат файла, который обеспечивает наилучшее качество изображения при минимально возможном размере файла и минимальной глубине цвета. Наконец, если применяется метод сжатия с потерями, поэкспериментируйте с параметрами сжатия.
Различные подходы к реализации пользовательских интерфейсов в управляемых средах выполнения
Существуют два способа интеграции управляемой среды выполнения с графикой и моделью пользовательского интерфейса хоста. Среда выполнения может использовать готовые библиотеки элементов пользовательского интерфейса, поддерживаемые операционной системой, или же привлечь для выполнения этой работы собственные библиотеки.
.NET Compact Framework, выполняющаяся на устройствах, использующих операционные системы Windows СЕ, Pocket PC и Smartphone, предоставляет визуализацию большинства своих элементов управления пользовательского интерфейса и управление ими операционной системе. Под этим подразумевается что элементу управления Window платформы .NET Compact Framework соответствует элемент управления Window операционной системы Windows СЕ, элементу управления ListView платформы .NET Compact Framework — элемент управления ListView операционной системы Windows СЕ, элементу управления Button платформы .NET Compact Framework — элемент управления Button операционной системы Windows СЕ и так далее. Преимущества такого подхода обусловлены несколькими причинами:
1 Производительность. Специалисты по разработке операционных систем затратили много времени на проектирование и настройку элементов управления своих пользовательских интерфейсов. Добиться аналогичной производительности при перерисовке всех окон и элементов управления и обеспечить надлежащее управление их взаимодействием с пользователем путем самостоятельной реализации этих возможностей очень трудно.
2. Внешний вид и нюансы поведения. Элементы управления .NET Compact Framework обладают теми же поведенческими характеристиками, что и элементы управления базовой системы Windows. Реализация пользовательского интерфейса сопряжена с необходимостью принятия множества мелких решений наподобие: "Как именно должны прорисовываться пиксели при визуализации элемента управления? Что должно происходить, если выделить блок текста и нажать клавишу забоя, ввести букву, выполнить двойной щелчок на слове?" Добиться точного воспроизведения внешнего вида и нюансов поведения пользовательского интерфейса очень трудно, а вместе с тем люди очень чувствительны к малейшим отклонениям от того, к чему они привыкли.
3. Размер кода. Повторная реализация кода для перерисовки и манипулирования элементами управления, который уже предусмотрен в операционной системе, приведет к ненужному увеличению размера кода каркаса приложения. Привлечение для этих целей того, что уже имеется в операционной системе, позволяет сэкономить значительный объем рабочего пространства среды выполнения.
Несмотря на то что в .NET Compact Framework, выполняющейся на устройствах с операционными системами Pocket PC, Smartphone или Windows СЕ, реализация большинства элементов пользовательского интерфейса делегируется операционной системе, это вовсе не означает, что вы не имеете возможности создать совершенно новый элемент управления средствами каркаса приложения. В .NET Compact Framework можно создать графический элемент управления с нуля, и это делается в тех случаях, когда в базовой операционной системе аналогичный элемент управления отсутствует. Эту работу может выполнить конечный разработчик, но для таких элементов управления, как GridControl, она была выполнена и в .NET Compact Framework.
Описанный подход применяется не во всех управляемых средах выполнения. Некоторые из них получают от базовой операционной системы лишь пространство для рисования и самостоятельно организуют рисование элементов управления и манипулирование ими. Преимуществом такого подхода является то, что он позволяет обеспечить единообразие внешнего вида и поведения интерфейса на каком бы устройстве приложение ни выполнялось. К недостаткам реализации нестандартных пользовательских интерфейсов относятся увеличение размера приложения и накладных расходов, связанных с необходимостью выполнения дополнительной обработки, а также риск того, что внешний вид и нюансы поведения элементов управления не будут совпадать с аналогичными свойствами элементов управления базовой операционной системы. Суть дела здесь состоит в достижении некоего разумного компромисса.
Если .NET Compact Framework переносится на другую платформу (в процессе ее проектирования такая возможность заранее предполагалась), то она должна будет либо использовать возможности пользовательского интерфейса базовой операционной системы, либо предоставить свою реализацию этих элементов управления в виде библиотек на основе собственного или управляемого кода. По своим возможностям встроенной поддержки элементов управления пользовательского интерфейса операционные системы различных устройств существенно отличаются друг от друга, так что объем работы, которую при этом придется выполнить, и выбор стратегии проектирования оказываются в высшей степени зависящими от характеристик конкретной целевой операционной системы.
Четырехминутный практикум по работе с графикой в .NET Compact Framework
В документации к .NET Framework и .NET Compact Framework содержится обширная информация по работе с графикой, с которой вам обязательно стоит ознакомиться. Ниже приведены лишь самые основные сведения.
Рабочей лошадкой графики в NET является объект System.Drawing.Graphics. Если вы знакомы с методами разработки приложений в собственных кодах Windows, считайте, что это — объектно-ориентированная версия hDC (Device Context, контекст устройства). Чтобы нарисовать что-либо (например, фигуру, линию, текст, растровое изображение) на поверхности битовой карты, ваш код должен вызвать соответствующий метод объекта Graphics. Не менее важно знать о том, что после того как вы закончите работать с созданным перед этим объектом Graphics, необходимо освободить память от этого объекта при помощи вызова функции Dispose(), иначе он будет занимать драгоценные системные ресурсы. Для того чтобы постоянно держать под рукой какой-либо из объектов Graphics, у вас должны быть веские причины.
Если объект Graphics не создается, а передается, то обычно этот объект вам предоставляет вызывающая функция. В подобных случаях забота о том, чтобы освободить память от этого объекта с помощью метода Dispose(), обычно лежит не на вашем коде; при вызове метода Dispose() объекта, который все еще используется другим кодом, возникают проблемы. Наиболее распространенные ситуации, в которых объект Graphics передается другой функции, возникают, когда вы пишете обработчик Paint для нестандартного элемента управления или подключаетесь к обработчику Paint для формы или стандартного элемента управления. В этих случаях вы выполняете нужные операции рисования при помощи передаваемого вам объекта Graphics.
Перья (Pen), кисти (Brush), шрифты (Font), растровые изображения (Bitmap) также должны создаваться. Эти объекты не принадлежат какому-то одному объекту Graphics; одни и те же объекты могут использоваться различными объектами Graphics. Когда работа с этими объектами в вашем коде закончена, для них также необходимо вызывать метод Dispose(). Тем не менее, в случае мобильных приложений использование глобальных объектов Pen, Brush, Font или Bitmap, если они часто используются, может оказаться полезным и эффективным. Производительность приложения можно значительно повысить, применяя тщательно продуманную стратегию кэширования объектов.
Для указания атрибутов рисования визуализируемых объектов используется класс ImageAttributes. Он передается при помощи перегруженных методов Graphics.DrawImage() и позволяет вашему приложению устанавливать прозрачный цвет для битовых образов, копируемых на другую поверхность. Использование класса ImageAttributes на платформе .NET Compact Framework позволяет вашему приложению назначать один из цветов битового образа в качестве прозрачного; благодаря этому ваш код получает возможность визуализировать на битовых образах объекты, форма которых отличается от прямоугольной. Такая возможность оказывается очень полезной при написании игр. Как и в случае других классов, объекты ImageAttributes по окончании работы должны вызывать метод Dispose().
Обработчики событий или перекрытые функции?
Существует еще один способ подключения к запросам Paint. В приведенном выше примере для этого использовался подход, основанный на механизме наследования. Однако обработку событий Paint можно осуществлять и при помощи обработчика событий. Это выполняется точно так же, как и подключение к обработчику событий Click; для получения запросов событий необходимо зарегистрировать функцию. Если вместо перекрытия метода OnPaint() использовать обработчик событий, то в приведенный выше код необходимо внести три вида изменений:
1. Следует изменить имя и сигнатуру метода таким образом, чтобы они соответствовали тому, что требуется для обработчика событий Paint (например, protected void PaintEventHandler(object sender, PaintEventArgs e) вместо protected override void OnPaint(PaintEventArgs e)).
2. Вызов base.OnPaint (e) необходимо удалить, поскольку осуществление этого вызова не входит в обязанности обработчика событий. В действительности, именно базовая реализация base.OnPaint(e) вызывает любой зарегистрированный обработчик событий.
3. В функцию InitializeComponent формы необходимо добавить код для подключения нового обработчика событий. Например, добавьте такой код:
this.Paint += new System.Windows.Forms.PaintEventHandler(this.PaintEventHandler);
InitializeComponent();
Выбирая между обработчиком событий и механизмом наследования, вы можете руководствоваться собственными соображениями. Что касается меня, то для такой низкоуровневой работы, как подключение к обработке запросов перерисовки экрана (Paint), я предпочитаю использовать подход, основанный на механизме наследования, который мне более понятен. Для высокоуровневых событий, например щелчков (Click), я предпочитаю прибегать к подходу, основанному на использовании обработчиков событий, поскольку этот код автоматически генерируется для меня после двойного щелчка на элементе управления в окне конструктора форм.
НА ЗАМЕТКУ
Существует возможность сделать пользовательский элемент управления видимым на стадии проектирования!
В данном примере пользовательский элемент управления для простоты создается во время выполнения. Чтобы отобразить его для разработчика на стадии проектирования, в результате чего этот элемент управления будет виден в окне конструктора форм подобно любому другому стандартному элементу управления, в приложение следует кое-что добавить. Обсуждение этого вопроса выходит за рамки данной книги, однако соответствующая информация содержится в документации по .NET Compact Framework.Окно сообщения, появляющееся в ответ на запуск события щелчка на пользовательском элементе управления
HA ЗАМЕТКУ
Те, кого интересует исходный текст этого приложения, могут найти его на Web-сайте. Приложение было написано на языке VB.NET и названо "HankTheCaveMan" ("Пещерный человек Хэнк"). Оно позволяет продемонстрировать многие из концепций графики, которые обсуждаются в этой главе. Полный исходный код приложения доступен для загрузки на сайте обмена исходными кодами www.gotdotnet.com вместе с бесчисленным множеством других примеров и информации.
"Упрощение — это удаление ненужного, дабы нужное могло заговорить."Ганс Гофман (Hans Hofmann) (1880–1966), американский художник и преподаватель, немец по происхождению(Encarta 2004. Quotations)
Тип устройства | Типичное разрешение | Количество пикселей | Относительный размер |
---|---|---|---|
Настольные компьютеры/лэптопы | 1024×768 | 786432 | 100% |
Pocket PC | 240×320 | 76800 | 9,77% |
Смартфоны | 176×220 | 38720 | 4,92% |
Дополнительные эффекты с использованием прозрачных изображений
Выбор желтого цвета в качестве прозрачного был сделан совершенно произвольно. Точно так же в качестве прозрачного цвета можно было выбрать синий цвет и позволить скопироваться в изображении переднего плана всему, что имеет желтый цвет, а синий цвет трактовать как прозрачный. Кроме того, не сложно поменять местами битовые карты переднего и заднего планов, сделав желтые и синие прямоугольники и эллипсы задним планом, а черный и белый текст — передним; в этом случае нам потребовалось бы выбрать в качестве прозрачного черный или белый цвет, и, в зависимости от нашего решения, прозрачными были бы либо текст, либо его фон. Прозрачность — мощная штука, и ее можно с большим успехом применять в растровых изображениях самых различных видов.
Имена встроенных ресурсов чувствительны к регистру
Независимо от того, чувствителен ли к регистру используемый вами язык программирования (для C# регистр имеет значение, для VB.NET — нет), в именах встроенных ресурсов строчные и прописные буквы различаются. Тщательно следите за правильным использованием регистра букв в именах файлов, которые вы делаете встроенными ресурсами; при поиске потоков ресурсов во время выполнения ваше приложение будет использовать буквы в том же регистре, в котором вы их указали. Если потоки ресурсов не удается найти из-за несовпадения имен, то во время выполнения генерируется исключение. Ошибки подобного рода являются распространенными, и их поиск может заставить вас понервничать, если вы не знаете о том, что надо сразу же проверять, правильно ли указаны регистры букв.
Форматы хранения изображений и прозрачность растровых изображений
При использовании изображений в приложении очень важно правильно выбрать для них формат хранения. Для крохотных битовых образов (например, 8×8 пикселей) применение сжатия смысла не имеет, поскольку они и так малы. В случае более крупных изображений можно сэкономить довольно много места по сравнению с несжатыми форматами (например, *.BMP), используя сжатые форматы с потерями (например, *.JPG) или без потерь (например, *.PNG). Несжатые фоновые изображения с размерами порядка размеров экрана могут значительно увеличить общий размер приложения. Особое внимание следует уделять выбору форматов хранения для изображений, в которых один цвет будет считаться прозрачным во время выполнения; в таких случаях необходимо использовать только форматы со сжатием без потерь. Сжатие с потерями часто позволяет сэкономить много места, но этого удается достигнуть лишь ценой ослабления контроля за каждым отдельным пикселем изображения; вы получаете лишь приближенное изображение. Растровые изображения с областями прозрачности требуют точного указания цвета каждого пикселя.
Автор данной книги настаивает, что точно так же, как существует мало анекдотов о библиотекарях, отсутствуют и краткие, но содержательные высказывания в адрес баз данных или доступа к данным. Слишком уж утилитарен этот предмет. И пусть читатель попробует доказать автору, что он не прав.Иво Салмре
Какой способ хранения данных лучше использовать: флэш-память или файл в ОЗУ?
Для долговременного хранения информации на мобильных устройствах обычно используется одна из двух стратегий: флэш-память или файл в системном ОЗУ. Флэш-память — это память, в которой данные могут храниться в течение длительного времени, не требуя постоянного подвода питания. Конструктивно флэш-память может выполняться либо в виде съемной карты (например, Secure Digital, Compact Flash), либо в виде встроенного элемента устройства. В настоящее время флэш-память большой емкости встречается довольно часто; карты емкостью 512 Кбайт уже не являются диковинкой, причем их емкость продолжает расти. Кроме того, флэш-память потребляет меньше электроэнергии по сравнению с ОЗУ, поскольку не должна непрерывно выполнять электрическое обновление. В то же время, доступ к флэш-памяти осуществляется медленнее, чем к энергозависимой памяти; особенно это касается записи данных. Кроме того, биты информации, которые хранятся во флэш-памяти, из-за процессов старения обычно могут обновляться лишь ограниченное число раз; в типичных случаях значение этого показателя составляет несколько сотен тысяч записей, и хотя это число очень большое, оно, однако, не является бесконечным. Несмотря на то что в отношении повышения гибкости флэш-памяти достигнут существенный прогресс, она уступает в этом ОЗУ. В настоящее время флэш-память можно использовать вместо жесткого диска, но не вместо энергозависимого программного ОЗУ.
Следует отметить, что SIM-карты в мобильных телефонах для GSM-связи также имеют флэш-память, предусмотренную для хранения ограниченного объема данных. Это пространство традиционно использовалось для хранения адресной книги мобильного телефона, но в современных телефонах большая часть этих данных хранится в памяти телефона, которая обеспечивает более быстрый и гибкий доступ. SIM-карты по-прежнему оказываются полезными в качестве памяти для хранения такой специфической "секретной" информации, как криптографические сертификаты и ключи, однако, в силу доступности других разновидностей универсальной флэш-памяти, для хранения информации общего назначения они используются все реже и реже.
Флэш-память можно считать аналогичной жесткому диску, в котором отсутствуют подвижные элементы. Ключи памяти USB, которые можете вставлять в ПК, также представляют собой флэш-память. Как и для жестких дисков, для флэш-памяти обычно также предусматривается построенная поверх нее файловая система, что обеспечивает быстрый структурированный доступ к данным.
Другой распространенный способ долговременного хранения информации на устройствах предусматривает использование файловых систем на основе ОЗУ. В отличие от файловых систем, основанных на флэш-памяти, файловые системы ОЗУ используют часть доступной памяти устройства. Хранилища в ОЗУ характеризуются меньшим временем доступа как при чтении, так и при записи данных, но потребляют значительно больше электроэнергии по сравнению с флэш-памятью. Файловые системы, хранимые в ОЗУ, требуют питания даже тогда, когда устройство выключено; если извлечь батарею или она разрядится, то содержимое файловой системы будет утеряно. Это делает файловые системы в ОЗУ более уязвимыми по сравнению с флэш-системами. На многих устройствах, включая системы Windows CE/Pocket PC, файлы, как правило, сохраняются в файловых системах ОЗУ с использованием алгоритмов сжатия. Тем самым эффективно увеличивается емкость файловой системы, но увеличивается время обработки, поскольку чтение и запись потоков данных должны сопровождаться работой алгоритма сжатия. Файловые системы ОЗУ работают быстро — значительно быстрее, чем флэш-память, но все же медленнее, чем осуществляется обработка данных, хранящихся непосредственно в памяти.
Устройства могут поддерживать файловые системы одновременно и во флэш-памяти, и в ОЗУ точно так же, как настольные системы могут поддерживать несколько жестких дисков. Используемые модели долговременного хранения данных могут существенно различаться между собой даже для близких по типу мобильных устройств. Так, на Pocket PC и смартфонах используются разные модели долговременных хранилищ. По умолчанию на Pocket PC используется файловая система на основе ОЗУ; именно по этой причине на устройствах Pocket PC устанавливаются значительно более мощные батареи, чем на смартфонах. На смартфонах главным образом используются файловые системы на основе флэш-памяти. Как Pocket PC, так и смартфоны поддерживают динамическую вставку карт флэш-памяти в процессе работы; благодаря этому устройства имеют возможность доступа к музыкальным файлам, рисункам и любым другим данным, хранящимся на картах
Емкость и эффективность организации хранения файлов на устройствах различных классов является еще одной причиной того, что стратегии, в основе которых лежит принцип "пишется однажды — выполняется везде", в случае мобильных устройств редко когда приводят к удовлетворительным результатам. Насколько эффективно осуществляется обмен данными с памятью, зависит от характеристик используемой на устройстве запоминающей среды и ее емкости. Очень важно знать, какие форматы хранения данных поддерживаются целевым устройством, и тщательно анализировать, каким образом приложение использует эти возможности. Знание этих факторов позволяет оптимизировать доступ к данным, хранящимся на устройстве, и стратегию их хранения исходя из требований производительности и устойчивости работы приложения. Кроме того, ясное понимание механизмов долговременного хранения данных облегчает перенос мобильного приложения с одного устройства на другое.
Для работы с базами данных использование в приложении объекта ADO.NET не является обязательным
Объекты DataSet — замечательная абстракция, но они не всегда являются наилучшим способом организации доступа к данным. Если требуется только считывать данные, то имеет смысл работать непосредственно с данными, предоставляемыми объектом ADO.NET DataReader, сохраняя их в наиболее эффективном для задачи, которую вы пытаетесь решить, формате. Более подробно по этому поводу говорится далее в этой главе.
НА ЗАМЕТКУ.NET Compact Framework не поддерживает компиляцию кода типизированных объектов DataSet, автоматически сгенерированного для настольных компьютеров, Это означает, что наиболее распространенным методом работы с объектами ADO.NET DataSet с использованием .NET Compact Framework является работа непосредственно с нетипизированным классом DataSet и подчиненными ему классами DataTable, DataColumn и DataRow. Кроме некоторого усложнения вашего кода и необходимости внимательно следить за тем, чтобы не допустить опечаток в именах столбцов и полей (распространенная ошибка), использование нетипизированных объектов DataSets не обладает никакими другими недостатками. Наиболее высокая производительность достигается тогда, когда вы работаете с нетипизированными классами непосредственно, а не через какие-либо интерфейсные уровни.
Важно отметить, что строго типизированные объекты DataSet ничуть не эффективнее нетипизированных объектов DataSet. Часто ошибочно полагают иное, поскольку раннее связывание интуитивно представляется более эффективным. Однако раннее связывание типизированных объектов DataSet просто перекладывается на основные нетипизированные объекты DataSet. Типизированные классы DataSet не работают быстрее, их просто легче использовать. Строго типизированные интерфейсные классы позволяют использовать во время проектирования такие возможности, как автоматическое завершение ввода операторов, что облегчает разработку программных кодов на основе объектов DataSet. Они также обеспечивают возможность выявления некоторых видов синтаксических ошибок на стадии проектирования, а не на стадии выполнения. Ничего сверх этого в плане производительности они не дают.
Перенос типизированных объектов ADO.NET DataSet на мобильные устройства
В Visual Studio .NET предусмотрена поддержка преобразования описаний схемы данных в исходный код типизированных объектов DataSet на стадии проектирования. К сожалению, не все из присутствующих в этом исходном коде типов, свойств и методов поддерживаются в .NET Compact Framework.
Если вы возьмете исходный код типизированного объекта DataSet, сгенерированный для настольного компьютера, и перенесете его путем копирования в проект .NET Compact Framework, то при компиляции этого проекта получите несколько сообщений об ошибках. Эти ошибки компиляции можно разбить на три категории:
1. Некоторые ошибки этого типа обусловлены наличием содержащих метаданные атрибутов классов и функций, которые не поддерживаются в .NET Compact Framework; эти метаданные можно эффективно исключить из кода, поставив перед ними символы комментария.
Например, атрибут [System.ComponentModel.ToolboxItem(true)] не поддерживается, и его можно поместить в комментарий.
2. Некоторые ошибки этого типа обусловлены отсутствием типов исключений; вместо таких исключений можно генерировать более общие исключения.
Например, поскольку в .NET Compact Framework не определено исключение new StrongTypingException(), то вместо него можно использовать исключение new Exception().
3. Некоторые ошибки этого типа обусловлены автоматически сгенерированным кодом, в котором используется функциональность, не поддерживаемая в .NET Compact Framework; функции, использующие эту функциональность, можно исключить с помощью символов комментария.
Скомпилировать в .NET Compact Framework код типизированных объектов DataSet, предназначенный для настольных компьютеров, не составляет особого труда; это даст вам великолепную возможность позаимствовать некоторые полезные концепции типизированных объектов DataSet и использовать их в своем мобильном приложении.
Вместо того чтобы отталкиваться от кода для настольного компьютера и отбрасывать ненужные части, гораздо надежнее справиться с задачей поддержки доступа к типизированным объектам DataSet, создавая собственные типизированные классы DataSet, DataTable и DataRow с нуля путем порождения строго типизированных классов из этих основных типов ADO.NET и импортирования лишь отдельных частей кода, автоматически сгенерированного для настольного проекта, в соответствии с необходимостью. Гораздо надежнее самостоятельно создать указанную поддержку с нуля и добавить лишь тот код, в котором есть необходимость, чем исходить из кода для настольных компьютеров и пытаться исключать из него отдельные фрагменты до тех пор, пока он не заработает. Вы получите более понятный, лучше разработанный и более легкий в сопровождении код, если создадите его с самого начала. Код для настольных компьютеров следует рассматривать лишь как полезное учебное пособие и не копировать его фрагменты непосредственно в код мобильного приложения.
Номер теста | (А) Текстовый индекс, с | (Б) Целочисленный индекс, с | (В) Индексирование по объектам DataColumn, с |
---|---|---|---|
1 | 32,538 | 30,09 | 23,554 |
2 | 33,063 | 30,387 | 23,491 |
3 | 32,87 | 30,372 | 23,582 |
Среднее | 32,82 | 30,28 | 23,54 |
Относительная производительность | 100% | 92% | 72% |
Номер теста | (А) Текстовый индекс, с | (Б) Целочисленный индекс, с | (В) Индексирование по объектам DataColumn, с | (Г) Пользовательский формат данных, с |
---|---|---|---|---|
(ADO.NET) | (ADO.NET) | (ADO.NET) | (Пользовательский) | |
1 | 32,538 | 30,09 | 23,554 | 12,268 |
2 | 33,063 | 30,387 | 23,491 | 12,335 |
3 | 32,87 | 30,372 | 23,582 | 12,358 |
Среднее | 32,82 | 30,28 | 23,54 | 12,32 |
Относительная производительность | 100% | 92% | 72% | 38% |
Другие базы данных для мобильных устройств и модели лицензирования баз данных
Следует отметить, что устанавливаемые на устройствах базы данных, которые могут выполняться и на мобильных устройствах, выпускаются и другими поставщиками программного обеспечения. С концептуальной точки зрения они аналогичны SQL СЕ, но у каждой из них есть свои сильные и слабые стороны в отношении возможностей синхронизации данных, разнообразия функциональных средств и модели ценообразования. Важной характеристикой SQL СЕ является то, что ее можно свободно использовать и распространять вместе со своим приложением без необходимости получения на это специальной лицензии или выплат авторских отчислений. Для синхронизации с SQL- серверами требуется наличие специальной лицензии клиента SQL, точно так же, соответствующая клиентская лицензия требуется и для подключения настольного приложения непосредственно к SQL-серверу.
Исторически так сложилось, что компания Microsoft ранее выпустила еще одну базу данных для мобильных устройств, которая называлась CEDB (Windows СЕ Database). Эта база данных имеет ограниченные функциональные возможности, и ее использование в новых приложениях не рекомендуется; на будущих устройствах база данных CEDB может отсутствовать. Поскольку эта технология почти полностью устарела, никакого непосредственного механизма для доступа к этой базе данных в .NET Compact Framework не предусмотрено. Если вашему приложению требуется доступ к CEDB, вы должны вызывать встроенный код или использовать интерфейсные классы .NET, созданные сторонними производителями. Имеются две неплохие альтернативы использованию CEDB: для сравнительно небольших объемов данных можно использовать XML-файлы, тогда как для крупных объемов данных наилучшим выбором будет SQL СЕ.
Visual Studio .NET 2005 и SQL СЕ
В следующей версии SQL СЕ и .NET Compact Framework будет предложено два существенных усовершенствования, касающихся доступа к данным при работе с SQL СЕ.
1. Класс SqlCeResultSet даст разработчикам возможность перемещаться по данным и обновлять их непосредственно в базе данных SQL СЕ. Это упростит создание приложений, которые работают с базами данных вплотную, а не используют высокоуровневые абстракции наподобие объектов ADO.NET DataSet.
2. SQL СЕ будет поддерживать многопользовательский доступ. Это означает, что несколько приложений на одном устройстве смогут одновременно открывать одни и те же базы данных и работать с ними. Благодаря этому устранятся некоторые из описанных выше проблем, связанных с параллельным доступом к базам данных на устройстве.
Даст что-либо введение этих новых функциональных возможностей вам и вашему приложению? Ответ звучит так: "Возможно". Многие разработчики мобильных приложений выбирают в качестве целевых такие устройства, в ПЗУ которых уже содержатся необходимые среды выполнения, поскольку это упрощает развертывание приложения. (Для некоторых устройств такая возможность является единственной, но это уже тема следующей главы.) Если речь идет о таких приложениях, то должно пройти некоторое время, пока не наберется некоторое критическое количество устройств, ПЗУ которых содержат обновленные компоненты. Однако если у вас есть возможность установить обновленную среду выполнения и процессор базы данных, то это стоит сделать хотя бы ради того, чтобы иметь эти средства.
"Информация решает все…"Маршалл Мак-Луган (Marshall McLuhan) (1911–1980), теоретик в области связи(Encarta 2004, Quotations)
"И-Ти звонить семья…"Пришелец, который просто хотел поговорить с родными (кинофильм "Пришелец" ("The Extra-Terrestrial"), 1982)
"Если что-то может пойти не так, то это обязательно произойдет, причем именно тогда, когда вы меньше всего этого ожидаете."Закон Мэрфи
Два примера коммуникационных стратегий
Синхронизация данных расписания встреч, списка контактов и электронной почты, хранящихся на мобильном устройстве
Хорошим примером применения двух описанных выше принципов является модель синхронизации, используемая Microsoft на устройствах Smartphone и Pocket PC Phone. На устройствах обоих типов имеется приложение электронной почты, допускающее периодическую синхронизацию электронной почты, данных расписания встреч (календаря) и списка контактов с сервером обмена сообщениями Exchange Server.
Запросы и предпочтения различных пользователей в отношении синхронизации этих данных различны. С целью минимизации потока данных мобильные приложения предоставляют пользователям возможность задавать, какие виды данных подлежат локальной синхронизации на устройстве. Например, я могу решить, что мне необходима синхронизация только расписания встреч и списка контактов, оставляя задачу синхронизации электронной почты для своего лэптопа. Можно также ограничивать объем синхронизируемой информации, указав, например, что данные обо всех предстоящих встречах должны синхронизироваться полностью, тогда как синхронизация данных о прошлых встречах должна охватывать информацию не более чем 2-недельной давности, а при загрузке электронных сообщений должны загружаться только первые 3 Кбайт данных.
Развернутое на устройстве приложение для работы с электронной почтой, информацией о контактах и расписанием встреч позволяет также указывать, с какой периодичностью и в каком режиме должна осуществляться синхронизация — автоматически или вручную. Наиболее подходящие для каждого пользователя установки определяются видом синхронизируемых данных и потребностями в их обновлении. У большинства пользователей расписание встреч изменяется реже, чем появляются новые входящие электронные сообщения, а список контактов изменяется еще реже. Лично я предпочитаю синхронизировать данные во время поездок на работу и с работы и, если это необходимо, на протяжении рабочего дня; другие люди, насколько мне известно, предпочитают синхронизировать свои данные чаще, используя автоматическое обновление. Модель синхронизации в значительной степени определяется тем, какой режим использования приложения является для пользователя привычным.
Для синхронизации этой информации устройства используют специальную службу, которая называется ActiveSync. Механизм ActiveSync периодически устанавливает через мобильную сеть соединение с Internet для подключения пользователя к серверу Exchange Server и последующей синхронизации данных. Процесс синхронизации состоит из двух операций:
1. Загрузка всех пакетных обновлений. Синхронизируются все локальные изменения, связанные с расписанием встреч, электронной почтой и списком контактов.
2. Загрузка данных, удовлетворяющих условиям локального фильтра. Соответствующим образом загружается информация о новых встречах и контактных лицах, а также заголовки электронной почты.
Эта модель позволяет сохранять разумный баланс между объемом обновляемых данных и пропускной способностью сети. Если бы информация о назначенных встречах загружалась по запросу индивидуально для каждой даты при ее выборе пользователем в календаре своего мобильного устройства, то во многих случаях сделать это было бы невозможно из-за отсутствия соединения с мобильной сетью или выключения сервера электронной почты. Но даже и при наличии соединения пользователь испытывал бы значительные неудобства от задержек при доступе к данным или их выгрузке. С другой стороны, если бы во время синхронизации с сервера загружалась вся возможная информация, то это происходило бы слишком медленно и неэффективно с точки зрения использования полосы пропускания. Совершенно очевидно, что достижение необходимого баланса указанных факторов требует вмешательства пользователя
Хорошо продуманное кэширование данных на устройстве, разумное их обновление в соответствии с потребностями пользователя и предоставление пользователю возможности самостоятельно определять, когда и какие именно данные должны синхронизироваться, создает все предпосылки для нормальной работы, не сопровождающейся неожиданными сбоями.
Отправка и получение SMS-сообщений с помощью мобильного телефона
SMS-сообщения — это короткие текстовые сообщения, пересылаемые между мобильными телефонами. SMS — многообещающая технология, используя которую пользователи мобильных телефонов могут легко обмениваться между собой несколькими строками текста. Устанавливая фиксированную плату за пересылку одного сообщения, операторы сетей мобильной связи получают огромные прибыли за счет предоставления лишь узкой полосы пропускания; SMS-сообщения с побитовой оплатой гораздо прибыльнее речевой связи! Таким образом, приложения для обработки SMS — это приложения-приманки, и вряд ли можно сомневаться в том, что изготовители мобильных телефонов и операторы сетей мобильной связи постарались отладить эту технологию идеальным образом.
Обмен SMS-сообщениями обладает одним большим достоинством и одним большим недостатком:
1. Преимущества SMS: разделение передачи и приема сообщений. Если SMS-сообщение пересылается с одного мобильного телефона на другой, то телефон, принимающий сообщение, во время его передачи не обязан быть подключенным к сети. Если вы совершаете перелет через Атлантику, и в этот момент кто-то отправляет вам SMS-сообщение, инфраструктура сети мобильной связи поместит сообщение в очередь на своих серверах и доставит его вам, когда вы приземлитесь и включите свои мобильный телефон. Точно так же будут развиваться события и в том случае, если принимающий телефон находится вне зоны досягаемости поскольку его владелец в данный момент находится в метро, лифте или катается на лыжах на той части склона, которая скрыта от сотового передатчика. По указанным причинам данный механизм прекрасно подходит для отправки кратких текстовых сообщений наподобие: "Встретимся в Лонгхорн Грилл в 17:00. Иво". Отправитель и получатель могут общаться между собой краткими предложениями, не соединяясь друг с другом.
2. Недостаток SMS: немые клиентские приложения, не имеющие возможности кэшировать сообщения в автономном режиме. В настоящее время большинство мобильных приложений не имеют автоматизированного механизма очередизации исходящих SMS-сообщений. Когда пользователь набирает сообщение и пытается его отправить, делая это обычно несколько раз, то при отсутствии доступа к сети сообщение не может быть отправлено. Эта ситуация служит примером модели синхронного приложения, в котором попытка соединения осуществляется немедленно и завершается либо удачно, либо неудачно, прежде чем управление возвращается пользователю. Гораздо более эффективной является модель клиентского приложения в соответствии с которой предпринимается попытка синхронной отправки сообщения, и если сделать это немедленно не удается, то сообщение помещается в очередь исходящих сообщений, отсылка которых будет произведена тогда, когда доступ к сети будет восстановлен. Когда SMS-сообщение, в конце концов, поступит на сервер, пользователь, отправивший сообщение, может быть извещен об этом по телефону.
Как и в предыдущем примере, отсюда можно извлечь важные уроки. Вы не задумывались над тем, почему в современных мобильных телефонах на клиентской стороне SMS-технологии действует подобное ограничение? Объясняется это тем, что создать асинхронную коммуникационную модель значительно сложнее; это требует написания для клиентской стороны логики, которая будет осуществлять фоновую отправку SMS- сообщений, обрабатывать повторные попытки отправки сообщений и формировать очередь исходящих сообщений, а в довершение всего неплохо было бы также предоставить пользовательский интерфейс, который после окончательной отправки SMS- сообщений, помещенных в очередь, известит об этом пользователя. Модели приложений, используемые предыдущими поколениями мобильных телефонов, отличались сравнительной простотой, и создание подобного рода систем считалось неоправданным, ибо вносило дополнительные сложности. Однако современные мобильные телефоны располагают как более мощными пользовательскими интерфейсами, так и моделями приложений, облегчающими выполнение фоновой обработки. Поэтому разумно предположить, что операционные системы и приложения будущих поколений мобильных телефонов будут поддерживать кэширование исходящих SMS-сообщений точно так же, как многие нынешние телефоны поддерживают синхронизацию с сервером кэшируемых исходящих сообщений электронной почты, контактной информации и расписания встреч.
НА ЗАМЕТКУ
Выполнение кода в фоновом потоке обсуждается в главе 9.
В листинге 15.1 представлен простой пример файлового ввода-вывода, иллюстрирующий некоторые различия между сбойными ситуациями, возникающими при обращении к локальным и удаленным файлам. Хотя вы и можете поместить этот код в форму мобильного приложения и запустить его на выполнение, вряд ли стоит это делать; этот листинг приведен в основном лишь для того, чтобы вы его изучили. Как видно из приведенных в коде комментариев, в случае доступа к серверу вероятность сбоя повышается не только для операции открытия файла, но и для файловых операций чтения/записи, что связано с возможностью потери доступа к сети. Вероятность сбоя повышается с увеличением количества коммуникационных уровней, отделяющих ваше устройство от данных, к которым оно пытается обратиться. Если используется беспроводная сеть, то сигнал может быть утерян вследствие перемещения устройства. Если доступ к данным осуществляется посредством виртуальной частной сети через брандмауэр, то сбой на данном сервере может наступить в любой момент. Если соединение проходит через сеть мобильной связи, то сбой может наступить по вине мобильной сети. Несмотря на то что каждый из этих уровней сам по себе может быть надежным, их объединение повышает вероятность сбоя. Поэтому при попытках переноса кода из систем с локальным доступом к файлам в системы, использующие доступ к удаленным серверам, следует быть очень внимательным. В коде, ориентированном на локальный доступ к файлам, могут быть заложены предположения, которые при доступе к удаленным источникам станут причиной сбоев. Чтобы этого не произошло, рекомендуется применять следующие меры предосторожности:Возбуждение и перехват исключений, которые могут приводить к образованию висячих соединений, и проблемы производительности
Под "исключениями" понимается следующее: это исключительные обстоятельства, которые должны обрабатываться средой выполнения и кодом приложения. Возбуждение (или, другими словами, генерация) исключения запускает в среде выполнения сложный процесс, сопровождающийся развертыванием стека для поиска обработчиков исключений, уничтожением локальных переменных и другими операциями, связанными с большими накладными расходами. С точки зрения производительности этот процесс, как правило, требует больших вычислительных ресурсов по сравнению подходом, в котором отказываются от возбуждения исключений и вместо этого заблаговременно выявляют условия, которые могут приводить к возникновению ошибок. Как и в случае других аспектов производительности, окончательным критерием всегда должны служить результаты количественных экспериментов. Кроме того, поскольку возбуждение исключений нарушает обычный порядок выполнения операций в вашем приложении, может оказаться так, что важные операции, связанные с освобождением коммуникационных ресурсов, не будут выполнены. В результате этого часть коммуникационных ресурсов может остаться в "зависшем" состоянии, что может стать причиной дополнительных проблем в процессе дальнейшего выполнения приложения.
В самой идее использования обработки исключений в приложении нет ничего плохого, однако важно понимать, при каких обстоятельствах этого делать не следует. Никакие исключения не должны возбуждаться и обрабатываться в процессе нормального выполнения приложения. Нецелесообразно использовать в приложении код, генерирующий и обрабатывающий исключения, лишь для того, чтобы контролировать возникновение самых обычных ситуаций в ходе выполнения приложения, поскольку это приведет к неэффективным тратам вычислительных ресурсов и усложнению программы. При малейшей возможности старайтесь контролировать состояние информационного обмена с помощью обычного кода, а не посредством механизма возбуждения и обработки исключений. Если обработчики исключений запускаются при нормальном выполнении приложения, то первое, что вы должны сделать — это проанализировать код и посмотреть, нельзя ли организовать дополнительные логические проверки, при помощи которых можно было бы предотвратить возбуждение этих исключений.
Пример сравнения возможностей механизма исключений и обычного алгоритмического кода можно найти в главе 7
НА ЗАМЕТКУ
Поскольку стандарт Bluetooth специально разрабатывался для мобильных устройств, он, как правило, обеспечивает неплохие характеристики энергосбережения, но при необходимости вы сможете найти и другие, более специализированные коммуникационные механизмы. В дополнение к таким технологиям персональных сетей, как Bluetooth, существуют также такие технологии нательных сетей, характеризуемые низким энергопотреблением, как Zig-Bee (IEEE 802.15). Сетевые протоколы нательных сетей пригодны для работы с встроенными датчиками и другими видами устройств, для которых необходим низкий уровень энергопотребления.
В приведенном в листингах 15.3, 15.4 и 15.6 коде показано, как организовать передачу содержимого файла с одного устройства на другое, используя IrDA. Для создания и запуска приложения необходимо выполнить следующие действия:В настоящее время поддержка сокетов .NET для IrDA доступна лишь в .NET Compact Framework, тогда как в .NET Framework для настольных компьютеров она отсутствует
В версии 1.1 NET Compact Framework обеспечивается встроенная поддержка IrDA, но в версии 1.1 .NET Framework для настольных компьютеров она отсутствует. Это именно тот случай, когда путь к введению технологии, представляющей интерес для мобильных устройств, был проложен .NET Compact Framework. Возможно, будущие версии .NET Framework для настольных компьютеров обеспечат поддержку программирования сокетов IrDA, но до тех пор, пока это не произойдет, если вам понадобится связать между собой настольные компьютеры и .NET Compact Framework, то для доступа к функциональным возможностям IrDA на настольных компьютерах вам придется использовать вызовы функций в собственных кодах. В качестве положительного фактора можно отметить то обстоятельство, что такой собственный код для настольных компьютеров не будет слишком сложным, поскольку имеющиеся в Windows API-интерфейсы для работы с сокетами в собственных кодах поддерживают использование IrDA, причем код на С/С++ будет выглядеть примерно так же, как и коды на C# или VB.NET, которые вы использовали бы для устройства. Для более подробного изучения этого вопроса вам следует обратиться к разделам "IrDA Programming with Windows sockets" и "IrDA and Windows sockets reference" справочной документации Windows Platform SDK.
В некоторых случаях полезно иметь возможность принудительной перекачки информации на мобильное устройство. Как ранее уже отмечалось, в случае стационарных пользовательских сетевых топологий это не составляет особого труда; мобильное устройство может иметь фиксированный или специальным образом зарегистрированный IP-адрес, так что ему остается только открыть сокет и дожидаться поступления запросов. Для универсальных мобильных устройств, мигрирующих между различными сетями, это представляет определенные трудности. Имеется несколько путей преодоления этих проблем:Не решаются ли все эти проблемы набором протоколов IPv6?
Ответ таков: "В перспективе — возможно", однако, как сказал известный экономист Мейнард Кинис (Maynard Keyneys): "В делах повседневных перспектива — плохой советчик. В перспективе нас всех ожидает смерть". Пройдет немало лет, пока IPv6 прочно утвердится в мире, но в любом случае такие компоненты сетевой безопасности, как брандмауэры, просуществуют еще очень долго. Как следствие, адресовать серверы по- прежнему будет проще, чем мобильные устройства. Для адресации мобильных устройств, непрерывно мигрирующих между различными сетевыми топологиями, будут требоваться специальные механизмы.
Организация доступа к поступающим SMS-сообщениям на устройствах Microsoft Smartphone
Для работы с SMS-сообщениями в операционной системе Microsoft Smartphone существует два способа: 1) работа на низком уровне путем создания собственного фильтра для проверки поступающих сообщений, или 2) работа на высоком уровне с использованием интерфейса прикладного программирования CEMAPI (СЕ Messaging API) для просмотра сообщений после того, как они поступили. В настоящее время оба эти способа требуют использования собственных кодов С/С++ для доступа к необходимым функциональным средствам операционной системы.
1. Создание собственного низкоуровневого фильтра для поступающих SMS-сообщений
Операционная система Smartphone предлагает опытным разработчикам два способа регистрации собственных фильтров, предназначенных для обработки SMS- сообщений. Это можно сделать путем создания и регистрации SMS-поставщика на устройстве или путем создания и регистрации компонента, реализующего интерфейс IMailRuleClient.
В принципе, оба эти подхода аналогичны разработке ISAPI-фильтра для сервера Internet Information Server; могут выполняться одновременно несколько фильтров, и запрос дескриптора передается первому из фильтров, критерии которого согласуются с поступающими запросами. (Например, в случае ISAPI-фильтров запросы Web-страницы *.ASP маршрутизируются на один дескриптор, а запросы Web-страницы *.ASPX — на другой, исходя из расширения файла.) Создание ISAPI-фильтра для Internet Information Server — задача нелегкая, требующая тщательного проектирования и тестирования. Точно так же как почти никому из Web-разработчиков не требуется использование собственных ISAPI-фильтров, создание собственных SMS-поставщиков или компонентов IMailRuleClient может понадобиться разработчикам мобильных приложений лишь в редких случаях. Тем не менее, если на первый план выходит гибкость, ее необходимо обеспечивать именно таким способом.
• SMS-поставщики
SMS-поставщики должны проверять заголовки поступающих SMS-сообщений и принимать решения относительно того, какому приложению следует доставить то или иное сообщение. Это относится как к двоичным, так и к текстовым SMS-сообщениям. Однако на практике многие "заблокированные" смартфоны не позволят вам реализацию собственного SMS-поставщика, поскольку это может нарушить политику безопасности, принятую изготовителем телефона.
Более подробную информацию относительно создания SMS-поставщиков вы сможете найти в справочной документации по Smartphone SDK, проведя поиск по термину "SMS Provider" или просмотрев раздел "Short Message Service" комплекта справочной документации "Smartphone Adaptation Kit for Mobile Operators".
• IMailRuleClient
Для устройств Smartphone 2003 и более поздних моделей можно реализовать и зарегистрировать компонент, реализующий интерфейс IMailRuleClient. Этому высокоуровневому, по сравнению с созданием SMS-поставщика, подходу следует отдавать предпочтение, поскольку он ориентирован на разработчиков приложений, а не на операторов сетей мобильной связи, выпускающих телефоны.
Интерфейс IMailRuleClient позволяет компоненту проверять входящие SMS-сообщения и отвечать на них. Такой подход может оказаться более легким в реализации по сравнению с написанием кода собственного SMS-поставщика, но для этого необходимо еще, чтобы компонент был подписан разрешенным криптографическим ключом, если этого требует изготовитель телефона. Более подробную информацию относительно интерфейса IMailRuleClient вы сможете найти, проведя в оперативной справочной документации MSDN поиск по ключевым словам "IMailRuleClient" или "CEMAPI".
2. Использование CEMAPI для высокоуровневого доступа к SMS-сообщениям
Интерфейс CEMAPI предлагает высокоуровневый механизм доступа к текстовым SMS- сообщениям, которые были маршрутизированы на почтовый ящик смартфона. CEMAPI предлагает набор интерфейсов для навигации по хранилищу сообщений устройства, а также создания и просмотра сообщений. Ваше мобильное приложение может периодически опрашивать папку входящих сообщений устройства с целью проверки того, не поступили ли новые сообщения, предназначенные для этого приложения. Для получения более подробной информации относительно порядка работы с папкой входящих сообщений Pocket PC или смартфона выполните в комплекте справочной документации Smartphone SDK поиск по ключевому слову "CEMAPI".
НА ЗАМЕТКУВызов Web-службы с устройства работает почти точно так же, как и вызов, выполняемый с настольного компьютера или сервера. Чтобы вызвать Web-службу с мобильного устройства, потребуется выполнить следующие действия:
Для выполнения кода на физическом или эмулированном устройстве используется логическая машина отличная от машины разработки, даже если эмулятор и выполняется на той же физической машине, что и ваш Web-сервер, имена соответствующих машин будут разными. Вследствие этого вы не можете использовать URL //localhost/WebService1, чтобы задать с устройства местоположение Web-службы; вы должны использовать фактическое имя хост-машины (например, //myDevMachine1/WebService) так, как вызывали бы Web-службу с другого ПК.
НА ЗАМЕТКУВ листинге 15.9 приведен пример неэффективной организации работы с Web-службой с использованием многократных запросов и ответов. В листинге 15.10 представлен пример пакетной организации того же диалога, когда вся необходимая обработка осуществляется при помощи одного цикла "запрос/ответ". При любом удобном случае старайтесь уменьшать количество запросов, объединяя несколько мелких запросов в один более емкий.
При использовании Web-служб справедлив тезис, в соответствии с которым лучше передавать двоичные данные в результате выполнения второго запроса, чем пытаться сразу же передавать большой поток XML-данных. Поскольку объем двоичных данных при преобразовании их к формату XML значительно возрастает, это приводит к увеличению длительности их передачи. При длительных временах передачи возрастает вероятность сбоев. Улучшенная модель предполагает выполнение одного вызова Web-службы для передачи всех данных, которые могут быть эффективно переданы в виде XML, и ряда последующих вызовов для передачи таких двоичных файлов, как файлы изображений. В листинге 15.11 представлен код, позволяющий загрузить файл с Web-сервера и сохранить его на устройстве. Если необходимо передать содержимое нескольких двоичных файлов, имеет смысл поэкспериментировать с объединением всех двоичных данных в один сжатый файл; такой объединенный файл может быть передан в виде двоичных данных и распакован на другом конце канала связи.
Ничто не кончено, пока не закончено.Йоги Берра (Yogi Berra), 1925(Encarta 2004, Quotations)
НА ЗАМЕТКУЕсли ваше мобильное приложение предназначено для выполнения на устройствах, ограничивающих круг приложений, которые могут использоваться на данном устройстве, то приложение необходимо снабдить подписью. Обычно эта процедура предполагает отправку приложения третьей стороне, являющейся владельцем ключей подписей, наличие которых проверяется устройством. Важно понимать, что модель, в которой применяются подписи, не зависит от того, каким именно способом приложение попало на устройство. Приложение может быть загружено из Web, установлено с использованием карты флэш-памяти или загружено с ПК; обычно для модуля устройства, проверяющего подписи, это не имеет никакого значения. Чтобы приложения могли выполняться, им приходится проходить одну и ту же процедуру проверки подписи.
Изготовитель может поставлять несколько версий устройства, одни из которых являются "открытыми", а другие относятся к устройствам с "ограниченным доступом". В качестве примера устройств такого типа можно привести устройства Microsoft Smartphone.
Некоторые изготовители и их партнеры, являющиеся операторами сетей мобильной связи, поставляют смартфоны как "открытые" устройства, на которых разрешается устанавливать любые приложения. Другие же поставщики поставляют их как устройства с "ограниченными возможностями расширения", позволяя устанавливать лишь разрешенные для этого приложения. Как правило, устройства, приобретаемые непосредственно у изготовителя, являются "открытыми". Обычно, если вы занимаетесь разработкой и тестированием приложений, то вам нужны открытые устройства, на которых ваше приложение можно беспрепятственно развернуть из инструмента разработки без какой-либо подписи. Приобретая устройство для целей разработки приложений, убедитесь в наличии такой возможности.
Почему поставщики некоторых устройств требуют, чтобы приложения были подписаны?
Операторы сетей мобильной связи являются основными дистрибьюторами мобильных устройств, требующими наличия цифровых подписей у приложений при установке и выполнении нового программного обеспечения. В основном это делается по следующим трем причинам:
1. Чтобы управлять коммерческой моделью использования приложений, выполняющихся на выданных ими устройствах. Операторы сетей мобильной связи нередко субсидируют часть стоимости телефонов, которые они выдают пользователям. Поэтому они нуждаются в механизме возврата средств, вложенных в телефонные трубки. Одни операторы предпочитают получать эту компенсацию в виде части дохода от выполнения приложений на их устройствах. Другие хотят, чтобы на устройствах развертывались лишь те приложения, которые они считают полезными для своего бизнеса. Третьи могут быть больше всего заинтересованы в том, чтобы на их устройствах развертывались лишь приложения, соответствующие определенным требованиям в отношении качества и содержимого.
2. Чтобы контролировать затраты на поддержку выдаваемых ими устройств. Операторов мобильных сетей, выдающих своим пользователям телефоны в больших количествах, волнует вопрос о стоимости их последующей поддержки. Каждый раз, когда у пользователя возникают проблемы с трубкой, и он обращается к своему сетевому оператору, все расходы, связанные с оказанием пользователю необходимой технической помощи, ложатся на поставщика. Целесообразность такой поддержки становится проблематичной, если выполнение развернутого на устройстве приложения случайно или преднамеренно приводит к несанкционированному использованию сети или препятствует использованию телефона для обычных операций. Оператор мобильной сети может захотеть быть полностью уверенным в том, что на выдаваемых им в больших количествах телефонах выполняются только одобренные высококачественные приложения, на которые распространяются условия поддержки.
3. Чтобы защитить свои сети. Операторы сетей мобильной связи заботятся о том, чтобы выполняющиеся на их устройствах приложения не могли, случайно или преднамеренно, нанести вред их дорогостоящим сетям связи. Для сетевых операторов нет ничего страшнее вирусов, распространяющихся среди множества телефонов и инициирующих атаку типа DoS (denial of service — отказ в обслуживании), которая приводит к невозможности коммерческого обслуживания сети.
Желание операторов сетей мобильной связи контролировать использование предоставляемых ими телефонов вступает в определенное противоречие с перспективами более быстрого внедрения инноваций, которые обеспечиваются использованием открытых платформ. Модель централизованного управления может привлекать своей стабильностью, однако открытые платформы предлагают возможность динамичного внедрения незапланированных новшеств. Эта ситуация аналогична противостоянию, которое существует между предсказуемой стабильностью плановой экономики и творческим хаосом капиталистической системы. Различные операторы мобильных сетей экспериментируют с различными моделями, и каждый из них пытается найти наиболее оптимальное соотношение между факторами контроля и свободы. Добавьте к этому еще и желание различных сторон предусмотреть настраиваемые для каждого отдельного приложения параметры безопасности (управляющие, например, возможностями доступа в сеть, отображения пользовательского интерфейса, доступа к файловой системе устройства и тому подобного), и вам станет понятно, что споры вокруг этого будут длиться еще не один год. В конечном счете, вероятно, предпочтение будет отдано чему-то более близкому к открытой модели, но с предусмотренными мерами безопасности, которые смогут гарантировать, что доступ к наиболее ценной функциональности мобильных устройств будет возможен лишь с согласия распространяющих эти устройства сетевых операторов. Вполне разумно предположить, что в эту схему будут вовлечены и другие категории поставщиков мобильных устройств. Организация, выдающая в пользование своим сотрудникам многофункциональные смартфоны, может разрешить использование на них лишь тех приложений, которые она считает заслуживающими доверия. В конце концов, последнее слово будет всегда оставаться за той стороной, от которой пользователь получает мобильное устройство. Те, кто покупает телефоны непосредственно у поставщиков, вероятнее всего, будут приобретать открытые устройства, тогда как тем, кто получает их от третьей стороны, будут предоставляться определенные возможности расширения функциональности устройств с некоторым уклоном, учитывающим интересы данной стороны.
НА ЗАМЕТКУНе менее важным аспектом является правильное использование версий среды выполнения. Независимо от технологии используемых сред выполнения (например, .NET Compact Framework, J2ME, J2SE, собственные коды), время от времени появляются их обновленные версии, поэтому необходимо внимательно следить за тем, с какой именно версией вы работаете.
Лишь некоторые классы устройств поддерживают динамическую установку сред времени выполнения и компонентов.
Как уже отмечалось ранее, одни устройства являются открытыми и допускают установку программного обеспечения, тогда как другие допускают установку лишь определенного программного обеспечения и в силу этого могут не предусматривать динамическую установку сред времени выполнения. Кроме того, круг устройств, допускающих динамическую установку сред времени выполнения, ограничивается также техническими причинами. Например, на устройствах Microsoft Smartphone и Pocket PC работа с памятью, отводимой под файловые системы, осуществляется по-разному, вследствие чего поддержка установки .NET Compact Framework в файловой системе ОЗУ Pocket PC, если это необходимо, оказывается возможной, но при этом неосуществимой для устройств Microsoft Smartphone, которые требуют установки среды выполнения в ПЗУ (хотя приложения и могут храниться в файловой системе смартфона). Поэтому знание спецификаций и возможностей расширения функциональности целевых устройств имеет очень большое значение.
Любую достаточно развитую технологию трудно
отличить от магии.Артур Кларк (Arthur С. Clark), автор научно-фантастической повести "Космическая одиссея 2001 года" и один из праотцов спутниковой связи(Encarta 2004, Quotations)
Спасибо, что скачали книгу в бесплатной электронной библиотеке BooksCafe.Net
Оставить отзыв о книге
Все книги автора