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

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

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

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

Я, очевидно, не делаю этого ниже (поскольку я следую шаблону из ресурсного документа ). Но затем я пытался выяснить, к какому поставщику это относится, и я не уверен, и они не включают заметки о передовом опыте для любого из других подробно описанных видов поставщиков. Должен ли я использовать 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'}
        }
    );
}

person bstockwell    schedule 16.12.2015    source источник


Ответы (1)


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

С фабрикой вы предоставляете функцию, которая возвращает объект, который вы хотите использовать для инжектора angular. Со службой вы предоставляете функцию конструктора. Затем инжектор создает объект, который будет внедрен путем обновления объекта с помощью предоставленной функции. Angular factory и сервис всегда являются синглтонами, поэтому предоставление функции 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;
}

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

...

.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
    }
}

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

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

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]);

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

person Dustin Hodges    schedule 16.12.2015
comment
Спасибо, это полезно. Я определенно согласен с тем, что существует довольно двусмысленное различие. - person bstockwell; 16.12.2015
comment
Я надеюсь, что кто-то еще звонит здесь. Я хотел бы услышать чье-либо мнение по этому поводу. Особенно, если есть веская причина для создания услуги - person Dustin Hodges; 17.12.2015