Как я должен осуществить рефакторинг свой код для удаления ненужных одиночных элементов?

Причина, по которой он не работает, заключается в том, что вы запускаете несколько вызовов извлечения, которые являются асинхронными, и устанавливаете состояние сразу после него. setState получит пустые фильмы в этом случае.

fetch api возвращает обещание, и вы должны установить свое состояние в обработчике разрешения обещаний. Измените ваш componentDidMount, как это.

componentDidMount() {

  fetch('https://api.themoviedb.org/3/movie/popular?api_key=APIKEY&page=1')
      .then(response => response.json())
      .then(data => {
          const movies = data.results;
          Promise.all(movies.map(movie => fetch(
            `https://api.themoviedb.org/3/movie/${movie.id}?api_key=APIKEY`
          )))
          .then(resp => Promise.all( resp.map(r => r.json()) ))
          .then(result => {
            const movies = result.map((data, i) => {
              const movie = Object.assign(movies[i], {
                genres: data.genres,
                homepage: data.homepage
              });
              return movie;
            });
            this.setState({
              movies
            });
          });
      })
}
20
задан Community 23 May 2017 в 11:54
поделиться

8 ответов

Внедрение зависимости является Вашим другом.

Смотрят на эти сообщения на превосходный Google Testing Blog :

, Надо надеяться, кто-то сделал платформу/контейнер DI для мира C++? Похож на Google, выпустил Среда тестирования C++ и Платформа Насмешки C++ , который мог бы выручить Вас.

19
ответ дан 30 November 2019 в 00:23
поделиться

Это не мыс Singleton, который является проблемой. Хорошо иметь объект, что только когда-либо будет один экземпляр. Проблемой является глобальный доступ. Ваши классы, которые используют Хранилище, должны получить экземпляр Хранилища в конструкторе (или иметь свойство Store / элемент данных, который может быть установлен), и они могут все получить тот же экземпляр. Хранилище может даже сохранить логику в нем, чтобы гарантировать, что только один экземпляр когда-либо создается.

3
ответ дан 30 November 2019 в 00:23
поделиться

Мой способ избежать одиночных элементов происходит из идеи, что "приложение, глобальное", не означает "VM, глобальный" (т.е. static). Поэтому я представляю ApplicationContext класс, который содержит много формирователя static одноэлементная информация, которая должна быть глобальным приложением, как хранилище конфигурации. Этот контекст передается во все структуры. При использовании какого-либо контейнера МОК или менеджера по сервису можно использовать это для получения доступа к контексту.

3
ответ дан 30 November 2019 в 00:23
поделиться

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

А класс параметра перемещает некоторые данные параметра к своему собственному классу, например, как это:

var parameterClass1 = new MenuParameter(menuBar, editor);
var parameterClass2 = new StuffParameters(sasquatch, ...);

var ctrl = new MyControllerClass(managedStore, parameterClass1, parameterClass2);

Это вид просто перемещает проблему в другое место все же. Вы могли бы хотеть обслужить своего конструктора вместо этого. Только сохраните параметры, которые важны, когда построение/инициирование, рассматриваемый класс и делает остальных с методом считывания/методами установщика (или свойства при выполнении.NET).

А метод фабрики является методом, который создает все экземпляры Вы потребность класса, и обладайте преимуществом инкапсуляции создания упомянутых объектов. К ним также довольно легко осуществить рефакторинг от Singleton, потому что они подобны getInstance методам, которые Вы видите в Шаблонах "одиночка". Скажите, что у нас есть следующий неориентированный на многопотоковое исполнение простой одноэлементный пример:

// The Rather Unfortunate Singleton Class
public class SingletonStore {
    private static SingletonStore _singleton
        = new MyUnfortunateSingleton();

    private SingletonStore() {
        // Do some privatised constructing in here...
    }

    public static SingletonStore getInstance() {
        return _singleton;
    }  

    // Some methods and stuff to be down here
}

// Usage: 
// var singleInstanceOfStore = SingletonStore.getInstance();

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

public class StoreWithFactory {

    public StoreWithFactory() {
        // If the constructor is private or public doesn't matter
        // unless you do TDD, in which you need to have a public 
        // constructor to create the object so you can test it.
    }

    // The method returning an instance of Singleton is now a
    // factory method. 
    public static StoreWithFactory getInstance() {
        return new StoreWithFactory(); 
    }
}

// Usage:
// var myStore = StoreWithFactory.getInstance();

Использование является все еще тем же, но Вы не срываетесь с наличием единственного экземпляра. Естественно Вы переместили бы этот метод фабрики для своего собственного класса как Store, класс не должен интересоваться созданием себя (и по совпадению следовать за Единственным Принципом Ответственности как за эффектом выгоняния с квартиры метода фабрики).

Отсюда у Вас есть много вариантов, но я оставлю это как осуществление для себя. Это легко сверхинженеру (или перегревание) на шаблонах здесь. Моя подсказка должна только применить шаблон, когда существует потребность в ней .

2
ответ дан 30 November 2019 в 00:23
поделиться

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

Тем не менее в Вашем примере, в приложении существует очевидная степень свободы: кто-то мог приехать и сказать, "но я хочу два хранилища".

существует несколько решений. Тот, который происходит, в первую очередь, должен создать класс фабрики; когда Вы просите Хранилище, оно дает Вам один названный с некоторым универсальным именем (например, URI.) В том хранилище, необходимо быть уверены, что несколько копий не ступают друг на друга через критические регионы или некоторый метод удостоверяющейся атомарности транзакций.

1
ответ дан 30 November 2019 в 00:23
поделиться

у MiЕЎko Hevery есть хороший ряд статьи на тестируемости, среди прочего одиночный элемент , где он не только говорит о проблемах, но также и как Вы могли бы решить его (см. 'Фиксацию дефекта').

1
ответ дан 30 November 2019 в 00:23
поделиться

Мне нравится поощрять использование одиночных элементов в случае необходимости при воспрепятствовании использования Шаблона "одиночка". Отметьте различие в случае слова. Одиночный элемент (нижний регистр) используется везде, где Вам только нужен один экземпляр чего-то. Это создается в начале Вашей программы и передается конструктору классов, которым нужен он.

class Log
{
  void logmessage(...)
  { // do some stuff
  }
};

int main()
{
  Log log;

  // do some more stuff
}

class Database
{
  Log &_log;
  Database(Log &log) : _log(log) {}
  void Open(...)
  {
    _log.logmessage(whatever);
  }
};

Используя одиночный элемент дает все возможности антишаблона Singleton, но он делает Ваш код более легко расширяемым, и он делает это тестируемым (в смысле слова определенный в блоге тестирования Google). Например, мы можем решить, что нам нужна способность зарегистрироваться к веб-сервису в несколько раз также, с помощью одиночного элемента, мы можем легко сделать это без существенных изменений к коду.

Для сравнения, Шаблон "одиночка" является другим названием глобальной переменной. Это никогда не используется в производственном коде.

1
ответ дан 30 November 2019 в 00:23
поделиться

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

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

Ясно, какова стоимость использования глобалов. Любая часть вашего приложения может изменить его. Отслеживать ошибки сложно, когда каждая строка кода является подозреваемой в расследовании. 1284 Но как насчет стоимости НЕ использования глобалов? Как и все остальное в программировании, это компромисс. Если вы избегаете использовать глобальные переменные, вы в конечном итоге должны передать эти объекты с состоянием в качестве параметров функции. Кроме того, вы можете передать их в конструктор и сохранить их как переменную-член. Когда у вас есть несколько таких объектов, ситуация ухудшается. Теперь вы работаете с своим состоянием. В некоторых случаях это не проблема. Если вы знаете, что только две или три функции должны обрабатывать этот объект Store с сохранением состояния, это лучшее решение. 1285 Но на практике это не всегда так. Если каждая часть вашего приложения коснется вашего Магазина, вы добавите в него десятки функций. Более того, Некоторые из этих функций могут иметь сложную бизнес-логику. Когда вы разбиваете эту бизнес-логику с помощью вспомогательных функций, вы должны еще больше продвинуть свое состояние! Например, вы понимаете, что глубоко вложенная функция нуждается в некоторых данных конфигурации из объекта Store. Внезапно, вам нужно отредактировать 3 или 4 объявления функций, чтобы включить этот параметр хранилища. Затем вы должны вернуться и добавить хранилище в качестве фактического параметра везде, где вызывается одна из этих функций. Может случиться так, что единственное использование функции для Магазина - это передать ее какой-то подфункции, которая в этом нуждается.

Шаблоны - это просто эмпирические правила. Вы всегда используете свои сигналы поворота перед тем, как менять полосу движения в своем автомобиле? Если вы обычный человек, вы, как правило, будете следовать правилу, но если вы едете в 4 часа утра по пустому шоссе, кто дерьмо, право? Иногда это кусает тебя в задницу, но это управляемый риск.

3
ответ дан 30 November 2019 в 00:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: