Contracts
시작하기
라라벨의 "Contract"는 프레임워크에서 제공하는 코어 서비스들을 정의한 인터페이스들의 모음입니다. 예를 들어, Illuminate\Contracts\Queue\Queue
Contract에는 어떤 작업들을 큐에서 다룰때 필요한 메소드들이 정의되어 있고, Illuminate\Contracts\Mail\Mailer
Contract에는 이메일을 보내기 위해 필요한 메소드들을 정의되어 있습니다.
라라벨 프레임워크에는 각각의 Contract에 상응하는 구현체(구현 클래스)가 있습니다. 예를 들어, 라라벨은 다양한 드라이버로 구현된 queue의 구현체를 가지고 있고, Symfony Mailer를 mailer의 구현체로 가지고 있습니다.
라라벨의 모든 Contract는 각각의 Github 저장소를 가지고 있습니다. 이것은 사용가능한 모든 인터페이스에 대해 확인할 수 있는 역할을 합니다. 또한 라라벨 서비스와 작용하는 패키지를 만들때 사용할 수 있는 독립적인 인터페이스를 제공합니다.
Contracts VS Facades
라라벨의 파사드는 서비스 컨테이너 외부에서 타입 힌트나, contracts 의 의존성 없이도 라라벨의 서비스를 시용할 수 있는 쉬운 방법을 제공합니다.
클래스 생성자에서 요구하지 않아도 되는 파사드와 달리 contracts를 통해 클래스에 대한 명시적 의존성을 정의 할 수 있습니다. 일부 개발자는 이러한 방식으로 의존성을 명시적으로 정의하는 contracts를 선호하지만 대다수의 개발자는 파사드의 편리함을 누리고 있습니다. 일반적으로 대부분의 애플리케이션은 개발 중에 문제 없이 파사드를 사용할 수 있습니다.
Contracts 사용 시기
contract나 파사드 둘 중 어느것을 사용할지는 개인적인 그리고 개발팀의 취향에 달려 있습니다. contract와 파사드 모두 강력하고 잘 테스트 된 라라벨 애플리케이션을 작성하는 데 사용할 수 있습니다. Contract와 파사드는 상호 배타적이지 않기 때문에 애플리케이션의 일부에는 파사드를 사용하고, 다른쪽에서는 Contract를 사용할 수도 있습니다. Contract와 파사드를 사용하는 것은 클래스의 역할에 집중하는 관점에서 실제적인 차이점가 거의 없습니다.
일반적으로, 대부분의 애플리케이션은 개발중에 파사드를 사용하는데 별다른 문제가 없습니다. 여러 PHP 프레임워크와 통합되는 패키지를 작성하는 경우 패키지에서 라라벨의 구체적인 구현서비스를 호출할 필요없이 composer.json
파일에 라라벨의 illuminate/contracts
패키지를 추가하여 통합을 정의할 수 있습니다.
Contract는 어떻게 사용할 수 있는가?
그럼 어떻게 Contract의 구현체를 얻을 수 있을까요? 사실 매우 간단합니다.
라라벨에 있는 여러 종류의 클래스들은 컨트롤러, 이벤트리스너, 미들웨어, 큐 작업, 라우트 클로저들을 관리하는 서비스 컨테이너를 통해 의존성 해결(resolve) 되고 있습니다. 따라서 의존성이 해결되는 어떤 클래스가 특정 Contract의 구현체를 얻으려면 그 클래스의 생성자에 그 인터페이스를 "type-hint"로 지정해놓으면 됩니다
그 예로 아래의 이벤트 리스너를 살펴보겠습니다.
<?php
namespace App\Listeners;
use App\Events\OrderWasPlaced;
use App\Models\User;
use Illuminate\Contracts\Redis\Factory;
class CacheOrderInformation
{
/**
* The Redis factory implementation.
*
* @var \Illuminate\Contracts\Redis\Factory
*/
protected $redis;
/**
* Create a new event handler instance.
*
* @param \Illuminate\Contracts\Redis\Factory $redis
* @return void
*/
public function __construct(Factory $redis)
{
$this->redis = $redis;
}
/**
* Handle the event.
*
* @param \App\Events\OrderWasPlaced $event
* @return void
*/
public function handle(OrderWasPlaced $event)
{
//
}
}
이벤트리스너가 의존성 해결될 때, 서비스 컨테이너는 클래스의 생성자에 있는 타입힌트를 읽고, 그에 적합한 객체 인스턴스를 주입해 줍니다. 서비스 컨테이너에 무언가를 등록하는 것에 대하여 더 알고싶다면, 이 문서를 참고하시기 바랍니다.
Contract 참조
아래는 대부분의 라라벨 Contract와 그에 대응되는 파사드들의 레퍼런스입니다.