Определение в википедии

Шаблон фасад (англ. Facade) — структурный шаблон проектирования, позволяющий скрыть сложность системы путём сведения всех возможных внешних вызовов к одному объекту, делегирующему их соответствующим объектам системы.

Шаблон проектирования - Фасад
Шаблон проектирования - Фасад

«Приёмы объектно-ориентированного проектирования. Па́ттерны проектирования» (англ. Design Patterns: Elements of Reusable Object-Oriented Software) — книга 1994 года о программной инженерии, описывающая шаблоны проектирования программного обеспечения. Авторами книги, которых прозвали «Бандой четырёх», являются Эрих ГаммаРичард ХелмРальф Джонсон  (англ.)рус.Джон Влиссидес

Теперь мы знаем официальные определение паттерна Фасад и давайте реализуем его на языке Dart.

Создаём класс с конструктором для наших данных, называться он будет Plane

class Plane {
  final String model;
  final int numberOfPassangers;
  final bool isCommerce;

  const Plane({
    required this.model,
    required this.numberOfPassangers,
    required this.isCommerce,
  });
}

Потом создаём необходимые интерфейсы. У нас будет 2 интерфейса и по 2 метода в каждом.

interface class IGetPlane {
  void getListPlane() {}
  void saveToFile() {}
}
interface class IExport {
  void exportToExel() {}
  void exportToWord() {}
}

Теперь создаём реализацию наших интерфейсов.

class ExportImpl implements IExport {
  final Plane plane;
  const ExportImpl({required this.plane});

  @override
  void exportToExel() {
    print('Экспорт в Эксель ${plane.model}');
  }

  @override
  void exportToWord() {
    print('Экспорт в Ворд');
  }
}

Не будем нагружать код реальными методами, а просто будем выводить что-то в консоль.

class GetPlaneImpl implements IGetPlane {
  @override
  void getListPlane() {
    print('получить список самолетов');
  }

  @override
  void saveToFile() {
    print('Сохранение в файл');
  }
}

А теперь мы создадим класс Facade, в который мы прокинем данные для наших методов и сделаем инстансы наших классов (ExportImpl и GetPlaneImpl) и сделаем единственный метод run, который будет запускать методы в наших 2х дочерних классах.

class Facade {
  final Plane plane;
  Facade(this.plane);

  late ExportImpl export = ExportImpl(plane: plane);
  final getPLANE = GetPlaneImpl();

  void run() {
    print(plane.model);
    getPLANE.getListPlane();
    export.exportToExel();
  }
}

Давайте теперь перейдём в main. Создаём наш самолёт с необходимыми данными. Делаем инстанс класса Фасад и вызываем метод run, который объединил в себе вызов внутренних методов других классов.

void main() {
  Plane plane = const Plane(
    model: 'Cesna 172',
    numberOfPassangers: 4,
    isCommerce: false,
  );

  Facade(plane).run();
}

Давайте запустим и посмотрим, что из этого выйдет!

Вывод в консоль
Вывод в консоль

Ну что же поздравляю, всё работает! Итак, мы с помощью языка Dart разобрали как организовать паттерн Фасад.

Комментарии (4)


  1. PackRuble
    06.01.2024 18:31
    +4

    Честно говоря, ваш Facade ни на секунду не фасад получился :)


  1. bondeg
    06.01.2024 18:31
    +1

    В другой статье уже отмечали, что интерфейс должен содержать один метод export, а в ворд, эксель или ещё куда-то экспортировать данные - это уже ответственность сервиса, который и будет реализовывать этот интерфейс.


    1. Metotron0
      06.01.2024 18:31
      -1

      Разве это зависит не от паттерна, применяемого уже для вывода данных? Там ведь может быть другой.


  1. Metotron0
    06.01.2024 18:31
    +1

    Перед тем, как показывать реализацию класса, неплохо бы дать описание, что он будет делать. Plane ведь может быть не только самолётом, но и планом: астральнпый план и всё такое вот. Некоторые больше играют в D&D, чем летают на самолётах на английском.

    Перед тем, как показывать, как какой-то класс реализует паттерн, было бы хорошо описать своими словами, что значит данное в начале официальное определение. Нужно просто создать какой-то объект, который знает, как реализуются те или иные методы, а внешний вызыватель будет обращаться к этому объекту, чтобы можно было менять количество и структуру этих методов, не заставляя вызывателя переписывать свой код, а переписывая только этот один объект? А если изменится количество параметров, то всё равно переписывать?

    То есть, вместо a.fn1(param1), b.fn2(param2) вызывается c.fun1(param1), e.fun2(param2)? В двух словах: почему это удобно?

    Для тех, кто не знаком с Dart, можно на словах описать, что тут у нас получилось? Какие методы класса Plane скрыты классом Facade? Как внешний код вызывал эти методы раньше и как стал вызывать теперь?

    Я слабо знаком с паттернами, могу выдавать вопросы, которые могут не возникнуть у человека, который уже всё знает и понял. Они могут казаться несущественными, но если статья должна научить тех, кто ничего не знает, то и у других могут возникнуть эти же вопросы.