AngularJS: Fabrika yerine servis ne zaman kullanılır?


296

Lütfen benimle burada kal. Bunun gibi başka cevaplar olduğunu biliyorum: AngularJS: Servis vs sağlayıcı vs fabrika

Ancak hizmeti fabrikada ne zaman kullanacağınızı hala anlayamıyorum.

Fabrikadan anlatabildiğim kadarıyla, birden fazla Denetleyici tarafından çağrılabilen "ortak" işlevler oluşturmak için yaygın olarak kullanılır: Ortak denetleyici işlevleri oluşturma

Açısal dokümanlar fabrika hizmetini tercih ediyor gibi görünüyor. Hatta daha da kafa karıştırıcı fabrika kullandıklarında "hizmet" anlamına gelir!http://docs.angularjs.org/guide/dev_guide.services.creating_services

Peki hizmet ne zaman kullanılır?

Hizmetle yapılabilecek veya daha kolay yapılabilecek bir şey var mı?

Perde arkasında farklı bir şey var mı? Performans / bellek farklılıkları?

İşte bir örnek. Deklarasyon yöntemi dışında, aynı görünüyorlar ve neden birini diğerine karşı yapacağımı anlayamıyorum. http://jsfiddle.net/uEpkE/

Güncelleme: Thomas'ın cevabından, hizmetin daha basit mantık ve fabrika için özel yöntemlerle daha karmaşık mantık için olduğunu ima ediyor gibi görünüyor, bu yüzden aşağıdaki keman kodunu güncelledim ve her ikisi de özel işlevleri destekleyebiliyor gibi görünüyor mu?

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

Tabii ki hizmet özel destekler ancak yazımı doğru okuduysanız bu tamamen kod stili: "özel" değişkenleri simüle etmek için yeni bir sözlük kapsamından da yararlanabiliriz. Bu "SİMÜLAT"
Thomas Pons

Bu tartışmayı çok faydalı buluyorum stackoverflow.com/questions/15666048/…
Anand Gupta

Yanıtlar:


280

açıklama

Burada farklı şeyler var:

İlk:

  • Bir hizmet kullanırsanız , bir işlev örneği alırsınız ("this " anahtar sözcüğü) .
  • Bir fabrika kullanırsanız , işlev başvurusunu (fabrikadaki return ifadesi) çağırarak döndürülen değeri alırsınız .

ref: açısal. servis vs açısal. fabrika

İkinci:

AngularJS'deki tüm değerlerin (değer, sabit, hizmetler, fabrikalar) tekil olduğunu unutmayın!

Üçüncü:

Bunlardan birini veya diğerini (servis veya fabrika) kullanmak kod stili ile ilgilidir. Ancak, AngularJS'nin ortak yolu fabrika kullanmaktır .

Neden ?

Çünkü "Fabrika yöntemi, AngularJS bağımlılık enjeksiyon sistemine nesne almanın en yaygın yoludur. Çok esnektir ve karmaşık yaratma mantığı içerebilir. Fabrikalar düzenli işlevler olduğundan, simüle etmek için yeni bir sözlüksel kapsamdan da yararlanabiliriz" özel "değişkenler. Bu, belirli bir hizmetin uygulama ayrıntılarını gizleyebileceğimiz için çok faydalıdır."

( ref : http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821 ).


kullanım

Hizmet:() Enjekte edilen işlev referansına ekleyerek çağırmak için yararlı olan yardımcı program işlevlerini paylaşmak için yararlı olabilir . Ayrıca injectedArg.call(this)veya benzeri ile çalıştırılabilir .

Fabrika: Daha sonra örnekler oluşturmak için yeni olabilecek bir 'sınıf' işlevini döndürmek için yararlı olabilir.

Bu nedenle, hizmetinizde karmaşık mantığınız olduğunda ve bu karmaşıklığı ortaya çıkarmak istemediğinizde bir fabrika kullanın .

Diğer durumlarda , hizmetin bir örneğini döndürmek istiyorsanız hizmeti kullanın .

Ama zamanla göreceksiniz, sanırım vakaların% 80'inde fabrikayı kullanacaksınız.

Daha fazla bilgi için: http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/


GÜNCELLEME :

Mükemmel yayın burada: http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html

"İşlevinizin normal bir işlev gibi çağrılmasını istiyorsanız, fabrika kullanın . İşlevinizin yeni operatörle başlatılmasını istiyorsanız hizmeti kullanın. Farkı bilmiyorsanız fabrika kullanın."


GÜNCELLEME :

AngularJS ekibi işini yapar ve bir açıklama yapar: http://docs.angularjs.org/guide/providers

Ve bu sayfadan:

"Fabrika ve Hizmet en sık kullanılan tariflerdir. Aralarındaki tek fark, Servis reçetesinin özel türdeki nesneler için daha iyi çalışması ve Fabrika'nın JavaScript ilkelleri ve işlevleri üretebilmesidir."


7
Re First: Bunu her yerde okudum ama bunun pratik sonuçlarını anlamıyorum. Sanırım cevabınızdan "çoğunlukla" pratik bir fark yoktur? Kitap ref için teşekkürler!
user1941747

Hizmetiniz gerçekten karmaşıksa ve özel yöntemlere ve nesnelere bir fabrika kullanmanız gerekiyorsa çok basit
Thomas Pons

1
"Bir hizmetin örneğini döndürmek istiyorsanız, sadece hizmeti kullanın" ifadesini eklediğinizi fark ettim. Takip eden sorum şu anda ne zaman bir hizmet örneği iade etmek isterdiniz? Burada özel bir kullanım durumu bulmaya çalışıyorum.
user1941747

12
"Fabrikalar düzenli işlevler olduğundan," özel "değişkenleri simüle etmek için yeni bir sözlüksel kapsamdan da yararlanabiliriz." - Bu fabrikalara özgü değil, aynı hizmetleri ile de yapabilirsiniz ..
pootzko

Google ekibinin fabrikada hizmeti tercih ettiği anlaşılıyor, bu da işleri daha da kafa karıştırıcı hale getiriyor! google-styleguide.googlecode.com/svn/trunk/...
xzhang

111

allernhwkim aslen bu soruya bloguna bağlantı veren bir cevap gönderdi , ancak bir moderatör bunu sildi. Sadece servis, sağlayıcı ve fabrika ile aynı şeyi nasıl yapacağınızı anlatmakla kalmayıp aynı zamanda bir fabrika ile yapamayacağınız bir sağlayıcıyla neler yapabileceğinizi ve bir servisle yapamayacağınız bir fabrika.

Doğrudan blogundan:

app.service('CarService', function() {
   this.dealer="Bad";
    this.numCylinder = 4;
});

app.factory('CarFactory', function() {
    return function(numCylinder) {
      this.dealer="Bad";
        this.numCylinder = numCylinder
    };
});

app.provider('CarProvider', function() {
    this.dealerName = 'Bad';
    this.$get = function() {
        return function(numCylinder) {
            this.numCylinder = numCylinder;
            this.dealer = this.dealerName;
        }
    };
    this.setDealerName = function(str) {
      this.dealerName = str;
    }      
});

Bu, CarService'in her zaman 4 silindirli bir araba nasıl üreteceğini gösterir, bireysel arabalar için değiştiremezsiniz. Oysa CarFactory new CarFactory, kontrolörünüzde o araca özgü birkaç silindiri geçirerek yapabilmeniz için bir işlev döndürür . Sen yapamaz new CarServiceCarService bir nesne değil, bir işlevdir çünkü.

Fabrikaların böyle çalışmamasının nedeni:

app.factory('CarFactory', function(numCylinder) {
      this.dealer="Bad";
      this.numCylinder = numCylinder
});

Ve otomatik olarak somutlaştırmak için bir işlev döndürün, çünkü bunu yapamazsınız (prototip / vb.

app.factory('CarFactory', function() {
    function Car(numCylinder) {
        this.dealer="Bad";
        this.numCylinder = numCylinder
    };
    Car.prototype.breakCylinder = function() {
        this.numCylinder -= 1;
    };
    return Car;
});

Tam anlamıyla araba üreten bir fabrika olduğunu görün.

Blogundan çıkan sonuç oldukça iyi:

Sonuç olarak,

---------------------------------------------------  
| Provider| Singleton| Instantiable | Configurable|
---------------------------------------------------  
| Factory | Yes      | Yes          | No          |
---------------------------------------------------  
| Service | Yes      | No           | No          |
---------------------------------------------------  
| Provider| Yes      | Yes          | Yes         |       
---------------------------------------------------  
  1. Hizmet'i yalnızca Hash gibi basit bir nesneye ihtiyacınız olduğunda kullanın, örneğin {foo; 1, bar: 2} Kodlamak kolaydır, ancak başlatamazsınız.

  2. Yeni Müşteri (), yeni Yorum () vb. Gibi bir nesneyi başlatmanız gerektiğinde Fabrika'yı kullanın.

  3. Yapılandırmanız gerektiğinde Sağlayıcı'yı kullanın. yani test url'si, KG url'si, üretim url'si.

Bir nesneyi fabrikada iade ettiğinizi fark ederseniz, muhtemelen hizmeti kullanmalısınız.

Bunu yapma:

app.factory('CarFactory', function() {
    return {
        numCylinder: 4
    };
});

Bunun yerine hizmeti kullanın:

app.service('CarService', function() {
    this.numCylinder = 4;
});

11
Benim için bu çok yararlı. Karşılaştırma tablosu için +1
Vu Anh

5
hizmet işlevini bir parametre numCylinder ile tanımlarsanız, fabrika yöntemiyle aynı esnekliğe sahip olacaktır
Ovi

gidip yazı blogunu okuyun ve açısal anlamaya çalışırken zamanınızı boşa harcamayın, eğer bu yazıyı okuduktan sonra javascript biliyorsanız bu arasındaki farkı tamamen anlayacaksınız.
ncubica

4
Çok şaşkın ! Burada bir blog atıfta bulunuyorsunuz ve her ikisi de tam tersi bir şey söylüyor. Diyorsun: Factory - Instantiable - Evet Blog diyor ki: Factory - Instantiable - Hayır
Devesh M

1
@Devesh ile aynı fikirdeyim. Bence örneklerin karıştığını görüyorsun. Blog gönderisinden: "Sadece fabrika ile, bunu başaramazsınız çünkü fabrika somutlaştırılamaz".
Matt

20

Tüm bu sağlayıcılar için konsept, başlangıçta göründüğünden çok daha basittir. Bir sağlayıcıyı incelerseniz ve farklı parçaları çıkarırsanız çok netleşir.

Basitçe bu sağlayıcıların her biri bu sırada diğer bir uzman versiyonudur koymak için: provider> factory> value/ constant/service .

Ne kadar uzun zaman sağlayıcı daha az kod yazarak sonuçlanacak zinciri daha aşağı sağlayıcı kullanabilirsiniz. İstediğinizi başaramazsa, zinciri yukarı çıkarabilirsiniz ve sadece daha fazla kod yazmanız gerekir.

Bu görüntü ne demek istediğimi gösterir, bu görüntüde bir sağlayıcının kodunu göreceksiniz, bölümler vurgulanmışsa bunun yerine sağlayıcının hangi kısımlarının fabrika, değer vb. Oluşturmak için kullanılabileceğini gösterir.

AngularJS sağlayıcıları, fabrikaları, hizmetleri vb. Aynı şeydir
(kaynak: simplygoodcode.com )

Resmi aldığım blog gönderisinden daha fazla ayrıntı ve örnekler için şu adrese gidin: http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/


8

Hem fabrika hem de hizmet, sağlayıcılar tarafından yapılandırılabilen ve denetleyicilere ve çalışma bloklarına enjekte edilebilen tekli nesnelerle sonuçlanır. Enjektör açısından, nesnenin bir fabrikadan mı yoksa bir hizmetten mi geldiği konusunda kesinlikle hiçbir fark yoktur.

Peki, ne zaman fabrika kullanılır ve ne zaman servis kullanılır? Kodlama tercihinize bağlıdır ve başka bir şey değildir. Modüler JS modelini beğendiyseniz fabrikaya gidin. Yapıcı işlevi ("sınıf") stilini beğenirseniz, hizmete gidin. Her iki stilin de özel üyeleri desteklediğini unutmayın.

Hizmetin avantajı, OOP bakış açısından daha sezgisel olması olabilir: bir "sınıf" oluşturun ve bir sağlayıcıyla birlikte aynı kodu modüller arasında yeniden kullanın ve örneklenen nesnelerin davranışını basitçe sağlayarak değiştirin Yapılandırma bloğundaki kurucuya farklı parametreler.


Bir yapılandırma bloğundaki kurucuya farklı parametreler sağlayarak ne demek istediğinize bir örnek verebilir misiniz? Sadece bir hizmet veya fabrika ise parametreleri nasıl sağlarsınız? "Bir sağlayıcıyla birlikte" ile ne demek istiyorsun? Yapılandırabilmem, nesnelerimin çoğunun fabrikalara veya hizmetlere karşı bir sağlayıcı olması gerektiğini düşündürüyor.
timbrown

2

Bir Fabrikanın bir Hizmete kıyasla yapamayacağı veya daha iyisini yapamayacağı hiçbir şey yoktur. Ve ayet. Fabrika daha popüler görünüyor. Bunun nedeni, özel / kamu üyelerini ele alma kolaylığıdır. Hizmet bu konuda daha beceriksiz olurdu. Bir Hizmeti kodlarken, nesne üyelerinizi “bu” anahtar kelimeyle herkese açık hale getirme eğilimindesiniz ve birdenbire bu genel üyelerin özel yöntemlere (örn. İç işlevler) görünmediğini öğrenebilirsiniz.

var Service = function(){

  //public
  this.age = 13;

  //private
  function getAge(){

    return this.age; //private does not see public

  }

  console.log("age: " + getAge());

};

var s = new Service(); //prints 'age: undefined'

Açısal, sizin için bir hizmet oluşturmak üzere “yeni” anahtar sözcüğünü kullanır, bu nedenle Açısal denetleyiciye geçiş örneği aynı dezavantaja sahip olur. Tabii ki şu / bunu kullanarak sorunun üstesinden gelebilirsiniz:

var Service = function(){

  var that = this;

  //public
  this.age = 13;

  //private
  function getAge(){

    return that.age;

  }

  console.log("age: " + getAge());

};

var s = new Service();// prints 'age: 13'  

Ancak büyük bir Hizmet sabiti ile bu kod kötü okunabilir hale gelir. Ayrıca, Hizmet prototipleri özel üyeleri görmeyecek - yalnızca herkese açık olacak:

var Service = function(){

  var name = "George";

};

Service.prototype.getName = function(){

  return this.name; //will not see a private member

};

var s = new Service();
console.log("name: " + s.getName());//prints 'name: undefined'

Özetle, Fabrika'yı kullanmak daha uygundur. Fabrika bu dezavantajlara sahip olmadığından. Varsayılan olarak kullanmanızı tavsiye ederim.


Bu cevabın birkaç problemi var. İlk olarak, bu yazı Javascript'in AngularJS hizmetlerinin çalışma biçiminden ziyade sözcüksel kapsam belirleme kavramını göstermektedir. İkincisi, arama bağlamı myapp.service(...)tamamen eksik. Nereden new Service()çağrılması gerektiği, servis fonksiyonunda veya Servisin enjekte edildiği yerde. Üçüncü liste, bağlamında mümkün değildir myapp.service ('Service', function() {...}).
lanoxx

2

Tüm hizmetlerin ve fabrikaların tekil olduğunu söyleseler bile, yüzde 100 katılmıyorum. Fabrikaların singleton olmadığını söyleyebilirim ve cevabım bu. Gerçekten her bileşeni (Hizmet / Fabrika) tanımlayan adı düşünürdüm, yani:

Bir fabrika bir tekton olmadığı için, enjekte ettiğinizde istediğiniz kadar oluşturabilirsiniz, bu yüzden bir nesne fabrikası gibi çalışır. Alan adınızdaki bir varlığın fabrikasını oluşturabilir ve modelinizin bir nesnesi gibi olabilecek bu nesnelerle daha rahat çalışabilirsiniz. Birkaç nesneyi aldığınızda bunları bu nesnelerde eşleştirebilir ve DDBB ile AngularJs modeli arasında bir çeşit katman oluşturabilir.

Bu arada bir hizmet tekil, bu yüzden sadece bir tür yaratabiliriz, belki yaratamazız, ancak bir denetleyiciye enjekte ettiğimizde sadece 1 örneğimiz vardır, bu nedenle bir hizmet daha çok ortak bir hizmet (dinlenme çağrıları, işlevsellik gibi) sağlar. denetleyicilere.

Kavramsal olarak, hizmetlerin bir hizmet sağladığı gibi düşünebilirsiniz, fabrikalar bir sınıfın birden çok örneğini (nesnesini) oluşturabilir


0

Hizmetler

Sözdizimi : module.service ('serviceName', işlev); Sonuç : serviceName öğesini enjekte edilebilir bir argüman olarak bildirirken, module.service öğesine iletilen gerçek işlev başvurusu size sağlanacaktır.

Kullanım : Enjekte edilen işlev referansına () eklenerek çağırılması yararlı olan yardımcı program işlevlerini paylaşmak için yararlı olabilir. Ayrıca injectedArg.call (bu) veya benzeri ile de çalıştırılabilir.

Fabrikalar

Sözdizimi : module.factory ('fabrikaAdı', işlev);

Sonuç : factoryName öğesini enjekte edilebilir bir argüman olarak bildirirken, module.factory öğesine iletilen işlev başvurusunu çağırarak size döndürülen değer sağlanacaktır.

Kullanım : Örnek oluşturmak için yeni olabilecek bir 'sınıf' işlevini döndürmek için yararlı olabilir.

Sağlayıcıları

Sözdizimi : module.provider ('sağlayıcıAdı', işlev);

Sonuç : vendorName öğesini enjekte edilebilir bir argüman olarak bildirirken, module.provider öğesine iletilen işlev başvurusunun $ get yönteminin çağrılmasıyla döndürülen değer size sağlanacaktır.

Kullanım : Örnek oluşturmak için daha sonra yeni olabilecek ancak enjekte edilmeden önce bir tür yapılandırma gerektiren bir 'sınıf' işlevini döndürmek için yararlı olabilir. Belki projeler arasında yeniden kullanılabilir sınıflar için yararlı? Bu konuda hala biraz puslu.


0

Her ikisini de istediğiniz şekilde kullanabilir : nesne oluştur veya her ikisinden işlevlere erişmek için


Hizmetten yeni nesne oluşturabilirsiniz

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();
})

Not :

  • hizmet varsayılan olarak yapıcı işlevini değil nesneyi döndürür.
  • Bu yüzden yapıcı işlevi this.model özelliğine ayarlanır.
  • Bu hizmet nedeniyle nesne döndürülür, ancak bu nesnenin içinde yeni nesne oluşturmak için kullanılacak yapıcı işlevi olacaktır;

Fabrikadan yeni nesne oluşturabilirsiniz

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();
})

Not :

  • fabrika varsayılan olarak nesne değil yapıcı işlevini döndürür.
  • Bu yüzden yapıcı işleviyle yeni nesne oluşturulabilir.

Yalnızca basit işlevlere erişmek için hizmet oluşturun

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

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

Sadece basit işlevlere erişmek için fabrika oluşturun

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()
})

Sonuç:

  • yeni nesne oluşturmak veya sadece basit işlevlere erişmek için istediğiniz şekilde kullanabilirsiniz
  • Birini diğerinin üzerinde kullanarak herhangi bir performans isabeti olmayacak
  • Her ikisi de tekil nesnelerdir ve uygulama başına yalnızca bir örnek oluşturulur.
  • Referanslarının geçildiği her yerde sadece bir örnek olmak.
  • Açısal dokümantasyonda fabrikaya servis, servis de hizmet olarak adlandırılır .

0

Fabrika ve Hizmet en sık kullanılan yöntemdir. Aralarındaki tek fark, Servis yönteminin kalıtım hiyerarşisine ihtiyaç duyan nesneler için daha iyi çalışması, Fabrika ise JavaScript ilkelerini ve işlevlerini üretebilmesidir.

Sağlayıcı işlevi temel yöntemdir ve diğerlerinin tümü sadece sözdizimsel şekerlerdir. Yalnızca genel yapılandırmaya ihtiyaç duyan yeniden kullanılabilir bir kod parçası oluşturuyorsanız buna ihtiyacınız olur.

Hizmet oluşturmanın beş yöntemi vardır: Değer, Fabrika, Hizmet, Sağlayıcı ve Sabit. Burada bu açısal hizmet hakkında daha fazla bilgi edinebilirsiniz , bu makale tüm bu yöntemleri pratik demo örnekleri ile açıklamaktadır.

.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.