Контролер аплікації (шаблон проєктування)
Контролер аплікації (англ. Application Controller) — шаблон проєктування, який дозволяє керувати порядком роботи аплікації залежно від стану.
Опис[ред. | ред. код]
Контролери сторінки відповідають за представлення сторінки користувачеві. При збільшені складності логіки аплікації вибір представлення дублюється в різних контролерах. Якщо логіка вибору представлення проста (інакше кажучи, якщо користувач може відкривати сторінки у довільному порядку), контролери сторінок являються самодостатніми, та не потребують змін. У випадку коли порядок відображення сторінок має значення в залежності від стану об'єкту, варто змінювати логіку.
Щоб запобігти повторам, необхідно винести логіку керування потоком виконання аплікації в окремий клас. В такому випадку контролери сторінок запитують контролери аплікації за операції, які варто виконати над моделлю та за представлення, яке необхідно відобразити користувачу.
Реалізація[ред. | ред. код]
Змоделюємо доменну область електронних черг. Нехай необхідно забронювати час на прийом до лікаря. Тоді потік виконання програми можна описати наступними кроками
Бронювання часу
- При спробі забронювати час можливий перехід в один із наступних станів:
- Стан помилки. На даний момент немає доступний вільних місць, час забронювати не вдалось.
- Підтвердження бронювання. Вільні місця є, час забронювати можна, необхідне підтвердження.
Підтвердження бронювання
Стан при якому користувач отримує повідомлення із кодом підтвердження.
- При підтверджені бронювання можливий перехід в один із наступних станів:
- Стан помилки. Введений код не вірний.
- Час заброньовано. Введений код вірний, бронювання підтверджено та створено.
Опишемо операції над моделлю предметної області у вигляді команд.
interface IReadOnlyState
{
object GetModel();
string GetViewName();
}
interface IState : IReadOnlyState
{
IState Execute();
}
class CreateReservationState : IState
{
public IState Execute()
{
// перевірка наявності місць
if (new Random().NextDouble() < 0.25)
{
return new ErrorState();
}
return new ConfirmReservationState();
}
public object GetModel() => new ReservationViewModel();
public string GetViewName() => "CreateReservationPage";
}
class ConfirmReservationState : IState
{
public IState Execute()
{
// перевірка коду
if (new Random().NextDouble() < 0.25)
{
return new ErrorState();
}
return new ReservationCreatedState();
}
public object GetModel() => new ConfirmReservationViewModel();
public string GetViewName() => "ConfirmPage";
}
class ReservationCreatedState : IState
{
public IState Execute() => null;
public object GetModel() => new ReservationCreatedViewModel();
public string GetViewName() => "SuccessPage";
}
class ErrorState : IState
{
public IState Execute() => null;
public object GetModel() => new ErrorViewModel();
public string GetViewName() => "ErrorPage";
}
Тоді контролери матимуть наступний вигляд:
class ApplicationController
{
private readonly Stack<IState> _history = new Stack<IState>();
public ApplicationController()
{
_history.Push(new CreateReservationState());
}
public IReadOnlyState GetNextView()
{
// зміна стану
var state = _history.Peek();
var nextState = state.Execute();
if (nextState != null) _history.Push(nextState);
return state;
}
public string GoBack()
{
return _history.Pop().GetViewName();
}
}
class ReservationController
{
private readonly ApplicationController _applicationController = new ApplicationController();
public ViewResult PressButton()
{
var state = _applicationController.GetNextView();
return View(state.GetViewName(), state.GetModel());
}
}
Див. також[ред. | ред. код]
- Скінченний автомат
- Стан (шаблон проєктування)
- Команда (шаблон проєктування)
- Контролер сторінки (шаблон проєктування)
Джерела[ред. | ред. код]
- Application Controller [Архівовано 21 жовтня 2020 у Wayback Machine.]