목차
1. 의존성 주입(DI)이란 무엇인가?
- DI의 개념
- DI의 장점
2. PHP-DI 라이브러리 사용법
- PHP-DI 설치 및 설정
- 기본적인 의존성 주입 구현
3. DI 컨테이너 설정 및 사용
- 컨테이너 설정
- 컨테이너를 사용한 객체 생성 및 관리
4. 코드 예제
5. 결론 및 추가 학습 자료
1. 의존성 주입(DI)이란 무엇인가?
DI의 개념
의존성 주입(Dependency Injection, DI)은 객체가 그 동작에 필요한 의존성을 스스로 생성하지 않고 외부에서 주입받는 디자인 패턴입니다. 이를 통해 코드의 결합도를 낮추고, 유지보수성을 높이며, 테스트가 용이한 코드를 작성할 수 있습니다.
DI의 장점
- 결합도 감소: 객체 간의 강한 결합을 제거하여 코드의 유연성과 재사용성을 높입니다.
- 테스트 용이성: 모의 객체(Mock Object)를 사용한 단위 테스트가 가능해집니다.
- 코드 가독성 향상: 객체의 의존성이 명확하게 드러나므로 코드의 이해도가 높아집니다.
- 유지보수성 향상: 의존성을 쉽게 교체할 수 있어 코드의 유지보수가 용이해집니다.
2. PHP-DI 라이브러리 사용법
PHP-DI 설치 및 설정
PHP-DI는 PHP에서 의존성 주입을 쉽게 구현할 수 있도록 도와주는 강력한 라이브러리입니다. Composer를 통해 설치할 수 있습니다.
Composer를 통한 설치:
composer require php-di/php-di
설치가 완료되면, PHP-DI를 사용하여 의존성 주입을 구현할 수 있습니다.
기본적인 의존성 주입 구현
의존성 주입을 구현하기 위해 먼저 필요한 인터페이스와 클래스들을 정의하고, PHP-DI 컨테이너를 통해 의존성을 주입받아 객체를 생성합니다.
예제:
// src/LoggerInterface.php
<?php
interface LoggerInterface
{
public function log(string $message);
}
?>
// src/FileLogger.php
<?php
class FileLogger implements LoggerInterface
{
public function log(string $message)
{
file_put_contents('app.log', $message . PHP_EOL, FILE_APPEND);
}
}
?>
// src/UserService.php
<?php
class UserService
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function registerUser(string $username)
{
// 사용자 등록 로직
$this->logger->log("User {$username} registered.");
}
}
?>
이 예제에서 'UserService' 클래스는 'LoggerInterface'에 의존하고 있으며, 'FileLogger' 클래스가 실제 구현체로 사용됩니다. 의존성을 외부에서 주입받아 'UserService'가 필요한 'LoggerInterface' 구현체를 사용할 수 있습니다.
3. DI 컨테이너 설정 및 사용
컨테이너 설정
PHP-DI 컨테이너는 의존성을 관리하고, 필요한 객체를 생성하여 주입하는 역할을 합니다. 설정 파일을 통해 컨테이너에 매핑 정보를 제공하여, 객체 생성과 의존성 주입을 자동화할 수 있습니다.
컨테이너 설정 예제:
// config/di.php
<?php
use DI\ContainerBuilder;
use function DI\create;
use function DI\get;
return function (ContainerBuilder $containerBuilder) {
$containerBuilder->addDefinitions([
LoggerInterface::class => create(FileLogger::class),
UserService::class => create(UserService::class)
->constructor(get(LoggerInterface::class)),
]);
};
?>
이 설정 파일은 'LoggerInterface'가 'FileLogger'로 매핑되도록 설정하고, 'UserService'가 'LoggerInterface'를 의존성으로 주입받도록 설정합니다.
컨테이너를 사용한 객체 생성 및 관리
설정된 컨테이너를 사용하여 객체를 생성하고 의존성을 주입할 수 있습니다.
// public/index.php
<?php
require '../vendor/autoload.php';
// 컨테이너 빌더 생성 및 설정 파일 로드
$containerBuilder = new DI\ContainerBuilder();
$containerBuilder->addDefinitions(require '../config/di.php');
// 컨테이너 빌드
$container = $containerBuilder->build();
// UserService 객체 생성 및 사용
$userService = $container->get(UserService::class);
$userService->registerUser('john_doe');
?>
이 예제에서는 'UserService' 객체를 DI 컨테이너에서 생성하며, 'FileLogger'가 'LoggerInterface'의 구현체로 자동 주입됩니다. 이렇게 생성된 'UserService' 객체를 통해 사용자 등록 작업을 수행합니다.
4. 코드 예제
다음은 PHP-DI를 사용하여 의존성 주입을 구현하는 종합적인 예제입니다.
1. Logger 인터페이스 및 구현체:
// src/LoggerInterface.php
<?php
interface LoggerInterface
{
public function log(string $message);
}
?>
// src/FileLogger.php
<?php
class FileLogger implements LoggerInterface
{
public function log(string $message)
{
file_put_contents('app.log', $message . PHP_EOL, FILE_APPEND);
}
}
?>
2. UserService 클래스:
// src/UserService.php
<?php
class UserService
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function registerUser(string $username)
{
// 사용자 등록 로직
$this->logger->log("User {$username} registered.");
}
}
?>
3. DI 컨테이너 설정:
// config/di.php
<?php
use DI\ContainerBuilder;
use function DI\create;
use function DI\get;
return function (ContainerBuilder $containerBuilder) {
$containerBuilder->addDefinitions([
LoggerInterface::class => create(FileLogger::class),
UserService::class => create(UserService::class)
->constructor(get(LoggerInterface::class)),
]);
};
?>
4. 메인 애플리케이션 파일:
// public/index.php
<?php
require '../vendor/autoload.php';
// 컨테이너 빌더 생성 및 설정 파일 로드
$containerBuilder = new DI\ContainerBuilder();
$containerBuilder->addDefinitions(require '../config/di.php');
// 컨테이너 빌드
$container = $containerBuilder->build();
// UserService 객체 생성 및 사용
$userService = $container->get(UserService::class);
$userService->registerUser('john_doe');
?>
코드 분석:
- 첫 번째 예제는 'LoggerInterface'와 그 구현체인 'FileLogger'를 정의합니다.
- 두 번째 예제는 'UserService' 클래스에서 'LoggerInterface'를 의존성으로 주입받아 사용자 등록을 처리합니다.
- 세 번째 예제는 PHP-DI 컨테이너 설정 파일로, 의존성을 정의하고 매핑합니다.
- 네 번째 예제는 설정된 컨테이너를 사용하여 'UserService' 객체를 생성하고, 이를 통해 사용자 등록 작업을 수행합니다.
5. 결론 및 추가 학습 자료
이번 글에서는 PHP에서 의존성 주입(DI)을 사용하는 방법에 대해 알아보았습니다. DI를 통해 코드의 결합도를 낮추고, 유지보수성과 테스트 용이성을 높일 수 있습니다. PHP-DI 라이브러리를 사용하여 DI 컨테이너를 설정하고, 객체 생성을 자동화함으로써 코드의 가독성과 유연성을 향상시킬 수 있습니다.
추가 학습 자료:
- [PHP-DI 공식 문서](https://php-di.org/doc/) PHP-DI 라이브러리의 설치 및 사용법에 대한 자세한 문서입니다.
- [Dependency Injection Explained](https://martinfowler.com/articles/injection.html) 마틴 파울러의 의존성 주입에 대한 설명과 다양한 패턴을 소개합니다.
- [PHP The Right Way - 의존성 주입](https://phptherightway.com/#dependency_injection) PHP에서 의존성 주입을 사용하는 올바른 방법에 대한 가이드입니다.
이제 의존성 주입을 사용하여 더욱 유연하고 유지보수성이 높은 PHP 애플리케이션을 개발할 수 있습니다. 실습을 통해 DI 패턴을 프로젝트에 적용해보세요!
'PHP' 카테고리의 다른 글
PHP에서 자주 사용되는 디자인 패턴 (3) | 2024.09.29 |
---|---|
PHP에서 이벤트와 리스너 사용하기 (0) | 2024.09.28 |
PHP에서 라우팅 구현하기 (4) | 2024.09.26 |
PHP로 MVC 패턴 구현하기 (6) | 2024.09.25 |
PHP에서 PSR 표준 적용하기 (2) | 2024.09.24 |