AngularJS : 공장 대신 서비스를 사용하는 경우


296

여기 나와 함께 해주세요. AngularJS : 서비스 대 공급자 대 공장 과 같은 다른 답변이 있다는 것을 알고 있습니다 .

그러나 공장을 통해 서비스를 사용할 때 여전히 파악할 수 없습니다.

내가 공장에서 말할 수있는 것은 일반적으로 여러 컨트롤러가 호출 할 수있는 "공통"기능을 만드는 데 사용됩니다. 공통 컨트롤러 기능 만들기

Angular 문서는 공장보다 서비스를 선호하는 것 같습니다. 그들은 심지어 더 혼란스러운 공장을 사용할 때 "서비스"를 참조하기도합니다! http://docs.angularjs.org/guide/dev_guide.services.creating_services

그러면 언제 서비스를 이용할까요?

서비스를 통해서만 가능하거나 훨씬 쉬운 일이 있습니까?

무대 뒤에서 다른 일이 있습니까? 성능 / 메모리 차이?

다음은 예입니다. 선언 방법 외에는 동일하게 보이며 왜 내가 한 대 다른 대를하는지 알 수 없습니다. http://jsfiddle.net/uEpkE/

업데이트 : Thomas의 답변에서 서비스는 개인 메소드를 사용하여보다 복잡한 논리를위한 간단한 논리 및 팩토리 용임을 암시하는 것처럼 보이므로 아래의 바이올린 코드를 업데이트했는데 둘 다 개인 함수를 지원할 수 있습니까?

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

물론 서비스는 개인을 지원하지만 내 게시물을 올바르게 읽으면 순전히 코드 스타일입니다. 우리는 "개인"변수를 시뮬레이션하기 위해 새로운 어휘 범위를 활용할 수도 있습니다. "SIMULATE"
토마스 폰

이 토론이 매우 유용하다는 것을 알았습니다 stackoverflow.com/questions/15666048/…
Anand Gupta

답변:


280

설명

여기에 다른 것들이 있습니다.

먼저:

  • 서비스를 사용하면 함수의 인스턴스 ( " this"키워드)를 얻게됩니다 .
  • 팩토리를 사용하는 경우 함수 참조 (팩토리의 return 문)를 호출하여 리턴되는 값을 얻을 수 있습니다.

심판 : 앵귤러 서비스 vs 앵귤러 팩토리

둘째:

AngularJS의 모든 공급자 (가치, 상수, 서비스, 공장)는 싱글 톤입니다!

제삼:

하나 또는 다른 것을 사용하는 것 (서비스 또는 공장)은 코드 스타일에 관한 것입니다. 그러나 AngularJS 의 일반적인 방법factory 를 사용하는 것 입니다.

왜 ?

때문에 개인 "공장 일반 기능이기 때문에, 우리는 또한 새로운 어휘 범위를 활용할 수있는 팩토리 메소드는 AngularJS와 의존성 주입 시스템에 개체를 얻을 수있는 가장 일반적인 방법입니다. 그것은 매우 유연하고 정교한 생성 로직을 포함 할 수 있습니다. 시뮬레이션" "변수. 이는 특정 서비스의 구현 세부 사항을 숨길 수 있으므로 매우 유용합니다."

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


용법

서비스 :() 주입 된 함수 참조 에 간단히 추가 하여 호출하는 데 유용한 유틸리티 함수를 공유하는 데 유용 할 수 있습니다 . 함께 injectedArg.call(this)또는 유사 하게 실행할 수 있습니다 .

Factory : 인스턴스를 생성하기 위해 새로 만들 수있는 '클래스'기능을 반환하는 데 유용 할 수 있습니다.

따라서 서비스에 복잡한 논리있고이 복잡성을 노출시키지 않으려면 팩토리를 사용 하십시오 .

다른 경우 에는 서비스 인스턴스를 반환하려면 service를 사용하십시오 .

그러나 시간이 지남에 따라 80 %의 공장에서 공장을 사용할 것이라고 생각합니다.

자세한 내용은 http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/


업데이트 :

여기에 훌륭한 게시물 : http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html

"함수 를 일반 함수처럼 호출 하려면 factory를 사용하십시오 . 새 연산자로 함수를 인스턴스화하려면 서비스를 사용하십시오. 차이점을 모르면 factory를 사용하십시오."


업데이트 :

AngularJS 팀은 그의 작업을 수행하고 설명을 제공합니다 : http://docs.angularjs.org/guide/providers

그리고이 페이지에서 :

"공장과 서비스는 가장 일반적으로 사용되는 레시피입니다. 이들 간의 유일한 차이점은 서비스 레시피는 사용자 정의 유형의 객체에 더 효과적이며 공장은 JavaScript 프리미티브와 함수를 생성 할 수 있다는 것입니다."


7
우선 : 나는 그것을 모든 곳에서 읽었지만 그 실제적인 의미를 이해하지 못합니다. 나는 당신의 대답에서 "대부분"에 실질적인 차이가 없다고 생각합니까? 책 참고 감사합니다!
user1941747

서비스가 실제로 복잡하고 개인용 메소드와 객체가 팩토리를 사용해야하는 경우 간단합니다.
Thomas Pons

1
"서비스 인스턴스를 반환하려면 서비스 만 사용하십시오"를 추가 한 것으로 나타났습니다. 내 후속 질문은 언제 서비스 인스턴스를 반환하고 싶습니까? 특정 사용 사례를 찾으려고합니다.
user1941747

12
"공장은 정규 기능이므로"사설 "변수를 시뮬레이션하기 위해 새로운 어휘 범위를 활용할 수도 있습니다." -이것은 공장에만 국한된 것이 아니며, 서비스를 통해 동일한 작업을 수행 할 수 있습니다.
pootzko

Google 팀이 공장보다 서비스를 선호하는 것 같습니다. google-styleguide.googlecode.com/svn/trunk/…
xzhang

111

allernhwkim은 원래 자신의 블로그에 연결된이 질문 에 대한 답변 을 게시 했지만 중재자가 삭제했습니다. 내가 찾은 유일한 게시물은 서비스, 공급자 및 공장에서 동일한 작업을 수행하는 방법뿐만 아니라 공장으로는 할 수없는 공급자와 함께 할 수있는 일을 알려줍니다. 서비스를 할 수없는 공장.

그의 블로그에서 직접 :

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

이것은 CarService가 항상 4 개의 실린더가있는 자동차를 생산하는 방법을 보여줍니다. 개별 자동차를 위해 변경할 수는 없습니다. 반면 CarFactory는 new CarFactory컨트롤러에서 수행 할 수있는 함수를 반환 하여 해당 자동차에 특정한 여러 실린더를 전달합니다. new CarServiceCarService는 함수가 아닌 객체이므로 수행 할 수 없습니다 .

공장이 다음과 같이 작동하지 않는 이유 :

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

그리고 인스턴스화 할 수있는 함수를 자동으로 반환합니다. 왜냐하면 그렇게 할 수 없기 때문입니다 (시제품 등을 추가하십시오).

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

그것이 문자 그대로 자동차를 생산하는 공장인지 확인하십시오.

그의 블로그의 결론은 꽤 좋습니다.

결론적으로,

---------------------------------------------------  
| Provider| Singleton| Instantiable | Configurable|
---------------------------------------------------  
| Factory | Yes      | Yes          | No          |
---------------------------------------------------  
| Service | Yes      | No           | No          |
---------------------------------------------------  
| Provider| Yes      | Yes          | Yes         |       
---------------------------------------------------  
  1. 해시와 같은 간단한 객체가 필요할 때 서비스를 사용하십시오 (예 : {foo; 1, bar : 2}) 코딩하기 쉽지만 인스턴스화 할 수는 없습니다.

  2. 객체를 인스턴스화해야하는 경우 (예 : new Customer (), new Comment () 등) Factory를 사용하십시오.

  3. 구성해야 할 때 공급자를 사용하십시오. 즉, 테스트 URL, 품질 관리 URL, 생산 URL입니다.

공장에서 객체를 반품하는 경우 서비스를 사용해야합니다.

이 작업을 수행하지 마십시오 :

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

대신 서비스를 사용하십시오.

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

11
그것은 나에게 매우 도움이됩니다. 비교 테이블에 대 한 +1
Vu Anh

5
하나의 매개 변수 numCylinder를 사용하여 서비스 기능을 정의하면 팩토리 방법과 동일한 유연성을 갖습니다.
Ovi

가서 게시물 블로그를 읽고 각도를 알아 내려고 노력하는 데 시간을 낭비하십시오.이 게시물을 읽은 후 자바 스크립트를 알고 있다면 이것의 차이점을 완전히 이해할 것입니다.
ncubica

4
매우 놀랐습니다! 당신은 여기서 블로그를 언급하고 있으며 둘 다 완전히 반대되는 것을 말합니다. 당신은 말합니다 : 공장-Instantiable-예 블로그 말 : 공장
-Instantiable-

1
@Devesh에 동의합니다. 나는 당신이 인스턴스가 섞여 있다고 생각합니다. 블로그 게시물에서 : "팩토리를 인스턴스화 할 수 없기 때문에 팩토리 만 사용할 수 없습니다."
Matt

20

이러한 모든 제공 업체에 대한 개념은 처음 나타난 것보다 훨씬 간단합니다. 공급자를 해부하고 다른 부분을 꺼내면 매우 명확 해집니다.

단순히 이러한 공급자의 각 하나를 넣어하는 것은 순서로, 다른 전문 버전 : provider> factory> value/ constant/ service.

너무 오래 공급자가 당신이 할 수있는 일을 수행하면 더 적은 코드를 작성할 수있는 체인 아래로 공급자를 사용할 수 있습니다. 원하는 것을 달성하지 못하면 체인을 올라갈 수 있으며 더 많은 코드를 작성해야합니다.

이 이미지는 내가 의미하는 바를 보여줍니다.이 이미지에는 제공자의 코드가 표시되며, 일부는 강조 표시되어 제공자의 어느 부분이 팩토리, 값 등을 만드는 데 사용될 수 있는지 보여줍니다.

AngularJS 제공자, 공장, 서비스 등은 모두 동일합니다.
(출처 : simplygoodcode.com )

이미지를 가져온 블로그 게시물의 자세한 내용과 예는 다음 웹 사이트를 참조하십시오.


8

팩토리와 서비스는 프로 바이더가 구성하고 컨트롤러 및 런 블록에 주입 할 수있는 싱글 톤 객체를 생성합니다. 인젝터의 관점에서 볼 때, 물체가 공장에서 생산 된 것인지 서비스에서 나온 것인지는 전혀 차이가 없습니다.

그렇다면 언제 공장을 사용하고 언제 서비스를 사용합니까? 코딩 선호도에 따라 달라집니다. 모듈 식 JS 패턴이 마음에 들면 공장으로 이동하십시오. 생성자 함수 ( "class") 스타일이 마음에 들면 서비스를 찾으십시오. 두 스타일 모두 개인 멤버를 지원합니다.

서비스의 이점은 OOP 관점에서보다 직관적이라는 것입니다. "클래스"를 작성하고 제공자와 함께 모듈에서 동일한 코드를 재사용하고 간단히 제공하여 인스턴스화 된 오브젝트의 동작을 변경하십시오. 구성 블록의 생성자에 다른 매개 변수.


구성 블록에서 생성자에 다른 매개 변수를 제공하여 의미의 예를 제공 할 수 있습니까? 서비스 또는 팩토리 일 경우 어떻게 매개 변수를 제공합니까? "제공자와 함께"는 무슨 뜻입니까? 이를 구성 할 수 있으면 많은 객체가 공급자 또는 팩토리 또는 서비스라고 생각합니다.
timbrown

2

팩토리가 서비스와 비교할 수 없거나 더 나은 것은 없습니다. 그리고 그 구절. 공장은 더 인기가있는 것 같습니다. 그 이유는 개인 / 공공 회원을 처리하는 것이 편리하기 때문입니다. 이와 관련하여 서비스가 더 서투른 것입니다. 서비스를 코딩 할 때“this”키워드를 통해 객체 멤버를 공개하는 경향이 있으며 이러한 공개 멤버가 개인 메소드 (예 : 내부 함수)에 보이지 않는 것을 갑자기 알 수 있습니다.

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'

Angular는“new”키워드를 사용하여 서비스를 생성하므로 컨트롤러에 대한 Angular 패스 인스턴스는 동일한 단점을 갖습니다. 물론 당신은 이것을 사용하여 문제를 극복 할 수 있습니다 :

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'  

그러나 서비스 상수가 크면이 코드를 읽을 수 없게됩니다. 또한 서비스 프로토 타입에는 비공개 멤버가 표시되지 않으며 공개 멤버 만 사용할 수 있습니다.

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'

요약하면 Factory를 사용하는 것이 더 편리합니다. Factory에는 이러한 단점이 없습니다. 기본적으로 사용하는 것이 좋습니다.


이 답변에는 몇 가지 문제가 있습니다. 먼저,이 글에서는 AngularJS 서비스의 작동 방식보다는 자바 스크립트의 어휘 범위 지정 개념을 보여줍니다. 둘째, 부름의 맥락이 myapp.service(...)완전히 사라졌습니다. 어디이되는 new Service()서비스 기능이나 서비스를 주입 곳에서 호출 될 예정. 세 번째 목록은 단순히 문맥 상으로는 불가능합니다 myapp.service ('Service', function() {...}).
lanoxx

2

모든 서비스와 공장이 싱글 톤이라고 말하더라도 100 % 동의하지 않습니다. 나는 공장이 싱글 톤이 아니며 이것이 내 대답의 요점이라고 말합니다. 모든 구성 요소 (서비스 / 공장)를 정의하는 이름에 대해 정말로 생각할 것입니다.

공장은 싱글이 없기 때문에 당신이 주입 할 때 원하는대로 객체의 공장처럼 작동하므로, 당신은 많은으로 만들 수 있습니다. 도메인 엔티티의 팩토리를 작성하고 모델의 오브젝트와 같은이 오브젝트로보다 편안하게 작업 할 수 있습니다. 여러 객체를 검색 할 때이 객체에 객체를 매핑 할 수 있으며 DDBB와 AngularJs 모델간에 다른 레이어와 같은 역할을 수행 할 수 있습니다.

한편 서비스 는 싱글 톤이므로, 하나만 만들 수는 있지만 어쩌면 만들 수는 없지만 컨트롤러에 주입 할 때 인스턴스가 하나뿐이므로 서비스는 일반적인 서비스와 같은 서비스를 제공합니다 (휴식 전화, ​​기능 ..) 컨트롤러에.

개념적으로 서비스가 서비스를 제공하는 것처럼 생각할 수 있으며 팩토리는 클래스의 여러 인스턴스 (객체)를 생성 할 수 있습니다


0

서비스

구문 : module.service ( 'serviceName', function); 결과 : serviceName을 주입 가능한 인수로 선언하면 module.service에 전달 된 실제 함수 참조가 제공됩니다.

사용법 : 주입 된 함수 참조에 단순히 ()를 추가하여 호출하는 데 유용한 유틸리티 함수를 공유하는 데 유용 할 수 있습니다. injectionArg.call (this) 또는 이와 유사한 방식으로 실행할 수도 있습니다.

공장

구문 : module.factory ( 'factoryName', function);

결과 : factoryName을 삽입 가능한 인수로 선언하면 module.factory에 전달 된 함수 참조를 호출하여 리턴되는 값이 제공됩니다.

사용법 : 인스턴스를 만들기 위해 새로 만들 수있는 '클래스'함수를 반환하는 데 유용 할 수 있습니다.

공급자

구문 : module.provider ( 'providerName', function);

결과 : providerName을 삽입 가능한 인수로 선언하면 module.provider에 전달 된 함수 참조의 $ get 메소드를 호출하여 리턴되는 값이 제공됩니다.

사용법 : 인스턴스를 만들기 위해 새로 만들 수 있지만 주입되기 전에 일종의 구성이 필요한 '클래스'함수를 반환하는 데 유용 할 수 있습니다. 프로젝트 전체에서 재사용 가능한 클래스에 유용할까요? 이건 여전히 흐릿합니다.


0

객체를 생성 하든 j를 사용 하든 원하는 방식으로 모두 사용할 수 있습니다 . 액세스 기능에 넣으면를 모두에서


서비스에서 새 개체를 만들 수 있습니다

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

노트 :

  • 기본적으로 service는 생성자 함수가 아닌 객체를 반환합니다.
  • 그래서 생성자 함수는 this.model 속성으로 설정됩니다.
  • 이 서비스로 인해 객체가 반환되지만 해당 객체 안에는 새 객체를 만드는 데 사용할 생성자 함수가 있습니다.

공장에서 새 객체를 만들 수 있습니다

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

노트 :

  • factory는 기본적으로 object가 아닌 생성자 함수를 반환합니다.
  • 따라서 생성자 함수를 사용하여 새 객체를 만들 수 있습니다.

간단한 기능에 액세스하기위한 서비스 작성

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

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

간단한 기능에 액세스하기위한 팩토리 생성

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

결론 :

  • 새 객체를 만들거나 간단한 기능에 액세스하기 를 원하는 방식으로 모두 사용할 수 있습니다.
  • 하나 이상을 사용하여 성능 저하가 발생하지 않습니다.
  • 둘 다 싱글 톤 객체이며 앱당 하나의 인스턴스 만 생성됩니다.
  • 참조가 전달 될 때마다 하나의 인스턴스가됩니다.
  • 앵귤러 문서 팩토리에서 service는 service라고하며 serviceservice라고합니다 .

0

공장 및 서비스가 가장 일반적으로 사용되는 방법입니다. 그들 사이의 유일한 차이점은 Service 메소드는 상속 계층이 필요한 객체에 더 효과적이며 Factory는 JavaScript 프리미티브와 함수를 생성 할 수 있다는 것입니다.

공급자 기능은 핵심 방법이며 다른 모든 방법은 구문 설탕입니다. 전역 구성이 필요한 재사용 가능한 코드를 작성하는 경우에만 필요합니다.

서비스를 생성하는 5 가지 방법은 Value, Factory, Service, Provider 및 Constant입니다. 여기서 각도 서비스 에 대해 더 자세히 배울 수 있습니다. .이 기사에서는이 모든 방법을 실제 데모 예제와 함께 설명합니다.

.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.