Приступая к проектированию .NET Compact Framework, мы знали, что в конечном счете должны получить некое совместимое подмножество среды .NET Framework, предназначенной для настольных компьютеров, которое удовлетворяло бы требованиям разработчиков. Вопрос о том, каким именно образом следовало определить это подмножество, стал предметом серьезного обсуждения. Следует ли отталкиваться от платформы .NET Framework, постепенно исключая из нее все то, что не нужно, или же лучше начать проектирование новой платформы с нуля, включая в нее только те средства, которые являются действительно необходимыми? Будучи не в состоянии решить эту философскую дилемму, мы остановились на том, чтобы использовать оба подхода и посмотреть, какой из них окажется более приемлемым. Такой способ действий требовал большего времени и ресурсов, однако, по моему мнению, только с его помощью и можно было окончательно разрешить указанные разногласия. Действуя в направлении сверху вниз, мы могли определить максимальный состав тех ключевых возможностей, поддержку которых мы хотели бы обеспечить, тогда как подход, соответствующий продвижению снизу вверх, позволял нам составить хорошее представление о том, какой может быть минимальная реализация и как влияет на размерные показатели и производительность добавление тех или иных возможностей. (Ради справедливости замечу, что лично я принадлежал к числу тех проигравших участников дебатов, которые рекомендовали использовать для создания библиотек программ разработку в направлении сверху вниз. Эта модель оказалась полезной в отношении понимания того, что же именно мы хотим создать, но не могла обеспечить необходимую производительность. Единственным путь, гарантирующий достижение этой цели, был связан с осуществлением разработки по принципу "снизу вверх".)
В конце концов, ситуация с определением наиболее оптимального варианта решения значительно прояснилась. Единственным способом достижения максимальной производительности при сохранении приемлемого размера платформы была ее разработка с нуля и постепенная достройка в направлении снизу вверх путем постепенного добавления только тех типов, классов, методов и свойств, введение которых было необходимым или оправданным. Но даже при таком подходе объем платформы намного превышал тот, который первоначально предсказывался большинством участников группы, хотя полученное решение и отличалось ясностью и оптимальностью. Мне кажется, что отсюда можно сделать один общий вывод: при проектировании подмножеств каркасов, компонентов или приложений для мобильных устройств на основе версий, предназначенных для настольных компьютеров или серверов, для получения прототипов на ранних стадиях разработки целесообразно отталкиваться от имеющихся версий, постепенно исключая из них те или иные элементы для получения лучшего представления о том, какой именно результат вы хотите получить; однако если речь идет о фактической реализации, то наиболее ясное и хорошо проработанное решение обеспечивается разработкой в направлении снизу вверх. В процессе анализа мыслите, переходя от более общих категорий к менее общим, тогда как в процессе реализации начинайте с разработки мелких деталей, постоянно оценивая эффективность каждого своего шага.
Управляемый код и собственный код
Размер кода большинства приложений значительно меньше размера выполняющегося под ним кода среды времени выполнения и операционной системы. Особенно это касается приложений с графическим пользовательским интерфейсом, при создании которых разработчик имеет дело с высокоуровневыми абстракциями, в то время как значительную часть остального выполняющегося кода составляет низкоуровневый библиотечный код, обеспечивающий функционирование пользовательского интерфейса. Отсюда становится очевидным, насколько важную роль играет хорошо спроектированная и высокопроизводительная среда времени выполнения.
При проектировании сред выполнения управляемого кода возможны два подхода:
1. Реализация как можно большей части среды времени выполнения и библиотек программ с использованием собственных кодов и последующее создание тонкого интерфейсного слоя управляемого кода, обеспечивающего доступ разработчиков приложений и компонентов к этой части. Привлекательной стороной такого подхода является то, что он позволяет добиться максимально высокой производительности, а отрицательной стороной — сложность и потенциально более низкая надежность среды выполнения, которая в этом случае не использует всех преимуществ, предоставляемых выполнением полностью управляемого кода.
2. Реализация с использованием собственных кодов лишь в самых необходимых случаях, тогда как вся остальная функциональность обеспечивается применением управляемого кода. Такой подход может улучшить характеристики переносимости и надежности и позволяет выжать из исполнительного механизма управляемого кода максимально возможную производительность, поскольку этот механизм будет использоваться подавляющей частью кода.