Саме це допомогло мені зрозуміти різницю завдяки публікації в блозі Паскаля Прехта.
Служба - це метод модуля, який приймає ім'я та функцію, яка визначає службу. Ви можете вводити та використовувати таку послугу в інших компонентах, як контролери, директиви та фільтри. Фабрика - це метод модуля, і він також приймає ім'я та функцію, яка визначає завод. Ми також можемо вводити і використовувати це так само, як ми це робили зі службою.
Об'єкти, створені за допомогою нового використання значення властивості прототипу їх конструктора функціонують як їх прототип, тому я знайшов кутовий код, який викликає Object.create (), і я вважаю, що це функція конструктора служб, коли вона отримує екземпляр. Однак фабрична функція насправді є лише функцією, яку викликають, тому ми мусимо повертати об'єкт буквально для фабрики.
Ось кутовий код 1,5, який я знайшов для фабрики:
var needsRecurse = false;
var destination = copyType(source);
if (destination === undefined) {
destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
needsRecurse = true;
}
Кутовий фрагмент вихідного коду для функції factory ():
function factory(name, factoryFn, enforce) {
return provider(name, {
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
}
Він приймає ім'я та фабричну функцію, яка передається, і повертає постачальника з тим же ім'ям, який має метод $ get, який є нашою заводською функцією. Щоразу, коли ви запитуєте інжектор про конкретну залежність, він, як правило, запитує у відповідного постачальника примірник цієї послуги, зателефонувавши методу $ get (). Ось чому під час створення провайдерів потрібно $ get ().
Ось кутовий код 1,5 для обслуговування.
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
Виявляється, коли ми викликаємо службу (), вона насправді викликає factory ()! Однак це не просто передає функцію нашого конструктора сервісу на завод, як є. Він також передає функцію, яка просить інжектор створити об'єкт даним конструктором.
Іншими словами, якщо ми вводимо MyService кудись, що в коді відбувається:
MyServiceProvider.$get(); // return the instance of the service
Щоб відновити його ще раз, служба викликає фабрику, що є методом $ get () відповідного постачальника. Більше того, $ injector.instantiate () - це метод, який в кінцевому підсумку викликає Object.create () з функцією конструктора. Ось чому ми використовуємо "це" в сервісах.
Для ES5 не має значення, який ми використовуємо: service () або factory (), це завжди називається фабрика, яка створює постачальника нашої послуги.
Ви можете зробити те саме, що і з сервісами. Сервіс - це конструкторська функція, однак це не заважає нам повернути об'єктні літерали. Таким чином, ми можемо взяти наш сервісний код і записати його таким чином, що він в основному робить те саме, що і наш завод, або іншими словами, ви можете написати службу як завод, щоб повернути об’єкт.
Чому більшість людей рекомендують використовувати фабрики через послуги? Це найкраща відповідь, яку я бачив із книги книги Павла Козловського: Освоєння розробки веб-додатків з AngularJS.
Фабричний метод - найпоширеніший спосіб потрапляння об'єктів у систему впорскування залежності AngularJS. Він дуже гнучкий і може містити складну логіку створення. Оскільки фабрики є регулярними функціями, ми також можемо скористатися новою лексичною сферою для імітації "приватних" змінних. Це дуже корисно, оскільки ми можемо приховати деталі реалізації певної послуги. "