# Laravel 고급 아키텍처
## 1. 서비스 클래스 패턴
```php
// app/Services/PostService.php
class PostService
{
public function create(array $data): Post
{
$post = Post::create($data);
event(new PostCreated($post));
return $post;
}
}
// 컨트롤러에서 사용
class PostController extends Controller
{
public function __construct(private PostService $postService) {}
public function store(StorePostRequest $request)
{
return $this->postService->create($request->validated());
}
}
```
## 2. Repository 패턴
```php
// app/Repositories/PostRepository.php
interface PostRepositoryInterface
{
public function all();
public function find(int $id);
public function create(array $data);
}
class PostRepository implements PostRepositoryInterface
{
public function all()
{
return Post::with("user")->latest()->get();
}
}
// AppServiceProvider에서 바인딩
$this->app->bind(PostRepositoryInterface::class, PostRepository::class);
```
## 3. 이벤트 & 리스너
```bash
php artisan make:event PostCreated
php artisan make:listener SendPostNotification --event=PostCreated
```
```php
// 이벤트 발생
event(new PostCreated($post));
// 리스너
class SendPostNotification
{
public function handle(PostCreated $event)
{
Mail::to($event->post->user)->send(new PostPublished($event->post));
}
}
```
## 4. Queue (백그라운드 작업)
```bash
php artisan make:job ProcessImage
php artisan queue:work
```
```php
// Job 디스패치
ProcessImage::dispatch($image)->onQueue("images");
// Job 클래스
class ProcessImage implements ShouldQueue
{
public function handle()
{
// 이미지 처리 로직
}
}
```
## 5. 테스트
```bash
php artisan make:test PostTest
php artisan test
```
```php
class PostTest extends TestCase
{
use RefreshDatabase;
public function test_can_create_post()
{
$user = User::factory()->create();
$response = $this->actingAs($user)
->postJson("/api/posts", [
"title" => "Test Post",
"content" => "Content here",
]);
$response->assertStatus(201);
$this->assertDatabaseHas("posts", ["title" => "Test Post"]);
}
}
```
## 6. 캐싱
```php
// 캐시 사용
$posts = Cache::remember("posts.all", 3600, function () {
return Post::all();
});
// 캐시 삭제
Cache::forget("posts.all");
// 태그 기반 캐시
Cache::tags(["posts"])->flush();
```