AngularJS - 의존성 주입: 초보자 가이드

안녕하세요, 야심 찬 프로그래머 여러분! 오늘 우리는 AngularJS의 세계와 그 중에서도 가장 강력한 기능 중 하나인 의존성 주입(Dependency Injection, DI)에 대해 흥미로운 여정을 시작할 것입니다. 이 용어들이 지금은 낯설게 들릴 수 있지만, 이 튜토리얼이 끝나면 당신은 이를 마스터级别으로 사용할 수 있을 것입니다!

AngularJS - Dependency Injection

의존성 주입이란?

정밀한 내용에 들어가기 전에, 의존성 주입이 무엇인지 이해해 보겠습니다. 상상해 보세요, 케이크를 만들 때입니다. 모든 재료를 스스로 준비하는 대신, 필요할 때마다 필요한 재료를 받는다면 얼마나 좋을까요? 이는 프로그래밍에서 의존성 주입이 하는 일입니다 - 코드(케이크)가 제대로 작동하기 위해 필요한 컴포넌트(재료)를 제공합니다.

이제 AngularJS가 의존성 주입을 어떻게 구현하는지 탐구해 보겠습니다.

Value

Value는 의존성 주입의 가장 간단한 형태입니다. 케이크 만들기 함수에 단일 재료를 전달하는 것과 같습니다.

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

app.value('playerName', 'LeBron James');

app.controller('PlayerCtrl', function($scope, playerName) {
$scope.name = playerName;
});

이 예제에서 우리는 'playerName'이라는 값을 생성하고 컨트롤러에 주입합니다. 컨트롤러는 이 값을 로컬 변수처럼 사용할 수 있습니다.

Factory

Factory는 케이크 믹스와 같습니다 - 객체를 생성하고 반환하는 함수입니다. Value보다 더 복잡하지만 더 많은 유연성을 제공합니다.

app.factory('playerFactory', function() {
return {
name: 'Stephen Curry',
team: 'Golden State Warriors',
getInfo: function() {
return this.name + '은 ' + this.team + '에서 뛰고 있습니다.';
}
};
});

app.controller('PlayerCtrl', function($scope, playerFactory) {
$scope.playerInfo = playerFactory.getInfo();
});

여기서 우리는 속성과 메서드를 가진 객체를 반환하는 팩토리를 생성합니다. 컨트롤러는 이 팩토리를 사용하여 선수의 정보에 접근할 수 있습니다.

Service

Service는 Factory와 비슷하지만, 객체 대신 함수 인스턴스를 반환합니다. 특정 케이크를 만드는 전문 베이커라고 생각할 수 있습니다.

app.service('PlayerService', function() {
this.name = 'Kevin Durant';
this.team = 'Phoenix Suns';
this.getInfo = function() {
return this.name + '은 ' + this.team + '에서 뛰고 있습니다.';
};
});

app.controller('PlayerCtrl', function($scope, PlayerService) {
$scope.playerInfo = PlayerService.getInfo();
});

Factory와 Service의 주요 차이는 인스턴스화 방식입니다. Service는 항상 싱글턴입니다 - 애플리케이션 전체에 하나의 인스턴스만 있습니다.

Provider

Provider는 AngularJS에서 의존성 주입의 가장 복잡한 형태입니다. 원하는 어떤 종류의 케이크든, 원하는 재료로, 원하는 방식으로 만들 수 있는 완전히 갖추어진 베이커리와 같습니다.

app.provider('playerProvider', function() {
var defaultName = 'Giannis Antetokounmpo';

return {
setName: function(name) {
defaultName = name;
},
$get: function() {
return {
getName: function() {
return defaultName;
}
};
}
};
});

app.config(function(playerProviderProvider) {
playerProviderProvider.setName('Luka Doncic');
});

app.controller('PlayerCtrl', function($scope, playerProvider) {
$scope.playerName = playerProvider.getName();
});

Provider는 애플리케이션이 실행되기 전에 서비스를 구성할 수 있게 해줍니다. 이 예제에서 우리는 설정 단계에서 선수의 이름을 설정하고 있습니다.

Constant

Constant는 Value와 비슷하지만, 설정 단계에서 주입할 수 있는 특성을 가집니다. 언제나 정확하게 따르는 레시피와 같습니다.

app.constant('GAME_DURATION', 48);

app.config(function(GAME_DURATION) {
console.log('농구 경기는 ' + GAME_DURATION + '분 동안 진행됩니다.');
});

app.controller('GameCtrl', function($scope, GAME_DURATION) {
$scope.duration = GAME_DURATION;
});

Constants는 애플리케이션 전체에서 변경되지 않는 값에 유용합니다.

예제: 농구 팀 매니저 만들기

이제 모든 종류의 의존성 주입을 다루었으므로, 더 복잡한 예제로 모든 것을 통합해 보겠습니다.

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

// Constant
app.constant('MAX_PLAYERS', 15);

// Value
app.value('teamName', 'Angular All-Stars');

// Factory
app.factory('PlayerFactory', function() {
var players = [];
return {
addPlayer: function(name) {
players.push(name);
},
getPlayers: function() {
return players;
}
};
});

// Service
app.service('CoachService', function() {
this.name = 'Coach Angular';
this.motivate = function() {
return this.name + '은 다음과 같이 말합니다: 이 경기를 이겨봅시다!';
};
});

// Provider
app.provider('gameProvider', function() {
var venue = 'Home Court';

return {
setVenue: function(v) {
venue = v;
},
$get: function() {
return {
getVenue: function() {
return venue;
}
};
}
};
});

app.config(function(gameProviderProvider) {
gameProviderProvider.setVenue('Angular Arena');
});

app.controller('TeamCtrl', function($scope, MAX_PLAYERS, teamName, PlayerFactory, CoachService, gameProvider) {
$scope.teamName = teamName;
$scope.maxPlayers = MAX_PLAYERS;
$scope.players = PlayerFactory.getPlayers();
$scope.coachMotivation = CoachService.motivate();
$scope.gameVenue = gameProvider.getVenue();

$scope.addPlayer = function(playerName) {
if ($scope.players.length < MAX_PLAYERS) {
PlayerFactory.addPlayer(playerName);
$scope.playerName = '';
} else {
alert('팀이 가득 찼습니다!');
}
};
});

출력

이 애플리케이션을 실행하면 완전한 기능을 갖춘 농구 팀 매니저를 가지게 됩니다. 팀에 선수를 추가할 수 있으며 (허용된 최대 인원까지), 코치의 동기부여를 볼 수 있고, 경기가 어디서 열리는지 알 수 있습니다.

다음은 우리가 다루었던 다양한 의존성 주입 유형을 요약한 표입니다:

유형 설명 사용 사례
Value 간단한 값 주입 간단한 값 주입에 사용
Factory 객체 반환 복잡한 로직을 가진 서비스 생성에 사용
Service 함수 인스턴스 반환 싱글턴 서비스에 사용
Provider 구성 가능한 서비스 팩토리 애플리케이션 실행 전에 서비스 구성에 사용
Constant 불변 값, 설정 주입 가능 애플리케이션 전체에서 변경되지 않는 값에 사용

의존성 주입을 마스터하기 위해서는 연습이 중요합니다. 간단한 주입부터 시작하여 점차 복잡한 상황으로 나아가세요. 언제나 그렇듯이, 앞으로의 AngularJS 마스터 여러분, 행복한 코딩을 기원합니다!

Credits: Image by storyset