class Laravel ve SOLID Prensipleri extends Post
@created_at(
"2025-01-14 07:20"
)
**Laravel ve SOLID Prensipleri**
SOLID prensipleri, yazılım geliştirirken daha esnek, okunabilir ve bakımı kolay kod yazmamıza yardımcı olan beş temel prensiptir. Laravel gibi modern framework'lerle bu prensipleri uygulamak çok daha kolay hale gelir.
Bu yazıda, SOLID prensiplerini Laravel uygulamaları üzerinde örneklerle açıklayacağız.
---
### 1. **Single Responsibility Principle (SRP)**
**Bir sınıfın sadece bir sorumluluğu olmalıdır.**
Laravel'de bu prensibi kontrolcüler ve servis sınıflarıyla kolayca uygulayabiliriz. İşlemleri bir kontrolcüye yığmak yerine, özel servis sınıflarına ayırabiliriz.
**Örnek:**
// PostController.php
namespace App\Http\Controllers;
use App\Services\PostService;
class PostController extends Controller
{
private PostService $postService;
public function __construct(PostService $postService)
{
$this->postService = $postService;
}
public function store(Request $request)
{
$this->postService->createPost($request->all());
return response()->json(['message' => 'Post created successfully']);
}
}
// PostService.php
namespace App\Services;
use App\Models\Post;
class PostService
{
public function createPost(array $data)
{
Post::create($data);
}
}
Yukarıdaki örnekte, PostController sadece HTTP isteklerini ele alırken, PostService asıl iş mantığını yürütür. Bu, SRP prensibine uygun bir yapıdır.
---
### 2. **Open/Closed Principle (OCP)**
**Bir sınıf geliştirilmeye açık, değişikliğe kapalı olmalıdır.**
Laravel'de OCP'yi uygulamak için Dependency Injection ve Interface kullanabiliriz.
**Örnek:**
// PostRepositoryInterface.php
namespace App\Repositories;
interface PostRepositoryInterface
{
public function getAllPosts();
}
// EloquentPostRepository.php
namespace App\Repositories;
use App\Models\Post;
class EloquentPostRepository implements PostRepositoryInterface
{
public function getAllPosts()
{
return Post::all();
}
}
// AppServiceProvider.php
use App\Repositories\PostRepositoryInterface;
use App\Repositories\EloquentPostRepository;
public function register()
{
$this->app->bind(PostRepositoryInterface::class, EloquentPostRepository::class);
}
// PostController.php
namespace App\Http\Controllers;
use App\Repositories\PostRepositoryInterface;
class PostController extends Controller
{
private PostRepositoryInterface $postRepository;
public function __construct(PostRepositoryInterface $postRepository)
{
$this->postRepository = $postRepository;
}
public function index()
{
return response()->json($this->postRepository->getAllPosts());
}
}
Burada, `PostRepositoryInterface` sayesinde, Eloquent şeklinde bir repository'yi kullandığımız için kodumuz değişmeden bambaşka bir veri kaynağına (örneğin, bir API'ye) geçebiliriz.
---
### 3. **Liskov Substitution Principle (LSP)**
**Türetilen sınıflar, temel sınıfın yerine geçebilir.**
Laravel'de bu prensip, Interface veya Abstract class kullanıldığında öne çıkar.
**Örnek:**
// NotificationInterface.php
namespace App\Notifications;
interface NotificationInterface
{
public function send(string $message);
}
// EmailNotification.php
namespace App\Notifications;
class EmailNotification implements NotificationInterface
{
public function send(string $message)
{
// E-posta gönderme mantığı
}
}
// SmsNotification.php
namespace App\Notifications;
class SmsNotification implements NotificationInterface
{
public function send(string $message)
{
// SMS gönderme mantığı
}
}
// NotificationService.php
namespace App\Services;
use App\Notifications\NotificationInterface;
class NotificationService
{
private NotificationInterface $notifier;
public function __construct(NotificationInterface $notifier)
{
$this->notifier = $notifier;
}
public function notify(string $message)
{
$this->notifier->send($message);
}
}
Email veya SMS bildirimleri arasında geçiş yapmak için `NotificationService`'i değiştirmeniz gerekmez.
---
### 4. **Interface Segregation Principle (ISP)**
**Bir sınıf, kullanmadığı metodlara zorlanmamalıdır.**
Karmaşık ve gereksiz metodları bir interface'de birleştirmek yerine, birden fazla özelleşmiş interface oluşturun.
**Örnek:**
// PaymentInterface.php
namespace App\Interfaces;
interface PaymentInterface
{
public function processPayment(float $amount);
}
// RefundInterface.php
namespace App\Interfaces;
interface RefundInterface
{
public function processRefund(float $amount);
}
// PaymentService.php
namespace App\Services;
use App\Interfaces\PaymentInterface;
class PaymentService implements PaymentInterface
{
public function processPayment(float $amount)
{
// Ödeme işlemi
}
}
Burada, geri ödeme (“refund”) yapmak istemeyen bir sınıf, RefundInterface'i implemente etmek zorunda değildir.
---
### 5. **Dependency Inversion Principle (DIP)**
**Yüksek seviye modüller, düşük seviye modüllere bağlı olmamalı, her ikisi de soyutlamalara bağlı olmalıdır.**
Laravel'de Service Container ve Dependency Injection bu prensibin uygulanmasını sağlar.
**Örnek:**
// PaymentInterface.php
namespace App\Interfaces;
interface PaymentInterface
{
public function pay(float $amount);
}
// StripePayment.php
namespace App\Services;
use App\Interfaces\PaymentInterface;
class StripePayment implements PaymentInterface
{
public function pay(float $amount)
{
// Stripe ile ödeme
}
}
// PayPalPayment.php
namespace App\Services;
use App\Interfaces\PaymentInterface;
class PayPalPayment implements PaymentInterface
{
public function pay(float $amount)
{
// PayPal ile ödeme
}
}
// PaymentController.php
namespace App\Http\Controllers;
use App\Interfaces\PaymentInterface;
class PaymentController extends Controller
{
private PaymentInterface $paymentService;
public function __construct(PaymentInterface $paymentService)
{
$this->paymentService = $paymentService;
}
public function pay(Request $request)
{
$this->paymentService->pay($request->amount);
}
}
`AppServiceProvider` ile hangi ödeme servisinin kullanılacağını belirleyebilirsiniz:
$this->app->bind(PaymentInterface::class, StripePayment::class);
Bu sayede PaymentController, spesifik bir ödeme sınıfına bağlı kalmaz.
---
### Sonuç
SOLID prensipleri, Laravel gibi framework'lerde kolayca uygulanabilir ve uzun vadede projelerinizin ölçeklenebilirliğini arttırır. Bu prensipleri uygulayarak daha temiz ve sürebilir bir kod yapısı oluşturabilirsiniz.