Фабричные шаблоны и ngResource

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

Когда я его строил, на глаза мне попалась строчка в угловом документе о провайдерах:

Рекомендация: назовите фабричные функции как Factory (например, apiTokenFactory). Хотя это соглашение об именах не требуется, оно помогает при навигации по базе кода или при просмотре трассировок стека в отладчике. ( источник)

Я, очевидно, не делаю этого ниже (как я следую шаблону из документа Doc). Но потом я пытался выяснить, к какому провайдеру это относится, и я не уверен, и они не содержат подробных заметок о лучших практиках для других провайдеров. Должен ли я использовать service() вместо factory()? (Я не могу найти четкий ответ.)

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

...

.factory("Entries",Entries)

...

function Entries($resource,config) {
    endpoint = config.endpoint + ":" + config.port + "/entry";
    return $resource(endpoint + '/:id', {id:'@id'},
        { 'get':    {method:'GET'},
          'create': {method:'POST'},
          'update': {method:'PUT'},
          'query':  {method:'GET', isArray:true},
          'remove': {method:'DELETE'},
          'delete': {method:'DELETE'}
        }
    );
}

1 ответ

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

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

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

...

.service("Entries",Entries)

...

function Entries($resource,config) {
    var endpoint = config.endpoint + ":" + config.port + "/entry";
    var resource = $resource(endpoint + '/:id', {id:'@id'},
        { 'get':    {method:'GET'},
          'create': {method:'POST'},
          'update': {method:'PUT'},
          'query':  {method:'GET', isArray:true},
          'remove': {method:'DELETE'},
          'delete': {method:'DELETE'}
        }
    );

    this.get = resource.get;
    this.create = resource.create;
    this.update = resource.update;
    this.query = resource.query;
    this.remove = resource.remove;
    this.delete = resource.delete;
}

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

...

.factory("Entries",Entries)

...

function Entries($resource,config) {
    var endpoint = config.endpoint + ":" + config.port + "/entry";
    var resource = $resource(endpoint + '/:id', {id:'@id'},
        { 'get':    {method:'GET'},
          'create': {method:'POST'},
          'update': {method:'PUT'},
          'query':  {method:'GET', isArray:true},
          'remove': {method:'DELETE'},
          'delete': {method:'DELETE'}
        }
    );

    return {
        get: resource.get,
        create: resource.create,
        update: resource.update,
        query: resource.query,
        remove: resource.remove,
        delete: resource.delete
    }
}

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

Учитывая, что у вас есть функция конструктора

function UnicornLauncher(apiToken) {

  this.launchedCount = 0;
  this.launch = function() {
    // Make a request to the remote API and include the apiToken
    ...
    this.launchedCount++;
  }
}

заводской провайдер будет выглядеть

myApp.factory('unicornLauncher', ["apiToken", function(apiToken) {
  return new UnicornLauncher(apiToken);
}]);

в то время как с услугой вы могли бы сделать его единоличным

myApp.service('unicornLauncher', ["apiToken", UnicornLauncher]);

Для меня это не слишком увлекательно и, конечно, не является веской причиной, заставляющей меня задуматься о том, должно ли это быть обслуживанием или фабрикой. Мой совет - забыть, что сервис () существует, и просто использовать фабрики

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