Специализированный стиль проектирования, ориентированный на максимально возможный учет специфики конкретной задачи, часто встречается в тех случаях, когда приложение в процессе разработки постепенно усложняется. Различные аспекты состояния приложения изменяются в разных местах приложения. Данные о состоянии хранятся в таких свойствах элементов управления, как Visible, Enabled, Size или Position. Переменные, используемые для хранения ключевой информации о состоянии, изменяются непосредственно в тех строках кода, где это оказывается необходимым, а загрузка данных и освобождение памяти от них распределяются по всему приложению в зависимости от конкретной ситуации. Развитие событий напоминает "перетягивание каната" между различными частями приложения, поскольку каждая из функций делает все необходимое для выполнения возложенных на нее задач, не обращая никакого внимания на остальную часть приложения. Простейшим примером подобного поведения может служить код, реагирующий на такие события пользовательского интерфейса, как щелчок на кнопке, которой соответствует встроенный код, изменяющий состояние приложения. В листинге 5.2 приведен типичный код, встречающийся в классах формы приложения, соответствующих описанному подходу. Как код события загрузки формы form1, так и код события щелчка кнопки button1 вносят изменения, которые влияют на общее состояние формы.
//Код, выполняющийся при загрузке формы
private void Form1_Load(object sender, System.EventArgs e) {
textBox1.Visible = true;
listBox1.Visible = false;
}
string m_someImportantInfo;
//Пользователь щелкнул на кнопке, желая перейти к выполнению
//следующего шага, предусмотренного в данном приложении. Скрыть
//текстовое окно и отобразить окно списка в отведенном для этого месте
private void button1_Click(object sender, System.EventArgs e) {
m_someImportantInfo = textBox1.Text;
textBox1.Visible = false;
listBox1.Visible = true;
}
Подход 2: плановое, централизованное, явное управление состояниями (удачный подход)
Явное управление состояниями — прямая противоположность предыдущему подходу. В этом случае любые переходы между состояния реализуются в рамках одной главной функции. В коде обработчика событий, ответственном за изменение некоторого аспекта состояния приложения, это обеспечивается вызовом единственной функции, которая также вызывается любым другим кодом, предназначенным для изменения состояния приложения в соответствии с логикой приложения. Пример реализации такого подхода представлен в листинге 5.3.
string m_someImportantInfo;
//Определить состояния, в которых может находиться приложение
enum MyStates {
step1, step2
}
//Главная функция, которая вызывается
//всякий раз, когда возникает необходимость
//в изменении состояния приложения
void ChangeApplicationState(MyStates newState) {
switch (newState) {
case MyStates.step1:
textBox1.Visible = true;
listBox1.Visible = false;
break;
case MyStates.step2:
m_someImportantInfo = textBox1.Text;
textBox1.Visible = false;
listBox1.Visible = true;
break;
}
}
//Пользователь щелкнул на кнопке, желая перейти к выполнению
//следующего шага, предусмотренного в данном приложении. Скрыть
//текстовое окно и отобразить окно списка в отведенном для этого месте
private void button1_Click(object sender, System.EventArgs e) {
//Вызвать главную функцию, осуществляющую изменение состояния
ChangeApplicationState(MyStates.step2);
}
//Код, выполняющийся при загрузке формы