& Ldquo; Singleton & Rdquo; заводы, хорошо или плохо?

Вы можете получить правильный объект в соответствии с браузером с помощью

function getXmlDoc() {
  var xmlDoc;

  if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlDoc = new XMLHttpRequest();
  }
  else {
    // code for IE6, IE5
    xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");
  }

  return xmlDoc;
}

. С помощью правильного объекта GET может быть абстрагирован на:

function myGet(url, callback) {
  var xmlDoc = getXmlDoc();

  xmlDoc.open('GET', url, true);

  xmlDoc.onreadystatechange = function() {
    if (xmlDoc.readyState === 4 && xmlDoc.status === 200) {
      callback(xmlDoc);
    }
  }

  xmlDoc.send();
}

И POST к:

function myPost(url, data, callback) {
  var xmlDoc = getXmlDoc();

  xmlDoc.open('POST', url, true);
  xmlDoc.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

  xmlDoc.onreadystatechange = function() {
    if (xmlDoc.readyState === 4 && xmlDoc.status === 200) {
      callback(xmlDoc);
    }
  }

  xmlDoc.send(data);
}
30
задан leeeroy 16 August 2009 в 19:20
поделиться

6 ответов

Это действительно зависит от того, что вы делаете, и от области применения вашего приложения. Если это довольно маленькое приложение, и оно никогда не вырастет дальше этого, тогда ваш текущий подход вполне может подойти. Для этих вещей не существует универсальной "лучшей" практики. Хотя я бы не рекомендовал использовать синглтоны для чего-либо, кроме листовых методов без сохранения состояния и / или односторонних вызовов (например, журналирования), отклонять его из-под контроля «просто потому, что» это синглтон, не обязательно делать. 12126] Для чего-либо, кроме тривиального или прототипного кода, мне лично нравится явно использовать инверсию управления с внедрением конструктора, поскольку это означает, что все зависимости учтены, и вы не получите никаких «сюрпризов». Компилятор не позволит вам создать экземпляр A без B и B без C. Синглтоны немедленно похоронят эти отношения - вы можете создать экземпляр A без B и B без C. Когда произойдет вызов от A к B, вы получите исключение нулевой ссылки.

Это особенно раздражает при тестировании, поскольку вам приходится итеративно работать в обратном направлении через ошибки времени выполнения. Когда вы тестируете код, вы используете API так же, как это сделал бы другой программист, поэтому это свидетельствует о проблемах проектирования с этим подходом. Внедрение конструктора гарантирует, что этого никогда не произойдет - все зависимости указаны заранее. Обратной стороной внедрения конструктора является более сложная конфигурация графа объектов. Это смягчается за счет использования контейнера IoC.

Думаю, я пытаюсь сказать, что если вы дошли до точки, где вы ' Рассматривая использование какого-либо объекта контекста и шаблона реестра, вы также можете взглянуть на контейнеры IoC. Попытки развернуть собственную версию mutt, вероятно, будут пустой тратой времени, если вы можете использовать уже установленный бесплатный продукт, такой как Autofac.

14
ответ дан 27 November 2019 в 22:36
поделиться

Наличие нескольких синглтонов довольно типично и обычно не вызывает проблем - большое количество синглтонов приводит к некоторому раздражающему коду.

Мы только что прошли через ситуацию, когда нам пришлось протестировать наш сильно синглтонский -груженные классы. Проблема в том, что когда вы тестируете класс b и он получает класс c (одноэлементный), у вас нет возможности имитировать класс c (по крайней мере, EasyMock не позволит нам заменить статический фабричный метод одноэлементного класса.

Одно простое исправление - наличие "Сеттеров" для всех ваших синглтонов в целях тестирования. На самом деле не рекомендуется.

Еще мы попробовали создать единственный класс, который содержал все синглтоны - реестр. приближается к внедрению зависимостей, что вам почти наверняка стоит использовать.

Помимо тестирования, Я давно узнал, что когда никогда не будет больше одного экземпляра данного объекта; в следующей ревизии они часто хотят два, что делает синглтоны НАМНОГО лучше, чем статические классы - по крайней мере, вы можете добавить параметр к получателю синглтона и вернуть второй без особого рефакторинга (который снова просто делает то, что делает DI ).

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

11
ответ дан 27 November 2019 в 22:36
поделиться

Нет, потому что вы здесь создаете глобальное состояние. С глобальным состоянием возникают всевозможные проблемы, главная из которых заключается в том, что одна функция затем довольно незаметным образом зависит от поведения других функций. Если функция вызывает другую функцию, которая забывает сохранить и восстановить фабрику до ее завершения, то у вас есть проблема, потому что вы даже не можете вернуть старое значение, если не сохранили его где-нибудь. И для этого вам нужно добавить код (судя по вашему коду, я предполагаю, что вы используете язык с finally , что оставляет еще больше места для ошибок). Более того, если вы получите код, который должен быстро переключаться между двумя фабриками для двух подобъектов, вам нужно будет написать вызов метода в каждой точке - вы можете ' t хранить состояние в каждом подобъекте (ну, вы можете, но тогда вы побеждаете цель глобального состояния [что, по общему признанию, не так уж и много]).

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

6
ответ дан 27 November 2019 в 22:36
поделиться

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

У Миско Хевери есть хорошая статья об этом в своем блоге.

4
ответ дан 27 November 2019 в 22:36
поделиться

Плохая форма синглтона - это тот, который реализует эквивалент вашего метода Factory с:

return new CalculationFactory ();

Это гораздо сложнее заглушить, имитировать или обернуть.

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

1
ответ дан 27 November 2019 в 22:36
поделиться

Считается ли это лучшей практикой?

Я не вижу проблем: вы сказали, что «моим программам больше не нужно», поэтому ваша реализация чего-то более гибкого / абстрактного может быть случаем You Ain Это не понадобится .

4
ответ дан 27 November 2019 в 22:36
поделиться
Другие вопросы по тегам:

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