Фабричные шаблоны и 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]);
Для меня это не слишком увлекательно и, конечно, не является веской причиной, заставляющей меня задуматься о том, должно ли это быть обслуживанием или фабрикой. Мой совет - забыть, что сервис () существует, и просто использовать фабрики