Services vs. Factories in Angular

EDIT 2016. Merk op dat deze post, die een repost is van een post uit 2015, gaat over Angular 1. Ik doe geen frontend meer, dus geen garanties dat deze post relevant is voor Angular 2 ;).

Een van mijn Hack Reactor-klasgenoten en ik hebben onlangs een hoge bloeddrukbehandelingscalculator gebouwd voor Moxe Health, een spannend Rock Health-bedrijf dat een database-integratiesysteem en API bouwt waarmee elke ontwikkelaar toegang krijgt tot de elektronische medische dossiers van elk ziekenhuis in Moxe’s netwerk. Ik ben enthousiast om te praten over Moxe en het project in een andere post. We bouwden de front-end van de app in Angular, een krachtig front-end framework met data binding en andere geweldige functies. Een ding dat verwarrend was, was wanneer services vs. factories te gebruiken. Stack Overflow heeft een goede thread over het verschil tussen de twee, maar het laat een aantal analogieën weg waarvan ik denk dat ze nuttig zijn voor ontwikkelaars die nog bezig zijn hun Javascript kennis te cementeren.

In deze post, ga je het verschil tussen de twee leren.

TLDR – factories en services hebben vrijwel dezelfde functionaliteit in termen van hun vermogen om methoden en eigenschappen te instantiëren en in te kapselen, net zoals functionele instantiatie en pseudoklassieke instantiatiepatronen vergelijkbare capaciteiten hebben. Er is geen voorkeur in de Angular gemeenschap voor het gebruik van de een of de ander. Factory en service recepten zijn gewoon syntactische suiker bovenop het provider recept. Dus de vraag die je jezelf moet stellen is meestal niet “moet ik factories of services gebruiken?” maar “moet ik functionele instantatie of pseudoklassieke instantiatie gebruiken?”

Anders dan dat high-level begrip, is het belangrijkste verschil dat als gevolg van het verschil in hun instantiatiepatronen, fabrieken primitieven en functies kunnen retourneren, maar services niet.

Primitieven, functies en objecten, oh my!

Check out this JSFiddle. Krediet aan Epokk voor het verstrekken van het grootste deel van de code. Ik maakte een paar wijzigingen die opnieuw, echt helpen ontwikkelaars die nieuw zijn voor Angular te boren op het verschil hier. Als je nieuw bent met JSFiddle, het is een tool waarmee je gemakkelijk interacties kunt testen tussen je javascript, html en css bestanden. Dus je kunt spelen met de code, en het zal niet de originele code overschrijven in de link.

Zowel de service en de factory in dit voorbeeld hebben dezelfde functionaliteit van het retourneren van de string “Hello World!”. Het verschil is hoe ze het doen.

De service instantieert een object en wijst de functie die “Hello World!” retourneert toe aan de “sayHello” eigenschap van dat object:

this.sayHello = function() { return "Hello, World!" };

De methode wordt dan aangeroepen in de controller: helloWorldFromService.sayHello().

De fabriek retourneert een functie die “Hello World!” retourneert:

return function() { return "Hello, World!" };

De functie wordt dan aangeroepen in de controller: helloWorldFromFactory(). Merk op hoe de verwijzing van de fabriek wijst naar de geretourneerde functie, in plaats van de eigenschap van een object waarvan de waarde een functie is, zoals in het service voorbeeld. Een service zou dit nooit kunnen doen, omdat een service een leeg object moet instantiëren waarvan de referentie binnen de service functie ‘dit’ is. Services retourneren altijd objecten.

Hier is het deel van fabrieken dat verwarrend kan zijn. De fabriek kan ook een object retourneren dat een methode ‘sayHello’ heeft, net als de service:

return { sayHello: function() { return "Hello, World!" } };

Die je in de controller zou aanroepen precies zoals je de sayHello functie van de service zou aanroepen: helloWorldFromFactory.sayHello().

De laatste fabriek formaat is handig wanneer u wilt dat meerdere methoden in een fabriek:

return { sayHello: function() { return "Hello, World!" }, sayGoodbye: function() { return "Goodbye, World!" } };

Nogmaals, de sleutel hier is niet verstrikt raken in het feit dat je coderen in Angular, en te onthouden dat de verschillen tussen diensten en fabrieken zijn voor het grootste deel hetzelfde als de verschillen tussen pseudoklassieke instantiatie en functionele instantiatie.

Broncode voor de nieuwsgierigen

Hier is de Angular broncode, die laat zien dat services & fabrieken zijn gelaagd bovenop de meer algemene providers functie:

//provider function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name); } return providerCache = provider_; } //factory function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); } //service function service(name, constructor) { return factory(name, ); }

Zowel service als factory creëren singletons. Basis functionele vs pseudoklassieke overervingspatronen hier. De fabriek retourneert wat de factoryFn retourneert.

De service retourneert een instantie van een pseudo-klasse. De constructor van de pseudo-klasse wordt doorgegeven aan Angular’s service builder service(). Het feit dat de constructor wordt doorgegeven aan de service builder service (return $injector.instantiate(constructor)) kan verwarrend zijn, maar zie het gewoon als return new constructor().

Happy coding!

Leave a Reply