Program Tip

서비스 대 공장에 대해 혼동

programtip 2020. 10. 2. 23:06
반응형

서비스 대 공장에 대해 혼동


내가 알기로 공장 내부에서 컨트롤러에 주입되는 객체를 반환합니다. 서비스 내부에서 나는 객체를 사용 this하고 아무것도 반환하지 않습니다.

나는 서비스가 항상 싱글 톤 이고 새로운 팩토리 객체 가 모든 컨트롤러에 주입 된다는 가정하에있었습니다 . 그러나 밝혀진대로 팩토리 객체도 싱글 톤입니까?

시연 할 예제 코드 :

var factories = angular.module('app.factories', []);
var app = angular.module('app',  ['ngResource', 'app.factories']);

factories.factory('User', function () {
  return {
    first: 'John',
    last: 'Doe'
  };
});

app.controller('ACtrl', function($scope, User) {
  $scope.user = User;
});

app.controller('BCtrl', function($scope, User) {
  $scope.user = User;
});

변경하는 경우 user.firstACtrl그것을 밝혀 user.first에서이 BCtrl예는,도 변경됩니다 User싱글인가?

내 가정은 공장이있는 컨트롤러에 새 인스턴스가 주입 된 것입니까?


모든 각도 서비스는 싱글 톤입니다 .

문서 ( 서비스를 싱글 톤으로 참조 ) : https://docs.angularjs.org/guide/services

마지막으로 모든 Angular 서비스가 애플리케이션 싱글 톤이라는 사실을 인식하는 것이 중요합니다. 이는 인젝터 당 주어진 서비스의 인스턴스가 하나만 있음을 의미합니다.

기본적으로 서비스와 공장의 차이점은 다음과 같습니다.

app.service('myService', function() {

  // service is just a constructor function
  // that will be called with 'new'

  this.sayHello = function(name) {
     return "Hi " + name + "!";
  };
});

app.factory('myFactory', function() {

  // factory returns an object
  // you can run some code before

  return {
    sayHello : function(name) {
      return "Hi " + name + "!";
    }
  }
});

$ provide에 대한이 프레젠테이션을 확인하십시오. http://slides.wesalvaro.com/20121113/#/

이 슬라이드는 AngularJs 모임 중 하나에서 사용되었습니다 : http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html


저에게 계시는 그들이 모두 똑같은 방식으로 작동한다는 것을 깨달았을 때 왔습니다 : 무언가를 한 번 실행하고 , 그들이 얻은 값을 저장하고, 의존성 주입을 통해 참조 될 때 동일한 저장된 값 을 기침함으로써 .

우리가 가지고 있다고 :

app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);

세 가지의 차이점은 다음과 같습니다.

  1. a의 저장된 값은 running fn에서 비롯됩니다 .fn()
  2. b의 저장된 값은 newing fn에서 나옵니다 .new fn()
  3. c의 저장된 값은 먼저 newing 을 사용하여 인스턴스를 fn가져온 다음 $get인스턴스 메서드 를 실행하여 가져옵니다.

즉, angular 내부에 캐시 객체와 같은 것이 있는데, 각 주입의 값은 처음 주입되었을 때 한 번만 할당됩니다.

cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()

이것이 우리 this가 서비스에서 사용 this.$get하고 공급자를 정의하는 이유 입니다.

도움이 되었기를 바랍니다.


라이브 예

"hello world"예

factory/ service/ provider:

var myApp = angular.module('myApp', []);

//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});

//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!"
        }
    };
});

//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {
    // In the provider function, you cannot inject any
    // service or factory. This can only be done at the
    // "$get" method.

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});


function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {

    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}​

당신이 돌아갈 수 있도록 생성자 함수를 반환하는 방법도있다 newable 과 같이 공장에서 클래스 :

function MyObjectWithParam($rootScope, name) {
  this.$rootScope = $rootScope;
  this.name = name;
}
MyObjectWithParam.prototype.getText = function () {
  return this.name;
};

App.factory('MyObjectWithParam', function ($injector) {
  return function(name) { 
    return $injector.instantiate(MyObjectWithParam,{ name: name });
  };
}); 

따라서 MyObjectWithParam을 사용하는 컨트롤러에서이를 수행 할 수 있습니다.

var obj = new MyObjectWithParam("hello"),

전체 예는 여기를 참조하십시오 :
http://plnkr.co/edit/GKnhIN?p=preview

여기에 논의 된 Google 그룹 페이지가 있습니다.
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ


주요 차이점은 다음과 같습니다.

서비스

통사론: module.service( 'serviceName', function );

결과 : 주입 가능한 인수로 serviceName을 선언하면에 전달 된 함수인스턴스 가 제공 됩니다 module.service.

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

공장

통사론: module.factory( 'factoryName', function );

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

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

또한 AngularJS 문서서비스 대 공장에 대해 혼란스러운 stackoverflow 에 대한 유사한 질문을 확인하십시오 .

다음은 서비스 및 공장을 사용하는 예 입니다. AngularJS 서비스 대 공장 에 대해 자세히 알아보십시오 .


첫 번째 답변에 추가하면 .service ()는 더 많은 객체 지향 스타일 (C # / Java)로 코드를 작성한 사람들을위한 것입니다 (이 키워드를 사용하고 프로토 타입 / 생성자 함수를 통해 객체를 인스턴스화).

Factory는 자바 스크립트 / 기능적 코딩 스타일에 더 자연스러운 코드를 작성하는 개발자를위한 것입니다.

angular.js 내부의 .service 및 .factory 메소드의 소스 코드를 살펴보십시오. 내부적으로는 모두 provider 메소드를 호출합니다.

  function provider(name, provider_) {
    if (isFunction(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw Error('Provider ' + name + ' must define $get factory method.');
    }
    return providerCache[name + providerSuffix] = provider_;
  }

  function factory(name, factoryFn) { \
    return provider(name, { $get: factoryFn }); 
  }

  function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }

아주 간단하게 :

.service에 등록 된 함수는 생성자로 호출됩니다 ( 'newed'라고도 함).

.factory 등록 된 함수는 간단한 함수로 호출됩니다.

둘 다 한 번 호출되어 앱의 다른 구성 요소에 삽입되는 단일 개체가 생성됩니다.


모든 공급자는 동일한 방식으로 작동합니다. 서로 다른 방법은 service, factory, provider당신이 더 적은 코드에서 같은 일을 수행 할 수 있습니다.

PS valueconstant.

로 시작 provider하고로 끝나는 체인 아래의 각 특수 사례 value에는 추가 제한이 있습니다. 따라서 둘 중 하나를 결정하려면 적은 코드로 원하는 것을 달성 할 수있는 방법을 자문해야합니다.

다음은 내가 의미하는 바를 보여주는 사진입니다.

여기에 이미지 설명 입력

이 이미지를 얻은 블로그 게시물에서 분석 및 참조 가이드를 얻을 수 있습니다.

http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/


다음은 서비스와 공장 간의 차이점을 확인하는 데 유용 할 수있는 몇 가지 추가 예입니다. 기본적으로 서비스에는 "new ..."가 호출되어 이미 인스턴스화되어 있습니다. 팩토리는 자동으로 인스턴스화되지 않습니다.

기본 예

단일 메소드가있는 클래스 객체를 반환합니다.

다음은 단일 메서드가있는 서비스입니다.

angular.service('Hello', function () {
  this.sayHello = function () { /* ... */ };
});

다음은 메서드로 객체를 반환하는 팩토리입니다.

angular.factory('ClassFactory', function () {
  return {
    sayHello: function () { /* ... */ }
  };
});

값 반환

숫자 목록을 반환하는 공장 :

angular.factory('NumberListFactory', function () {
  return [1, 2, 3, 4, 5];
});

console.log(NumberListFactory);

숫자 목록을 반환하는 서비스 :

angular.service('NumberLister', function () {
  this.numbers = [1, 2, 3, 4, 5];
});

console.log(NumberLister.numbers);

두 경우의 출력은 숫자 목록과 동일합니다.

고급 예

팩토리를 사용하는 "클래스"변수

이 예제에서 우리는 CounterFactory를 정의하고, 카운터를 증가 또는 감소시키고 현재 카운트를 얻거나 생성 된 CounterFactory 객체의 수를 얻을 수 있습니다 :

angular.factory('CounterFactory', function () {
  var number_of_counter_factories = 0; // class variable

  return function () {
    var count = 0; // instance variable
    number_of_counter_factories += 1; // increment the class variable

    // this method accesses the class variable
    this.getNumberOfCounterFactories = function () {
      return number_of_counter_factories;
    };

    this.inc = function () {
      count += 1;
    };
    this.dec = function () {
      count -= 1;
    };
    this.getCount = function () {
      return count;
    };
  }

})

를 사용하여 CounterFactory여러 카운터를 만듭니다. 클래스 변수에 액세스하여 생성 된 카운터 수를 확인할 수 있습니다.

var people_counter;
var places_counter;

people_counter = new CounterFactory();
console.log('people', people_counter.getCount());
people_counter.inc();
console.log('people', people_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());

places_counter = new CounterFactory();
console.log('places', places_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());
console.log('counters', places_counter.getNumberOfCounterFactories());

이 코드의 출력은 다음과 같습니다.

people 0
people 1
counters 1
places 0
counters 2
counters 2

“Factory”와“Service”는 각도에서 DI (Dependency injection)를 수행하는 다른 방법입니다.

따라서 아래 코드와 같이“service”를 사용하여 DI를 정의 할 때. 이렇게하면 "Logger"개체의 새 GLOBAL 인스턴스가 만들어지고 함수에 주입됩니다.

app.service("Logger", Logger); // Injects a global object

"팩토리"를 사용하여 DI를 정의하면 인스턴스가 생성되지 않습니다. 메서드를 전달하기 만하면 나중에 소비자는 내부적으로 개체 인스턴스를 위해 팩토리를 호출해야합니다.

app.factory("Customerfactory", CreateCustomer);

아래는“서비스”에 대한 DI 프로세스가“공장”과 어떻게 다른지 시각적으로 보여주는 간단한 이미지입니다.

여기에 이미지 설명 입력

시나리오에 따라 다른 유형의 개체를 만들고 싶을 때 공장을 사용해야합니다. 예를 들어 시나리오에 따라 간단한 "고객"개체 또는 "주소"개체가있는 "고객"또는 "전화"개체가있는 "고객"을 만들려고합니다. 이 단락에 대한 자세한 설명은 다음과 같습니다.

Utility, Logger, Error handler 등과 같이 주입 할 유틸리티 또는 공유 함수가있을 때 서비스를 사용해야합니다.


서비스 스타일 : ( 아마도 가장 간단한 것 ) 실제 함수를 반환합니다. 삽입 된 함수 참조에 ()를 추가하여 호출하는 데 유용한 유틸리티 함수를 공유하는 데 유용합니다.

AngularJS의 서비스는 함수 집합을 포함하는 단일 JavaScript 객체입니다.

var myModule = angular.module("myModule", []);

myModule.value  ("myValue"  , "12345");

function MyService(myValue) {
    this.doIt = function() {
        console.log("done: " + myValue;
    }
}

myModule.service("myService", MyService);
myModule.controller("MyController", function($scope, myService) {

    myService.doIt();

});

팩토리 스타일 : ( 더 복잡하지만 더 정교함 ) 함수의 반환 값을 반환합니다. java에서 new Object ()와 같은 객체를 인스턴스화합니다.

공장은 가치를 창출하는 기능입니다. 서비스, ​​컨트롤러 등이 공장에서 주입 된 값을 필요로 할 때 공장은 필요에 따라 값을 생성합니다. 생성 된 값은 주입이 필요한 모든 서비스, 컨트롤러 등에 재사용됩니다.

var myModule = angular.module("myModule", []);

myModule.value("numberValue", 999);

myModule.factory("myFactory", function(numberValue) {
    return "a value: " + numberValue;
})  
myModule.controller("MyController", function($scope, myFactory) {

    console.log(myFactory);

});

공급자 스타일 : ( 완전한 구성 가능 버전 ) 함수의 $ get 함수 : Configurable의 출력을 반환합니다.

AngularJS의 공급자는 생성 할 수있는 가장 유연한 형태의 팩토리입니다. provider () 함수를 대신 사용한다는 점을 제외하면 서비스 또는 팩토리에서하는 것처럼 모듈에 공급자를 등록합니다.

var myModule = angular.module("myModule", []);

myModule.provider("mySecondService", function() {
    var provider = {};
    var config   = { configParam : "default" };

    provider.doConfig = function(configParam) {
        config.configParam = configParam;
    }

    provider.$get = function() {
        var service = {};

        service.doService = function() {
            console.log("mySecondService: " + config.configParam);
        }

        return service;
    }

    return provider;
});

myModule.config( function( mySecondServiceProvider ) {
    mySecondServiceProvider.doConfig("new config param");
});

myModule.controller("MyController", function($scope, mySecondService) {

    $scope.whenButtonClicked = function() {
        mySecondService.doIt();
    }

});

src jenkov

<!DOCTYPE html>
    <html ng-app="app">
    <head>
    	<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
    	<meta charset=utf-8 />
    	<title>JS Bin</title>
    </head>
    <body ng-controller="MyCtrl">
    	{{serviceOutput}}
    	<br/><br/>
    	{{factoryOutput}}
    	<br/><br/>
    	{{providerOutput}}
    
    	<script>
    
    		var app = angular.module( 'app', [] );
    
    		var MyFunc = function() {
    
    			this.name = "default name";
    
    			this.$get = function() {
    				this.name = "new name"
    				return "Hello from MyFunc.$get(). this.name = " + this.name;
    			};
    
    			return "Hello from MyFunc(). this.name = " + this.name;
    		};
    
    		// returns the actual function
    		app.service( 'myService', MyFunc );
    
    		// returns the function's return value
    		app.factory( 'myFactory', MyFunc );
    
    		// returns the output of the function's $get function
    		app.provider( 'myProv', MyFunc );
    
    		function MyCtrl( $scope, myService, myFactory, myProv ) {
    
    			$scope.serviceOutput = "myService = " + myService;
    			$scope.factoryOutput = "myFactory = " + myFactory;
    			$scope.providerOutput = "myProvider = " + myProv;
    
    		}
    
    	</script>
    
    </body>
    </html>

jsbin

<!DOCTYPE html>
<html ng-app="myApp">
<head>
	<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
	<meta charset=utf-8 />
	<title>JS Bin</title>
</head>
<body>
<div ng-controller="MyCtrl">
    {{hellos}}
</div>
	<script>

	var myApp = angular.module('myApp', []);

//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});

//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!"
        }
    };
});
    
//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});
        

function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
    
    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}
	</script>

</body>
</html>

jsfiddle


기본적인 차이점은 제공자 는 기본 (객체가 아닌), 배열 또는 콜백 함수 값을 팩토리 선언 변수로 설정할 수 있으므로 객체를 반환하는 경우 명시 적으로 선언하고 반환해야한다는 것입니다.

반면에 서비스 는 서비스 선언 변수를 객체로 설정하는 데만 사용할 수 있으므로 객체의 명시 적 생성 및 반환을 피할 수있는 반면에 this 키워드를 사용할 수 있습니다 .

또는 간단히 말해서 " 제공자 는보다 일반적인 형태이지만 서비스 는 객체로만 제한됩니다".


이것이 디자인 패턴 측면에서 차이점을 이해 한 방법입니다.

서비스 : 해당 유형의 객체를 생성하기 위해 새로 추가 될 유형을 반환합니다. Java 비유가 사용되는 경우 서비스는 Java 클래스 정의를 반환합니다 .

Factory : 즉시 사용할 수있는 구체적인 객체를 반환합니다. Java Analogy에서 Factory는 Java Object를 반환합니다 .

사람들 (나를 포함하여)을 자주 혼동하는 부분은 서비스 또는 팩토리를 코드에 삽입 할 때 동일한 방식으로 사용할 수 있다는 것입니다. 두 경우 모두 코드에서 얻는 것은 즉시 호출 할 수있는 구체적인 객체입니다. 즉, 서비스의 경우 angular는 귀하를 대신하여 서비스 선언에 "new"라고 부릅니다. 나는 이것이 복잡한 개념이라고 생각합니다.


이것은 Service Vs Factory Vs Provider를 이해하는 데 가장 좋고 짧은 대답입니다.

출처 : https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J

여기 데모 http://jsbin.com/ohamub/1/edit?html,output으로 말하는 내용

"코드에 주요 차이점을 설명하는 주석이 있지만 여기에서 조금 더 자세히 설명하겠습니다. 참고로이 문제에 대해 머리를 돌리는 중이므로 잘못된 점이 있으면 알려주십시오.

서비스

구문 : module.service ( 'serviceName', function);

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

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

공장

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

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

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

제공자

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

결과 : providerName을 주입 가능한 인수로 선언 할 때 module.provider에 전달 된 함수 참조의 $ get 메서드를 호출하여 반환되는 값이 제공됩니다.

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


나는 잠시 동안 이러한 혼란을 겪었고 여기에 간단한 설명을 제공하기 위해 최선을 다하고 있습니다. 이것이 도움이되기를 바랍니다!

angular .factory그리고 angular .service모두 동일한 방식으로 서비스와 작업을 초기화하는 데 사용됩니다.

유일한 차이점은 서비스를 초기화하는 방법입니다.

둘 다 싱글 톤입니다.


var app = angular.module('app', []);


공장

app.factory ( <service name>, <function with a return value>)

반환 값이있는 함수 에서 서비스를 초기화 하려면이 factory메서드 를 사용해야합니다 .

예 :

function myService() {
  //return what you want
  var service = {
    myfunc: function (param) { /* do stuff */ }
  }
  return service;
}

app.factory('myService', myService);

이 서비스를 삽입 할 때 (예 : 컨트롤러에) :

  • Angular는 주어진 함수 (as )를 호출 하여 myService()객체를 반환합니다.
  • Singleton- 한 번만 호출되고 저장되고 동일한 객체를 전달합니다.


서비스

app.service ( <service name>, <constructor function>)

생성자 함수 ( this키워드 사용 ) 에서 서비스를 초기화 하려면이 service메서드 를 사용해야합니다 .

예 :

function myService() {
  this.myfunc: function (param) { /* do stuff */ }
}

app.service('myService', myService);

이 서비스를 삽입 할 때 (예 : 컨트롤러에) :

  • Angular는 new주어진 함수 (as new myService())를 사용하여 객체를 반환합니다.
  • Singleton- 한 번만 호출되고 저장되고 동일한 객체를 전달합니다.


참고 : factory와 함께 <constructor function>또는와 service함께 사용하면 <function with a return value>작동하지 않습니다.


예-데모


이것이 Pascal Precht의 블로그 게시물 덕분에 차이점을 이해하는 데 도움이되었습니다.

서비스는 서비스를 정의하는 이름과 함수를 사용하는 모듈의 메서드입니다. 컨트롤러, 지시문 및 필터와 같은 다른 구성 요소에 특정 서비스를 삽입하고 사용할 수 있습니다. 팩토리는 모듈의 메서드이며 팩토리를 정의하는 이름과 함수도받습니다. 또한 서비스에서했던 것과 동일한 방식으로 주입하고 사용할 수 있습니다.

new로 생성 된 객체는 생성자 함수의 프로토 타입 속성 값을 프로토 타입으로 사용하므로 인스턴스화 될 때 서비스 생성자 함수라고 생각하는 Object.create ()를 호출하는 Angular 코드를 찾았습니다. 그러나 팩토리 함수는 실제로 호출되는 함수일 뿐이므로 팩토리에 대한 객체 리터럴을 반환해야합니다.

공장에서 찾은 각 1.5 코드는 다음과 같습니다.

var needsRecurse = false;
    var destination = copyType(source);

    if (destination === undefined) {
      destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
      needsRecurse = true;
    }

factory () 함수에 대한 Angular 소스 코드 스 니펫 :

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

service ()를 호출하면 실제로 factory ()를 호출합니다! 그러나 서비스 생성자 함수를 그대로 팩토리에 전달하는 것은 아닙니다. 또한 주어진 생성자에 의해 객체를 인스턴스화하도록 인젝터에 요청하는 함수를 전달합니다.

즉, MyService를 어딘가에 삽입하면 코드에서 일어나는 일은 다음과 같습니다.

MyServiceProvider.$get(); // return the instance of the service

다시 설명하기 위해 서비스는 해당 공급자의 $ get () 메서드 인 팩토리를 호출합니다. 게다가 $ injector.instantiate ()는 궁극적으로 생성자 함수로 Object.create ()를 호출하는 메서드입니다. 이것이 우리가 서비스에서 "this"를 사용하는 이유입니다.

ES5의 경우 service () 또는 factory () 중 어느 것을 사용하는지는 중요하지 않습니다. 항상 우리 서비스에 대한 공급자를 생성하는 호출되는 팩토리입니다.

하지만 서비스에서도 똑같은 일을 할 수 있습니다. 서비스는 생성자 함수이지만 객체 리터럴을 반환하는 것을 막지는 않습니다. 따라서 우리는 서비스 코드를 가져 와서 기본적으로 우리 공장과 똑같은 방식으로 작성할 수 있습니다. 즉, 서비스를 공장으로 작성하여 객체를 반환 할 수 있습니다.

왜 대부분의 사람들은 서비스보다 공장을 사용하도록 권장합니까? 이것은 Pawel Kozlowski의 저서 : Mastering Web Application Development with AngularJS에서 가져온 최고의 답변입니다.

팩토리 방법은 객체를 AngularJS 종속성 주입 시스템으로 가져 오는 가장 일반적인 방법입니다. 매우 유연하고 정교한 생성 논리를 포함 할 수 있습니다. 팩토리는 일반 함수이기 때문에 새로운 어휘 범위를 이용하여 "개인"변수를 시뮬레이션 할 수도 있습니다. 이는 주어진 서비스의 구현 세부 사항을 숨길 수 있으므로 매우 유용합니다. "


  • 공장 당신은 실제로 만들 객체 의 내부 공장을 하고 돌아갑니다.
  • 으로 서비스 당신은 단지가 표준 기능 용도 this함수를 정의하는 키워드를.
  • 제공 거기의 $get당신이 정의하고 사용할 수 있습니다 얻기 위해 데이터를 반환하는 개체를.

AngularJS에는 비즈니스 로직을 처리하는 세 가지 방법이 있습니다. ( Yaakov의 Coursera AngularJS 과정에서 영감을 얻음 )

  1. 서비스
  2. 공장
  3. 공급자

여기서는 서비스공장 에 대해서만 이야기하겠습니다.

서비스 :

통사론:

app.js

 var app = angular.module('ServiceExample',[]);
 var serviceExampleController =
              app.controller('ServiceExampleController', ServiceExampleController);
 var serviceExample = app.service('NameOfTheService', NameOfTheService);

 ServiceExampleController.$inject = ['NameOfTheService'] //very important as this protects from minification of js files

function ServiceExampleController(NameOfTheService){
     serviceExampleController = this;
     serviceExampleController.data = NameOfTheService.getSomeData();
 }

function NameOfTheService(){
     nameOfTheService = this;
     nameOfTheService.data = "Some Data";
     nameOfTheService.getSomeData = function(){
           return nameOfTheService.data;
     }     
}

index.html

<div ng-controller = "ServiceExampleController as serviceExample">
   {{serviceExample.data}}
</div>

서비스의 주요 기능 :

  1. Lazily Instantiated : 서비스가 주입되지 않으면 인스턴스화되지 않습니다. 따라서이를 사용하려면 모듈에 주입해야합니다.

  2. Singleton : 여러 모듈에 주입되면 모두 하나의 특정 인스턴스에만 액세스 할 수 있습니다. 그렇기 때문에 서로 다른 컨트롤러간에 데이터를 공유하는 것이 매우 편리합니다.

공장

이제 AngularJS의 공장에 대해 이야기 해 봅시다.

먼저 구문을 살펴 보겠습니다 .

app.js :

var app = angular.module('FactoryExample',[]);
var factoryController = app.controller('FactoryController', FactoryController);
var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne);
var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo);

//first implementation where it returns a function
function NameOfTheFactoryOne(){
   var factory = function(){
      return new SomeService();
    }
   return factory;
}

//second implementation where an object literal would be returned
function NameOfTheFactoryTwo(){
   var factory = {
      getSomeService : function(){
          return new SomeService();
       }
    };
   return factory;
}

이제 컨트롤러에서 위의 두 가지를 사용합니다.

 var factoryOne = NameOfTheFactoryOne() //since it returns a function
 factoryOne.someMethod();

 var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
 factoryTwo.someMethod();

공장의 특징 :

  1. 이러한 유형의 서비스는 공장 설계 패턴을 따릅니다 . 공장은 새로운 대상이나 방법을 만드는 중심 장소로 생각할 수 있습니다.

  2. 이것은 싱글 톤뿐만 아니라 사용자 정의 가능한 서비스도 생성합니다.

  3. .service()방법은 항상 동일한 유형의 서비스를 생산 하는 팩토리 입니다. 동작을 구성하는 쉬운 방법은 없습니다. .service()방법은 일반적으로 구성이 필요하지 않은 항목의 바로 가기로 사용됩니다.


짧고 간단한 설명은 https://stackoverflow.com/a/26924234/5811973을 참조 하십시오 .

자세한 설명은 https://stackoverflow.com/a/15666049/5811973을 참조 하십시오 .

또한 angularJs 문서에서 : 여기에 이미지 설명 입력


이 비유로 그 차이를 이해할 수 있습니다-어떤 값을 반환하는 일반 함수와 new 키워드를 사용하여 인스턴스화 할 생성자 함수의 차이점을 고려하면 팩토리를 생성하는 것은 일부 값 (기본 또는 서비스를 생성하는 것은 생성자 함수 (OO 클래스)를 생성하는 것과 같으며 새로운 키워드를 사용하여 인스턴스를 생성 할 수 있습니다. 여기서 주목해야 할 것은 Service 메서드를 사용하여 서비스를 만들 때 AngularJS에서 지원하는 종속성 주입 메커니즘을 사용하여 자동으로 인스턴스를 생성한다는 것입니다.

참고 URL : https://stackoverflow.com/questions/13762228/confused-about-service-vs-factory

반응형