Определение шаблонов проектирования: краткие и элегантные решения конкретных проблем объектно-ориентированного проектирования программного обеспечения
Конечно, можно воспользоваться расхожей поговоркой: шаблон проектирования — это решение проблемы в конкретном сценарии. Поэтому, когда мы сталкиваемся с подходящим сценарием, мы, естественно, можем подумать о шаблоне проектирования, который соответствует этому сценарию.
Например, когда структура интерфейса в системе уже не соответствует нашим текущим бизнес-потребностям, но этот интерфейс нельзя изменить, потому что от этого интерфейса могут зависеть многие функции исходной системы, а при изменении интерфейса будет задействовано слишком много файлов . Поэтому в ответ на этот сценарий мы можем быстро подумать, что шаблон адаптера можно использовать для решения этой проблемы.
Вот несколько шаблонов проектирования, распространенных в JavaScript:
1. Одноэлементный шаблон
Определение шаблона singleton: гарантирует, что класс имеет только один экземпляр, и предоставляет глобальную точку доступа для доступа к нему. Реализованный метод состоит в том, чтобы сначала определить, существует экземпляр или нет, и вернуть его напрямую, если он существует.Если он не существует, создать его, а затем вернуть, что гарантирует, что класс имеет только один объект-экземпляр.
Применимая сцена: один объект. Например: всплывающее окно, независимо от того, сколько раз вы нажимаете, всплывающее окно должно быть создано только один раз.
class CreateUser {
constructor(name) {
this.name = name;
this.getName();
}
getName() {
return this.name;
}
}
// 代理实现单例模式
var ProxyMode = (function() {
var instance = null;
return function(name) {
if(!instance) {
instance = new CreateUser(name);
}
return instance;
}
})();
// 测试单体模式的实例
var a = new ProxyMode("aaa");
var b = new ProxyMode("bbb");
// 因为单体模式是只实例化一次,所以下面的实例是相等的
console.log(a === b); //true
2. Режим стратегии
Определение шаблона стратегии: определите серию алгоритмов, инкапсулируйте их один за другим и сделайте их взаимозаменяемыми.
Цель шаблона стратегии состоит в том, чтобы отделить реализацию алгоритма от его использования.
Программа, основанная на шаблоне стратегии, состоит как минимум из двух частей. Первая часть представляет собой набор классов стратегий (переменная), класс стратегий инкапсулирует конкретный алгоритм и отвечает за конкретный процесс расчета. Вторая часть — класс среды Context (без изменений), Context принимает запрос клиента, а затем делегирует запрос определенному классу политики. Для этого необходимо поддерживать ссылку на объект политики в Context.
/*策略类*/
var levelOBJ = {
"A": function(money) {
return money * 4;
},
"B" : function(money) {
return money * 3;
},
"C" : function(money) {
return money * 2;
}
};
/*环境类*/
var calculateBouns =function(level,money) {
return levelOBJ[level](money);
};
console.log(calculateBouns('A',10000)); // 40000
3. Прокси-режим
Определение шаблона прокси: Предоставляет суррогат или заполнитель для объекта, чтобы управлять доступом к нему.
Часто используемая форма виртуального прокси: очень дорогая операция может быть отложена до тех пор, пока она не понадобится виртуальному прокси для ее создания (например: используйте виртуальный прокси для ленивой загрузки изображений)
Способ ленивой загрузки картинок: сначала занимаем место через загрузочную картинку, потом загружаем картинку асинхронно, а потом готовую картинку загружаем в тег img после загрузки картинки.
var imgFunc = (function() {
var imgNode = document.createElement('img');
document.body.appendChild(imgNode);
return {
setSrc: function(src) {
imgNode.src = src;
}
}
})();
var proxyImage = (function() {
var img = new Image();
img.onload = function() {
imgFunc.setSrc(this.src);
}
return {
setSrc: function(src) {
imgFunc.setSrc('./loading,gif');
img.src = src;
}
}
})();
proxyImage.setSrc('./pic.png');
Преимущество использования шаблона прокси для ленивой загрузки изображений заключается в том, что он соответствует принципу единой ответственности. Уменьшите детализацию и связанность класса или метода.
4. Модель посредника
Определение шаблона посредника: Через объект посредника все другие связанные объекты взаимодействуют через объект посредника вместо того, чтобы ссылаться друг на друга.Когда один из объектов изменяется, необходимо уведомить только объект посредника. Отношения тесной связи между объектами могут быть устранены с помощью шаблона посредника.
Например: в реальной жизни самолету на маршруте нужно связаться только с вышкой в аэропорту, чтобы определить маршрут и статус рейса, и не нужно связываться со всеми самолетами. В то же время, как посредник, башня знает статус полета каждого самолета, поэтому может организовать взлет, посадку и маршрутизацию всех самолетов.
Сценарии, в которых применим режим посредника: например, запрос корзины, наличие формы выбора продукта, формы выбора цвета, формы количества покупки и т. д. инициируют событие изменения, затем эти события могут быть перенаправлены и обрабатываются посредником для достижения развязки между событиями, просто поддерживайте объект посредника.
var goods = { //手机库存
'red|32G': 3,
'red|64G': 1,
'blue|32G': 7,
'blue|32G': 6,
};
//中介者
var mediator = (function() {
var colorSelect = document.getElementById('colorSelect');
var memorySelect = document.getElementById('memorySelect');
var numSelect = document.getElementById('numSelect');
return {
changed: function(obj) {
switch(obj){
case colorSelect:
//TODO
break;
case memorySelect:
//TODO
break;
case numSelect:
//TODO
break;
}
}
}
})();
colorSelect.onchange = function() {
mediator.changed(this);
};
memorySelect.onchange = function() {
mediator.changed(this);
};
numSelect.onchange = function() {
mediator.changed(this);
};
5. Шаблон декоратора
Определение шаблона декоратора: исходя из того, что сам объект не изменяется, динамически добавлять методы к объекту во время работы программы.
Например: существующие 4 типа велосипедов определены как отдельный класс.Если вы добавите 3 аксессуара, таких как фары, задние фонари и звонки к каждому велосипеду, если вы используете наследование классов, вам нужно создать 4 * 3 = 12 подклассов. Но если вы пройдете шаблон декоратора, вам нужно будет создать только 3 класса.
Сценарии, в которых применим шаблон декоратора: исходный метод остается неизменным, а другие методы монтируются на исходный метод для удовлетворения существующих требований, развязка функций, функция делится на несколько повторно используемых функций, а затем выполняется развязка. Функция монтируется на функцию для достижения того же эффекта, но для повышения возможности повторного использования.
Пример. Реализация шаблона декоратора с декоративными функциями АОП
Function.prototype.before = function(beforefn) {
var self = this; //保存原函数引用
return function(){ //返回包含了原函数和新函数的 '代理函数'
beforefn.apply(this, arguments); //执行新函数,修正this
return self.apply(this,arguments); //执行原函数
}
}
Function.prototype.after = function(afterfn) {
var self = this;
return function(){
var ret = self.apply(this,arguments);
afterfn.apply(this, arguments);
return ret;
}
}
var func = function() {
console.log('2');
}
//func1和func3为挂载函数
var func1 = function() {
console.log('1');
}
var func3 = function() {
console.log('3');
}
func = func.before(func1).after(func3);
func();