75호. 라라벨 기본 기능을 런타임에 확장하기: 매크로 free

2019-10-18

프레임워크가 제공하는 클래스에 기능 하나만 추가하고 싶은 경우 어떻게 해야할까요? 기본적으로 떠올릴 수 있는 방법은 프레임워크가 제공하는 클래스를 상속받아 기능을 추가하는 것입니다.


하지만 상속을 하면 귀찮은 일이 발생할 가능성이 많습니다. 74호에서도 다뤘듯이 프레임워크가 부모 클래스가 아닌 자식 클래스를 사용하도록 무언가를 수정해줘야 합니다. 74호는 모델이 커스텀 컬렉션을 반환하는 예제를 다뤘는데, 이런 방법을 직접 알아내려고 했다면 프레임워크가 어떻게 동작하는지 분석해야하므로 다소 어렵웠을 수 있다고 생각합니다.


그래서 라라벨은 프레임워크가 제공하는 클래스에 쉽게 기능을 추가할 수 있는 방법을 제공합니다. 바로 매크로라고 부르는 것입니다.


Macroable 트레이트를 사용하는 클래스는 쉽게 macro() 매서드로 런타임에 기능을 확장할 수 있습니다. Macroable 트레이트가 적용된 클래스는 매우 많습니다. Request, Response, Event, Collection 등 과장해서 말하면 흔히 사용하는 대부분의 클래스가 매크로를 이용한 기능 확장을 지원합니다.


지난 74호의 예제는 컬렉션에 기능을 확장하는 것이었는데, 컬렉션이 Macroable 트레이트를 사용하므로 매크로를 이용해서 훨씬 쉽게 목적을 달성할 수 있습니다.


<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{

}

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Collection::macro('groupByDate', function(){
return $this->groupBy(function($video) {
if($video->created_at->isToday()) {
return 'today';
}

if($video->created_at->isCurrentWeek()) {
return 'this week';
}

if($video->created_at->isLastWeek()) {
return 'last week';
}

return 'older'
});
});
}
}

위와 같이 서비스 프로바이더에서 매크로를 추가하고 Collection에서 groupByDate() 매서드를 사용하면 됩니다. VideoCollection을 만들 필요도, Video 모델이 Collection 대신 VideoCollection을 반환하게 할 필요도 없습니다.


뭔가 라라벨의 클래스를 상속받아서 기능을 추가해야겠다 싶으면 우선 해당 클래스가 Macroable 트레이트를 사용하고 있는지 먼저 확인해보세요!


1일 1식 라라벨 75호

2019년 10월 18일


이현석

메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.