Laravel에서 데이터 엑세스를 추상화하는 디자인 패턴인 Repository Pattern을 적용해 보도록 한다.
Repository Pattern은 간단히 말하자면, 데이터 출처에 관계 없이 동일한 인터페이스로 데이터에 접근할 수 있도록 만드는 것이다. 이 패턴을 적용시키면 Model은 Repository에 데이터를 요청해서 받아올 수 있기 때문에, Model은 데이터의 출처(로컬/서버)나 방식에 대해서 알 필요가 없어지며 순전히 비즈니스 로직에만 집중할 수 있게 된다.
코드 재사용성
엑세스 로직을 캡슐화시킴으로써 동일한 방식의 엑세스 로직을 필요로 하는 경우, 코드를 재사용하기 쉽다.
데이터 엑세스의 추상화
엑세스 로직의 추상화를 통해 데이터의 세부 정보를 비즈니스 로직으로부터 분리시킬 수 있다. 이로 인해, 데이터를 받아오는 방법을 변경하더라도 애플리케이션의 다른 부분의 영향을 미치지 않는다.
로직을 분리함으로써, 그만큼 독립성/재사용성이 상승했다는 장점도 있지만 그에 반해 유지보수할 곳이 더 늘어난다는 점과 복잡성이 늘어나므로 새로 들어온 멤버의 코드 이해의 시간이 더 걸릴 가능성이 높다.
Repository Pattern의 핵심이 되는 엑세스 로직의 분리를 위해 Laravel에서는 app\Repositories라는 디렉토리를 권장한다.
namespace App\Repositories;
interface UserRepositoryInterface
{
public function getAllUsers();
public function findUserById($id);
public function createUser(array $data);
}
namespace App\Repositories;
use App\Models\User;
class UserRepository implements UserRepositoryInterface
{
public function getAllUsers()
{
return User::all();
}
public function findUserById($id)
{
return User::find($id);
}
public function createUser(array $data)
{
return User::create($data);
}
}
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Repositories\UserRepositoryInterface;
use App\Repositories\UserRepository;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(UserRepositoryInterface::class,
UserRepository::class);
}
}
namespace App\Http\Controllers;
use App\Repositories\UserRepositoryInterface;
class UserController extends Controller
{
protected $userRepository;
public function __construct(UserRepositoryInterface $userRepository)
{
$this->userRepository = $userRepository;
}
public function index()
{
$users = $this->userRepository->getAllUsers();
return view('users.index', compact('users'));
}
}