Паттерн Фасад

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

Паттерн Фасад

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

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

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

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

Масштабируемость

Применение паттерна Фасад дает нам гибкость при масштабируемости. Фасад, как мы помним, дает лишь интерфейс, для взаимодействия со всей системой в целом. А как работают отдельные подсистемы пользователя волновать не должно вообще. Так вот, если допустим одна из подсистем для работы с DOM использовала jQuery, вполне вероятно, что разработчик этой подсистемы решит, что пора облегчить этот модуль и перейти на Zepto или вовсе на чистый JavaScript. С точки зрения конечного пользователя фасада - ничего не изменится, ведь он и не знает ничего о том модуле, в котором программист навел порядок.

Пример

Напишем простой пример магазина телефонов. Как у любого магазина, у нашего будет свой склад. Как только человек захочет купить какую-либо модель телефона, мы будем брать ее со склада и отдавать покупателю. Если на складе данной модели не будет, мы закажем ее у производителя, поместим на склад, а затем, забрав со склада продадим покупателю. Очевидно, что покупателю знать об этих тонкостях не нужно, поэтому для него мы создаем фасад в виде магазина, у которого будет лишь только один метод - купить.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//Производитель
var Apple = {
buy: function (model) {
return this._create(model);
},
_create: function (model) {
//сложный процесс производства модели
return model;
}
};

//Склад
var Stock = {
_stock: [],
//добавление на склад
add: function (product) {
this._stock.push(product);
},
//получение со склада
get: function (product) {
var self = this,
stockProduct;


this._stock.forEach(function (item, index) {
if (item === product) {
stockProduct = self._stock.splice(index, 1);
}
});

return stockProduct ? stockProduct[0] : null;
}
};

//Магазин
var Shop = {
//фасад магазина - интерфейс для покупки
buy: function (product) {
return this._getFromStock(product);
},
//внутрений метод магазина по получению продукта
_getFromStock: function (product) {
var stockProduct;


stockProduct = Stock.get(product);
//если есть на складе - отдаем
if (stockProduct) {
return stockProduct;
}
//если нет на складе - покупаем у производителя и кладем на склад
Stock.add(Apple.buy(product));

//отдаем со склада
return Stock.get(product);
}
};

//Добавим на склад несколько моделей
Stock.add('iPhone 3g');
Stock.add('iPhone 4');
Stock.add('iPhone 4s');
Stock.add('iPhone 5s');

//Купим модель, которая есть на складе
console.log(Shop.buy('iPhone 3g'));
//Купим модель, которой нет на складе
console.log(Shop.buy('iPhone 6'));

Поиграться с примером можно традиционно в JSFiddle. Не забудьте открыть консоль.