Edit Page

Facade


Три Базовых класса мета-паттерна MVC представлены в PureMVC классами Модели, Представления и Контроллера. Чтобы упростить процесс разработки приложения, PureMVC задействует паттерн Фасад.

Фасад распределяет ваши запросы к Модели, Представлению и Контроллеру, так что ваш код не нуждается в импорте этих классов и вам не нужно работать с ними индивидуально. Класс Фасада автоматически создает экземпляры базовых синглтонов MVC в своем конструкторе.

Обычно Фасад самого фреймворка становится над-классом вашего приложения и используется для инициализации Контроллера с назначениями Команд. Подготовка Модели и Представления затем дирижируется Командами, выполняемыми Контроллером.

Что такое Конкретный Фасад (Concrete Facade)?

Хотя Базовые классы являются завершенными, готовыми к использованию реализациями, Фасад предоставляет реализацию, которую следует рассматривать как абстрактную в том смысле, что вы никогда не создаете его экземпляр непосредственным образом.

Вместо этого вы наследуете Фасад из фреймворка и / или переопределяете некоторые его методы, чтобы сделать их полезными конкретно для вашего приложения. (вы конкретизируете абстрактный Фасад фреймворка в конкретный Фасад своего приложения).

Этот конкретный Фасад затем используется для доступа и оповещения Команд, Медиаторов и Прокси, которые делают свою работу в системе. По соглашению, он называется ‘ApplicationFacade’, но вы можете назвать его как хотите.

В общем случае иерархия Представления вашего приложения будет создаваться согласно принятого для вашей платформы процесса. Как только построена иерархия Представления приложения, стартует аппарат PureMVC и регионы Модели и Вида готовятся к использованию.

Ваш конкретный Фасад также используется для облегчения процесса старта приложения, в том смысле, что он освобождает основной код приложения от необходимости глубокой осведомленности об аппарате PureMVC, к которому это приложение будет подключено. Приложение просто передает ссылку на себя в метод ‘startup’ синглтон-экземпляра вашего конкретного Фасада.

Создание Конкретного Фасада для вашего приложения

Вашему конкретному Фасаду не обязательно прилагать много усилий, чтобы передать приложению силу PureMVC. Рассмотрим следующую реализацию:

export default (Module) => {
  const {
    STARTUP,
    Facade,
    initialize, partOf, meta, property, method, nameBy
  } = Module.NS;

  @initialize
  @partOf(Module)
  class ApplicationFacade extends Facade {
    @nameBy static  __filename = __filename;
    @meta static object = {};

    @property _isInitialized: boolean = false;

    @method startup(app) {
      if (!this._isInitialized) {
        this._isInitialized = true;
        this.send(STARTUP, app);
      }
    }

    @method initializeFacade(): void {
      super.initializeFacade(... arguments)
      this.rebind('ApplicationModule').toConstructor(this.Module);
      this.addCommand(STARTUP, 'StartupCommand');
    }
  }
}

Отметим несколько моментов в приведенном выше коде:

  • Он расширяет класс Facade PureMVC, который в свою очередь реализует интерфейс IFacade.
  • Он не переопределяет конструктор. Если бы он это делал, то нужно было бы вызвать конструктор суперкласса прежде, чем делать чтолибо.
  • Он определяет константы для имен Оповещений (STARTUP). Поскольку это игрок, используемый всеми другими участинками системы для доступа и связи друг с другом, конкретный Фасад является идеальным местом для определения констант, общих для всех участников обмена оповещениями.
  • Он инициализирует Контроллер Командами, которые будут выполняться при отправке соответствующих Оповещений.
  • Он предоставляет метод startup, который принимает один аргумент (в данном случае) типа MyApp, который с помощью Оповещения передается Команде StartupCommand (зарегистрированной на имя оповещения STARTUP).

С этими простыми требованиями реализации ваш конкретный Фасад унаследует ощутимую часть функциональности своего абстрактного класса-родителя.

Инициализация вашего Конкретного Фасада

Конструктор Фасада PureMVC вызывает защищенные методы для инициализации экземпляров Модели, Представления и Контроллера и кэширует их ссылки на них.

Затем по композиции Фасад реализует и делает доступными возможности Модели, Представления и Контроллера; агрегируя их функциональность и защищая разработчика от прямого взаимодействия с Базовыми классами фреймворка.

Итак, где и как Фасад внедряется в реальное положение вещей конкретного приложения? Рассмотрим упрощенный пример из реального приложения:

export default (Module) => {
  const {
    LIGHTWEIGHT,
    initialize, partOf, meta, property, method, nameBy,
    Utils: { uuid }
  } = Module.NS;

  @initialize
  @partOf(Module)
  class Application extends CoreObject {
    @nameBy static  __filename = __filename;
    @meta static object = {};

    @property isLightweight: boolean = false;
    @property name: string = null;

    @method start(): void {
      this.facade.startup(this);
    }

    @method async finish(): Promise<void> {
      await this.facade.remove();
    }

    constructor(name: string, ApplicationFacade: Class<*>, symbol: ?Symbol) {
      const isLightweight = symbol === LIGHTWEIGHT;
      if (isLightweight) {
        const appName = `${name}|>${uuid.v4()}`
        super(ApplicationFacade.getInstance(appName));
        this.name = appName;
      } else {
        super(ApplicationFacade.getInstance(name));
        this.name = name;
      }
      this.isLightweight = isLightweight;
    }
  }
}

Вот и все. Достаточно просто.

Создайте эту начальную иерархию вида, получите экземпляр ApplicationFacade и вызовите его метод startup.

Ключевые моменты этого примера:

  • Поскольку мы инициализируем переменную вызовом статического метода ApplicationFacade.getInstance, то это означает, что в момент создания Application будет создан Фасад, а вместе с ним и Модель, Представление и Контроллер, хотя ни Медиаторы, ни Прокси не будут пока созданы.
  • В отдельном методе start инстанса Application мы вызываем метод startup, передавая ему ссылку на главное приложение в качестве аргумента.

Заметьте, что обычные компоненты Представления не нуждаются в знании того, как им нужно взаимодействовать с Фасадом, но объект верхнего уровня Application является исключением для этого правила.

Верхнеуровневый объект Application строит иерархию Вида, инициализирует Фасад, а затем запускает аппарат PureMVC.