Прокси-режим режима внешнего дизайна

Шаблоны проектирования

предисловие

Адрес доставки:

Передняя часть режима заводского шаблона дизайна

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

прокси-режим

Что такое прокси-режим?

Определение шаблона прокси: режим прокси предоставляет прокси-объект для определенного объекта и используетсяПрокси-объект управляет ссылкой на исходный объект.通俗的来讲代理模式就是我们生活中常见的中介。

Зачем использовать прокси-режим

изоляция посредничества: В некоторых случаях клиентский класс не хочет или не может напрямую ссылаться на объект делегата, а объект прокси-класса может играть роль посредника между клиентским классом и объектом делегата, которая характеризуется тем, что прокси-класс и класс делегата реализовать тот же интерфейс.

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

взять каштан

Раз уж мы упомянули посредников, то должны сказать, что в нашей повседневной жизни существуют различные посредники, такие как агентства недвижимости, магазины 4S, билетные кассы и т.д.

По сути, зоомагазин в предыдущей статье тоже своего рода посредник, потому что все источники питомцев не генерируются напрямую в магазине, некоторые из них приходят из дикой природы, а некоторые — с ферм.

Поскольку мы хотим сделать наш бизнес больше и сильнее, нам необходимо использовать посредников, чтобы помочь нам расширить наш бизнес в настоящее время.

class headPet { // 宠物总店提供了最基础的出售,回购宠物的服务
  sellPet(name) { // 出售宠物
    console.log('出售一只宠物', name)
  }
  desert(name) { // 遗弃宠物
    console.log('遗弃一只宠物', name)
  }
}

class subPet extends headPet { // 宠物分店,我们提供搭配服务,以便更好地卖宠物
  constructor() {
    super()
  }
  sell(name) { // 出售宠物
    this.sellPet(name)
  }
  sellPetFood(name) { // 购买宠物食物送宠物活动
    console.log('搭配了一大波食粮')
    this.sellPet(name)
  }
  sellPetCage(name) { // 购买宠物笼子送宠物活动
    console.log('搭配一个大笼子')
    this.sellPet(name)
  }
}

const subPet1 = new subPet()
subPet1.sell('tom')
subPet1.sellPetFood('tom')
subPet1.sellPetCage('tom')

Из приведенной выше простой программы мы видим, что как филиал, при фактической продаже домашних животных, он также оснащен различными услугами, такими как корм для домашних животных и клетки для домашних животных, чтобы мы могли лучше продавать домашних животных, и, наконец, мы все еще называем Служба основного магазина, но филиал также предоставляет дополнительные услуги, что позволяет нашему бизнесу расширяться, что является расширением возможностей филиала в основном магазине.

Боевой проект

Далее используем идею агентского режима для проведения практических занятий в проекте.

Запросы прокси - чтение локального кеша

function ajax(params) { // 实际发送请求方法
  console.log(`发送请求${params}`)
  return params + Math.random()
}

const storage = new Map();

function cache(params) { // 缓存模式
  if (storage.has(params)) {
    return storage.get(params)
  }
  const value = ajax(params)
  storage.set(params, value)
  return value
}

function proxyAjax(params) { // 代理ajax请求
  return cache(params)
}

console.log(proxyAjax(1)) // 发送参数为1的请求
console.log(proxyAjax(1)) // 发送相同参数为1的请求,cache读取到缓存,所以不再调用ajax方法,直接返回结果
console.log(proxyAjax(2)) // 发送参数为2的请求,此时未读取到缓存,直接调用ajax方法,从后台请求

Из вышеприведенного кода нетрудно увидеть, что мы проксируем слой метода запроса ajax и добавляем слой кэша, который может помочь нам не вызывать http-запросы в случае запросов с одинаковыми параметрами, экономя некоторое время запроса и ресурсы .

Рекомендуется при фактическом использовании проекта пытаться судить по бизнесу, не кэшировать произвольно все запросы, вообще кэшироватьполучить запрос или запрос данных, где данные нелегко изменить.

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

Функция скрытой точки - глобальная выборка через прокси

const oldFetch = window.fetch;

function newFetch(url, init) { // 重新fetch方法,代理fetch本身的功能,添加埋点功能
  const { method = 'GET', body } = init || {};
  const fetchObj = {
    url: url,
    method: method,
    body: body,
    start: performance.now(),
  }
  
  ajaxEventTrigger.call(fetchObj, AJAX_START); // 自定义埋点监听方法
  
  return oldFetch.apply(this, arguments).then(function (response) {
    fetchObj.end = performance.now();
    if (response.ok) {
      ajaxEventTrigger.call(fetchObj, AJAX_END)
    } else {
      ajaxEventTrigger.call(fetchObj, AJAX_ERROR)
    }
    return response
  }).catch(function (error) {
    fetchObj.end = performance.now();
    fetchObj.error = error
    ajaxEventTrigger.call(fetchObj, AJAX_ERROR);
    throw error
  })
}

window.fetch = newFetch;

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

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

Кэширующий прокси — обработка времени кэширования

class Storage {

  constructor(props) { // 根据类型跟缓存时间,初始化缓存方法
    const { type, time } = props
    this.type = type
    this.time = time
    this.storageType = {
      local: 'localStorage',
      session: 'sessionStorage'
    }
  }

  setItem(key, value) { // 代理原生缓存方法,添加缓存时间
    window[this.storageType[this.type]].setItem(key, JSON.stringify({
      value,
      time: new Date().getTime()
    }));
  }

  getItem(key) { // 代理原生获取缓存方法,根据缓存时间,判断数据是否过期
    try {
      const { time, value } = JSON.parse(window[this.storageType[this.type]].getItem(key));
      const now = new Date().getTime()
      if (now > time + this.time) {
        window[this.storageType[this.type]].removeItem(key);
        return null
      } else {
        return value
      }
    } catch (e) {
      return null
    }
  }
}

const local = new Storage({ type: 'local', time: 30000 }) // 初始化localStorage,添加5分钟缓存时效
const session = new Storage({ type: 'session', time: 30000 }) // 初始化sessionStorage,添加5分钟缓存时效
local.setItem(1, 2)
local.getItem(1)
session.setItem(3, 4)
session.getItem(3)

Этот метод может быть дополнительно расширен, например, для различения по типу хранилища

Дополнительная информация

Полный демонстрационный адрес:Боевая демонстрация проекта, друзья, которым нравится, могутstarДалее мы будем постепенно расширять этот проект в соответствии с введением сообщения в блоге о режиме дизайна.

Здание города ручной собачьей головы

В этой статье используетсяmdniceнабор текста