Внедрение принципа единой ответственности (SRP) в классе

Я хотел бы реорганизовать класс Cache, чтобы он не нарушал принцип единой ответственности (SRP).

Однако мне трудно понять, как я могу преобразовать ненужные шаги в Cache классе в memoize функцию. В идеале у меня было бы два метода в классе Cacheget и set

function isObject(arg) {
  const typeOfObj = typeof arg;
  return (typeOfObj === 'object' || typeOfObj === 'function') && arg !== null;
}

class Cache {
  constructor() {
    this.map = new Map();
    this.weakmap = new WeakMap();
  }

  // create or retrieve a nested Cache instance based on an arguments object
  get(args) {
    let cache = this;

    for (const key of args) {
      const map = cache[isObject(key) ? 'weakmap' : 'map'];
      cache = map.get(key) || map.set(key, new Cache()).get(key);
    }

    return cache;
  }
}

function memoize(fn) {
  const cache = new Cache();

  return (...args) => {
    // get (or create) a cache item

    const item = cache.get(args);
    if (Reflect.has(item, 'value')) {
      return item.value;
    }
    return (item.value = fn(args));
  };
}

let counter = 1;
function foo() {
  counter += 1;
  return counter;
}

const id1 = Symbol('id');
const id2 = Symbol('id');
const obj1 = { a: 1 };
const obj2 = { a: 1 };

const memoizedFoo = memoize(foo);
console.info(memoizedFoo(id1)); // 2
console.info(memoizedFoo(id1)); // 2
console.info(memoizedFoo(id2)); // 3
console.info(memoizedFoo(id2)); // 3
console.info(memoizedFoo(obj1)); // 4
console.info(memoizedFoo(obj1)); // 4
console.info(memoizedFoo(obj2)); // 5
console.info(memoizedFoo(obj2)); // 5
console.info(memoizedFoo(5)); // 6
console.info(memoizedFoo(5)); // 6
console.info(memoizedFoo(4)); // 7
console.info(memoizedFoo(4)); // 7
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Один из вариантов — иметь 3 метода в классе NestedCache:

  • getNestedMap для перебора карт с заданным массивом ключей
  • getMap, чтобы получить значение ключа на определенной карте
  • setKeyIfNeeded, чтобы установить значение ключа для карты, если она еще не существует

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

function isObject(arg) {
  const typeOfObj = typeof arg;
  return (typeOfObj === 'object' || typeOfObj === 'function') && arg !== null;
}

class NestedCache {
  constructor() {
    this.map = new Map();
    this.weakmap = new WeakMap();
  }

  // retrieve a nested Cache instance based on an array of keys
  getNestedMap(keys) {
    return keys.reduce((cache, key) => cache.getMap(key), this);
  }
  // return a Cache's value at a key
  getMap(key) {
    const map = this[isObject(key) ? 'weakmap' : 'map'];
    this.setKeyIfNeeded(map, key);
    return map.get(key);
  }
  // create a Cache's key, if needed
  setKeyIfNeeded(map, key) {
    if (!map.has(key)) {
      map.set(key, new NestedCache());
    }
  }
}

function memoize(fn) {
  const cache = new NestedCache();

  return (...args) => {
    // get (or create) a cache item
    const item = cache.getNestedMap(args);
    if (Reflect.has(item, 'value')) {
      return item.value;
    }
    return (item.value = fn(args));
  };
}

let counter = 1;
function foo() {
  counter += 1;
  return counter;
}

const id1 = Symbol('id');
const id2 = Symbol('id');
const obj1 = { a: 1 };
const obj2 = { a: 1 };

const memoizedFoo = memoize(foo);
console.info(memoizedFoo(id1)); // 2
console.info(memoizedFoo(id1)); // 2
console.info(memoizedFoo(id2)); // 3
console.info(memoizedFoo(id2)); // 3
console.info(memoizedFoo(obj1)); // 4
console.info(memoizedFoo(obj1)); // 4
console.info(memoizedFoo(obj2)); // 5
console.info(memoizedFoo(obj2)); // 5
console.info(memoizedFoo(5)); // 6
console.info(memoizedFoo(5)); // 6
console.info(memoizedFoo(4)); // 7
console.info(memoizedFoo(4)); // 7

Я пытаюсь получить getNestedMap из Class, если это возможно

John John 28.05.2019 04:27

Технически было бы довольно тривиально переместить getNestedMap из jsfiddle.net/mnhcp8s3, но я думаю, что все это (а также getMap и setKeyIfNeeded) больше связано с NestedCache, чем что-либо еще.

CertainPerformance 28.05.2019 04:41

Я вижу вашу точку зрения. поэтому имеет смысл просто иметь его в классе

John John 28.05.2019 04:45

Я так думаю - без методов, связанных с вложенными операциями, класс Cache был бы не более чем простым объектом.

CertainPerformance 28.05.2019 04:48

Спасибо за ваше объяснение. Я очень ценю это!

John John 28.05.2019 04:49

Другие вопросы по теме