301 votes

AngularJS : Quand utiliser un service plutôt qu'une fabrique

Je vous prie d'être indulgent avec moi. Je sais qu'il y a d'autres réponses telles que : AngularJS : service, fournisseur et usine

Cependant, je n'arrive toujours pas à comprendre quand on utilise le service plutôt que l'usine.

D'après ce que j'ai pu constater, la notion de "factory" est généralement utilisée pour créer des fonctions "communes" qui peuvent être appelées par plusieurs contrôleurs : Création de fonctions de contrôleur communes

La documentation d'Angular semble préférer l'usine au service. Ils font même référence à "service" lorsqu'ils utilisent factory, ce qui est encore plus déroutant ! http://docs.angularjs.org/guide/dev_guide.services.creating_services

Alors, quand utiliser le service ?

Y a-t-il quelque chose qui n'est possible ou qui est beaucoup plus facile à faire qu'avec le service ?

Y a-t-il quelque chose de différent qui se passe en coulisses ? Des différences de performance/mémoire ?

Voici un exemple. À part la méthode de déclaration, ils semblent identiques et je n'arrive pas à comprendre pourquoi je ferais l'un plutôt que l'autre. http://jsfiddle.net/uEpkE/

Mise à jour : D'après la réponse de Thomas, il semble que service soit destiné à une logique plus simple et factory à une logique plus complexe avec des méthodes privées. J'ai donc mis à jour le code ci-dessous et il semble que les deux soient capables de prendre en charge les fonctions privées ?

myApp.factory('fooFactory', function() {
    var fooVar;
    var addHi = function(foo){ fooVar = 'Hi '+foo; }

    return {
        setFoobar: function(foo){
            addHi(foo);
        },
        getFoobar:function(){
            return fooVar;
        }
    };
});
myApp.service('fooService', function() {
    var fooVar;
    var addHi = function(foo){ fooVar = 'Hi '+foo;}

    this.setFoobar = function(foo){
        addHi(foo);
    }
    this.getFoobar = function(){
        return fooVar;
    }
});

function MyCtrl($scope, fooService, fooFactory) {
    fooFactory.setFoobar("fooFactory");
    fooService.setFoobar("fooService");
    //foobars = "Hi fooFactory, Hi fooService"
    $scope.foobars = [
        fooFactory.getFoobar(),
        fooService.getFoobar()
    ];
}

0 votes

Bien sûr, le service supporte le private mais si vous lisez correctement mon post, c'est purement du style de code : nous pouvons aussi profiter d'une nouvelle portée lexicale pour simuler des variables "privées". C'est "SIMULATE".

0 votes

Je trouve cette discussion très utile stackoverflow.com/questions/15666048/

2 votes

2voto

Même quand on dit que tous les services et toutes les usines sont singleton, je ne suis pas d'accord à 100 % avec cela. Je dirais que les fabriques ne sont pas des singletons et c'est le point de ma réponse. Je réfléchirais vraiment au nom qui définit chaque composant (Service/Factory), je veux dire :

A usine car ce n'est pas un singleton, vous pouvez en créer autant que vous le souhaitez lors de l'injection, il fonctionne donc comme une usine d'objets. Vous pouvez créer une usine d'une entité de votre domaine et travailler plus confortablement avec ces objets qui pourraient être comme un objet de votre modèle. Lorsque vous récupérez plusieurs objets, vous pouvez les mapper dans ces objets et ils peuvent agir comme une autre couche entre le DDBB et le modèle AngularJs. Vous pouvez ajouter des méthodes aux objets afin de les orienter un peu plus vers votre application AngularJs.

Pendant ce temps, un service est un singleton, donc nous ne pouvons créer qu'une seule instance d'un même type, peut-être pas créer mais nous n'avons qu'une seule instance lorsque nous injectons dans un contrôleur, donc un service fournit plus comme un service commun (appels de repos, fonctionnalité..) aux contrôleurs.

D'un point de vue conceptuel, on peut penser que les services fournissent un service, les usines peuvent créer plusieurs instances (objets) d'une classe.

0voto

Nishant Upadhyay Points 414

Services

Syntaxe : module.service( 'serviceName', function ) ; Résultat : Lorsque vous déclarez serviceName comme argument injectable, vous recevrez la référence de la fonction réelle passée à module.service.

Utilisation : Pourrait être utile pour partager des fonctions utilitaires qu'il est utile d'invoquer en ajoutant simplement () à la référence de la fonction injectée. Peut également être exécuté avec injectedArg.call( this ) ou similaire.

Usines

Syntaxe : module.factory('factoryName', function ) ;

Résultat : Lorsque vous déclarez factoryName en tant qu'argument injectable, on vous fournira la valeur renvoyée en invoquant la référence de la fonction passée à module.factory.

Utilisation : Pourrait être utile pour retourner une fonction 'classe' qui peut ensuite être new'ed pour créer des instances.

Prestataires

Syntaxe : module.provider( 'providerName', function ) ;

Résultat : Lorsque vous déclarez providerName en tant qu'argument injectable, on vous fournira la valeur renvoyée en invoquant la méthode $get de la référence de fonction passée à module.provider.

Utilisation : Pourrait être utile pour retourner une fonction 'classe' qui peut ensuite être new'ed pour créer des instances mais qui nécessite une sorte de configuration avant d'être injectée. Peut-être utile pour les classes qui sont réutilisables à travers les projets ? Encore un peu flou sur ce point.

0voto

vijay Points 3460

Peut utiliser les deux comme vous le souhaitez : si créer un objet ou j ust pour accéder aux fonctions des deux


Vous pouvez créer un nouvel objet à partir du service

app.service('carservice', function() {
    this.model = function(){
        this.name = Math.random(22222);
        this.price = 1000;
        this.colour = 'green';
        this.manufacturer = 'bmw';
    }
});

.controller('carcontroller', function ($scope,carservice) { 
    $scope = new carservice.model();
})

Note :

  • Le service renvoie par défaut un objet et non une fonction de construction.
  • C'est pourquoi la fonction constructeur est définie sur la propriété this.model.
  • Ce service renverra un objet, mais à l'intérieur de cet objet, il y aura une fonction de construction qui sera utilisée pour créer un nouvel objet ;

Vous pouvez créer un nouvel objet à partir de la fabrique

app.factory('carfactory', function() {
    var model = function(){
        this.name = Math.random(22222);
        this.price = 1000;
        this.colour = 'green';
        this.manufacturer = 'bmw';
    }
    return model;
});

.controller('carcontroller', function ($scope,carfactory) { 
    $scope = new carfactory();
})

Note :

  • factory par défaut retourne la fonction constructeur et non l'objet .
  • C'est pourquoi un nouvel objet peut être créé avec la fonction constructeur.

Créer un service pour accéder à des fonctions simples

app.service('carservice', function () {
   this.createCar = function () {
       console.log('createCar');
   };
   this.deleteCar = function () {
       console.log('deleteCar');
   };
});

.controller('MyService', function ($scope,carservice) { 
    carservice.createCar()
})

Créer une usine pour accéder aux fonctions simples

app.factory('carfactory', function () {
    var obj = {} 
        obj.createCar = function () {
            console.log('createCar');
        };
       obj.deleteCar = function () {
       console.log('deleteCar');
    };
});

.controller('MyService', function ($scope,carfactory) { 
    carfactory.createCar()
})

Conclusion :

  • vous pouvez utiliser les deux comme vous le souhaitez que ce soit pour créer un nouvel objet ou juste pour accéder à des fonctions simples
  • Il n'y aura pas de perte de performance, en utilisant l'un plutôt que l'autre.
  • Les deux sont des objets singleton et une seule instance est créée par application.
  • Il n'y a qu'une seule instance chaque fois que leur référence est transmise.
  • Dans la documentation angulaire l'usine est appelée service et aussi le service est appelé service .

0voto

user3114005 Points 11

L'usine et le service sont les méthodes les plus couramment utilisées. La seule différence entre elles est que la méthode Service fonctionne mieux pour les objets qui nécessitent une hiérarchie d'héritage, tandis que la méthode Factory peut produire des primitives et des fonctions JavaScript.

La fonction Provider est la méthode de base et toutes les autres ne sont que du sucre syntaxique. Vous n'en avez besoin que si vous construisez un morceau de code réutilisable qui nécessite une configuration globale.

Il existe cinq méthodes pour créer des services : Value, Factory, Service, Provider et Constant. Vous pouvez en apprendre davantage à ce sujet ici service angulaire Cet article explique toutes ces méthodes à l'aide d'exemples pratiques.

.

0voto

Gileno Points 58

À noter Un guide de style AngularJS pour les utilisateurs de Closure chez Google où il est dit :

Les services enregistrés sur le module avec module.service sont des classes. Utilisez module.service au lieu de module.provider ou module.factory à moins que vous n'ayez besoin d'effectuer une initialisation allant au-delà de la simple création d'une nouvelle instance de la classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X