Существуют и такие ситуации, в которых действительно имеет смысл затратить усилия на оптимизацию отдельных алгоритмов и вынести код за пределы функций, сделав его встроенным. Это, например, может оказаться целесообразным в случае кода, выполняющего интенсивную многократную обработку крупных наборов данных в циклах. При необходимости можно систематически выявлять такие ситуации и принимать соответствующие меры. Однако для конечных автоматов, работающих на уровне приложения, которые вызываются при переходе приложения из одного режима выполнения операций или отображения пользовательского интерфейса в другой, такие ситуации не характерны; указанные изменения обычно осуществляются с низкой частотой и не встречаются внутри плотных циклов.
Наконец, гораздо проще взять инкапсулированный код и вставить его в вызывающую функцию, чем пытаться преобразовать произвольный фрагмент кода к инкапсулированному виду, чтобы повысить эффективность работы с ним. Это вам подтвердит каждый, кому хотя бы раз приходилось заниматься упорядочением кода типа "спагетти", написанного другими разработчиками, приводя его к более удобной в работе инкапсулированной форме!
В силу описанных причин при разработке программного обеспечения для мобильных устройств удачная структура кода играет, по крайней мере, не меньшую роль, чем в случае настольных компьютеров. Использование конечных автоматов облегчает эффективную организацию кода, что в свою очередь способствует созданию замечательных приложений.
Отдаете ли вы себе в этом отчет или нет, но значительная доля кода вашего приложения всегда будет связана с управлением его состояниями. Как бы то ни было, вам придется иметь дело с задачами подобного рода, и только вам решать, выбрать ли явный подход к управлению состояниями приложения или же остановиться на модели неявного управления. Явное управление состояниями имеет ряд существенных преимуществ, не самым последним из которых является то, что такой подход заставляет вас более тщательно продумывать схемы функционирования вашего приложения.
На самых ранних стадиях разработки приложений и построения их прототипов формализация этих процессов, как правило, затруднена. Это ни в коем случае не должно отбивать у вас охоту к использованию конечных автоматов. Наоборот, конечные автоматы пригодятся вам на этих стадиях не меньше, чем на более поздних. Из предыдущего рассмотрения вы уже должны были понять, что для реализации конечного автомата требуется совсем небольшой объем дополнительного кода. При этом добавление новых состояний, а также удаление и переименование существующих состояний в соответствии с изменением определений по мере разработки ваших идей не составляет никакого труда. По моему мнению, при проектировании пользовательских интерфейсов мобильных приложений конечных автоматов, позволяющие централизованным образом экспериментировать с логикой размещения и масштабирования элементов управления, оказываются особенно полезными. Даже если разработка ведется в специализированном стиле, подход, основанный на использовании конечных автоматов, поможет вам сэкономить время и обеспечит необходимую гибкость в процессе уточнения ваших идей.
Сколько конечных автоматов должно быть в приложении?
Надеюсь, к этому моменту вы уже успели убедиться в целесообразности использования конечных автоматов в качестве центральной составляющей проекта мобильного приложения. Как и в случае любого другого аспекта проектирования, существуют некоторые общие принципы создания конечных автоматов, а также важные детали реализации. Конструирование подходящих разновидностей конечных автоматов является своего рода искусством, овладение которым приходит с приобретением опыта. Конечный автомат должен служить "абстрактным представлением одной или нескольких переменных, принимающих набор конечных значений, каждое из которых отображается в полезное дискретное состояние". Эти переменные должны некоторым образом коррелировать с различными состояниями, в которых может пребывать приложение или класс. Как и в случае приведенного выше примера кода, полезно явно определить переменную типа перечисления, значения которой, получающие определенные имена, задают действительное множество состояний, которыми вы хотите управлять посредством того или иного конечного автомата.
Иногда удобно использовать несколько конечных автоматов в одном приложении. Конечный автомат, который управляет кэшированными данными, извлеченными из базы данных, может использоваться наряду с независимым конечным автоматом, управляющим такими графическими объектами, как перья и кисти, кэшируемыми для их использования в обычных задачах рисования. Третий конечный автомат может управлять выполнением задач фоновыми потоками. И хотя все перечисленные конечные автоматы можно было бы объединить в один "главный конечный автомат", такой комбинированный конечный автомат представлял бы просто формальное объединение всех возможных случаев изменения состояния приложения и не дал бы ничего нового, поскольку состояния, которыми управляют отдельные конечные автоматы, слабо или вообще не коррелируют друг с другом. Точно так же, возможна крайность другого рода, когда вместо создания одного конечного автомата, выполняющего всю работу, предпочитают иметь десятки небольших конечных автоматов, каждый из которых управляет отдельной переменной приложения. Роль ключа к нахождению правильного решения играет корреляция. Если можно выделить набор переменных, объектов или ресурсов, которые тем или иным образом коррелируют между собой, то управление этим набором удобно и целесообразно осуществлять при помощи одного конечного автомата.
Читать дальше