Kullanım Durumları ve Uygulama Hizmetleri
İş eylemlerini çerçeveden bağımsız kullanım durumları olarak ifade edin.
Kullanım Durumları ve Uygulama Hizmetleri, CoddyKit'te ücretsiz bir PHP Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, PHP Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. PHP Academy kursu toplamda 4 dersten oluşur.
Bir Kullanım Senaryosu Gerçekte Nedir
Bir kullanım senaryosu (başka adıyla uygulama hizmeti veya etkileşimci), uygulamaya özgü tam olarak tek bir işlemi kapsar: Kullanıcı Kaydet, Sipariş Ver, Aboneliği İptal Et. Tek bir amacı gerçekleştirmek için varlıkları ve bağlantı noktalarını koordine eder. En önemlisi, çerçeveden bağımsızdır: Request yoktur, Response yoktur, global yardımcılar yoktur — yalnızca her yerden çağırabileceğiniz yalın PHP vardır.
Komut ve Sonuç Veri Aktarım Nesneleri
Bir kullanım senaryosu girdi olarak değişmez bir komut DTO'su alır ve bir sonuç DTO'su döndürür. DTO'lar yalnızca veri taşıyan, davranış içermeyen ve biçim dışında doğrulama mantığı barındırmayan yapılardır. Salt okunur özellikler (PHP 8.1+) onları değiştirilmeye karşı korur.
<?php
final class RegisterUserCommand
{
public function __construct(
public readonly string $email,
public readonly string $plainPassword,
) {}
}
final class RegisterUserResult
{
public function __construct(public readonly string $userId) {}
}Uygulama Hizmetinin Gövdesi
Hizmet, komutu alan işlemlerine dönüştürür. Uygulama düzeyindeki düzenlemeyi — benzersizlik denetimleri, kalıcılık ve tanımlayıcıları döndürme işlemlerini — gerçekleştirirken kuralları varlıklara bırakır.
<?php
final class RegisterUser
{
public function __construct(
private Users $users,
private PasswordHasher $hasher,
) {}
public function __invoke(RegisterUserCommand $c): RegisterUserResult {
if ($this->users->existsByEmail($c->email)) {
throw new EmailAlreadyRegistered($c->email);
}
$user = User::register(
UserId::generate(),
new Email($c->email),
$this->hasher->hash($c->plainPassword),
);
$this->users->add($user);
return new RegisterUserResult((string) $user->id());
}
}Mantığı Varlıklarda Tutun
Anemik alan modeline dikkat edin: varlıkların alıcı ve ayarlayıcı yöntemlere indirgenmesi, tüm mantığın hizmetlerde toplanmasıdır. Değişmezlikler varlığa ait olmalıdır. Kullanım senaryosu, iş kurallarından oluşan bir duvar gibi değil, kısa bir amaçlar dizisi gibi okunmalıdır.
<?php
final class User
{
private function __construct(
private UserId $id,
private Email $email,
private string $passwordHash,
private bool $active = false,
) {}
public static function register(UserId $id, Email $e, string $hash): self {
return new self($id, $e, $hash); // invariants enforced here
}
public function activate(): void {
if ($this->active) throw new AlreadyActive();
$this->active = true;
}
public function id(): UserId { return $this->id; }
}İşlem Sınırları
Bir kullanım senaryosu doğal işlem sınırıdır: tek kullanım senaryosu = tek tutarlı iş birimi. Hizmetleri beginTransaction() çağrılarıyla doldurmak yerine, onları işlemsel bir dekoratörle sarın; böylece çekirdek kalıcılık ayrıntılarından bağımsız kalır.
<?php
interface TransactionManager {
public function transactional(callable $work): mixed;
}
final class TransactionalRegisterUser
{
public function __construct(
private RegisterUser $inner,
private TransactionManager $tx,
) {}
public function __invoke(RegisterUserCommand $c): RegisterUserResult {
return $this->tx->transactional(fn() => ($this->inner)($c));
}
}Doğrulama: Nereye Aittir
Doğrulamayı iki katmana ayırın:
- Girdi doğrulaması (biçim, zorunlu alanlar), kullanım senaryosu çalışmadan önce giriş adaptöründe veya özel bir doğrulayıcıda gerçekleştirilir.
- Alan doğrulaması (değişmezlikler, iş kuralları), değer nesnelerinde ve varlıklarda bulunur ve alan istisnaları fırlatır.
Kullanım senaryosu, düzgün biçimlendirilmiş bir girdi varsayar ve anlamı uygular.
<?php
final class Email
{
public function __construct(public readonly string $value) {
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("Invalid email: $value");
}
}
}
try { new Email('nope'); } catch (Throwable $e) { echo $e->getMessage(), PHP_EOL; }
echo (new Email('a@b.com'))->value, PHP_EOL;HTTP Olmadan Çıktı Döndürme
Çerçeveden bağımsız kalırken veri döndürmek için iki yaklaşım:
- Bir sonuç DTO'su döndürmek (basit, eşzamanlı).
- Çıktı bağlantı noktası / sunumlayıcı — kullanım senaryosu sonucu enjekte edilmiş bir çıktı sınırına gönderir; biçimlendirmeye (JSON, HTML, CLI) adaptör karar verir. Böylece yanıtın biçimi bile çekirdeğin dışında kalır.
<?php
interface RegisterUserOutput {
public function present(RegisterUserResult $r): void;
}
final class RegisterUserWithPresenter {
public function __construct(private Users $users, private PasswordHasher $h) {}
public function __invoke(RegisterUserCommand $c, RegisterUserOutput $out): void {
$user = User::register(UserId::generate(), new Email($c->email), $this->h->hash($c->plainPassword));
$this->users->add($user);
$out->present(new RegisterUserResult((string) $user->id()));
}
}Kullanım Senaryolarından Alan Olayları
Kullanım senaryoları genellikle varlıkların ürettiği alan olaylarını kaydeder ve ardından işlem tamamlandıktan sonra bunları dağıtır. Bu, yan etkileri (hoş geldin e-postası gönderme, okuma modelini güncelleme) çekirdek iş akışından ayırır.
<?php
trait RecordsEvents {
private array $events = [];
protected function record(object $e): void { $this->events[] = $e; }
public function releaseEvents(): array {
$e = $this->events; $this->events = []; return $e;
}
}
final class UserRegistered {
public function __construct(public readonly string $userId) {}
}
// Use case calls $user->releaseEvents() and hands them to a dispatcher
echo 'event recorded pattern', PHP_EOL;Her Kullanım Senaryosu İçin Bir Sınıf
On yöntemli çok kapsamlı bir hizmet yerine tek eylemli bir sınıfı (tek bir ortak yöntem, çoğunlukla __invoke) tercih edin. Faydaları:
- Net bir tek sorumluluk ve adlandırma (
CancelSubscription,SubscriptionService::canceldeğil). - Kurucu yalnızca bu işlemin ihtiyaç duyduğu bağımlılıkları enjekte eder.
- Dekoratörlerle (işlem, günlükleme, yetkilendirme) sarmalamak kolaydır.
Birleştirme Kökünde Bağlama
Kullanım senaryosu bağımlılıklarını hiçbir zaman kendisi oluşturmaz; bunu birleştirme kökü yapar. Aşağıda, bir DI konteyneri tanımına yerleştirebileceğiniz elle yapılmış bir bağlama gösterilmiştir.
<?php
$pdo = new PDO('sqlite::memory:');
$users = new PdoUsers($pdo);
$hasher = new BcryptHasher();
$register = new RegisterUser($users, $hasher);
// Decorate with a transaction boundary
$register = new TransactionalRegisterUser($register, new PdoTransactionManager($pdo));
// Driving adapter calls it
$result = $register(new RegisterUserCommand('dev@coddykit.com', 's3cret!'));
echo $result->userId, PHP_EOL;Dekoratörlerle Çapraz Kesen Sorumluluklar
Günlükleme, ölçüm ve yetkilendirme çapraz kesen sorumluluklardır — bunları kullanım senaryosunun gövdesinin dışında tutun. Hizmeti, arayüzünü paylaşan dekoratörlerle sarın; böylece çekirdek iş akışına odaklanırken altyapı sorumlulukları onun çevresinde bir araya gelir.
<?php
interface RegisterUserHandler {
public function __invoke(RegisterUserCommand $c): RegisterUserResult;
}
final class LoggingRegisterUser implements RegisterUserHandler {
public function __construct(
private RegisterUserHandler $inner,
private LoggerInterface $log,
) {}
public function __invoke(RegisterUserCommand $c): RegisterUserResult {
$this->log->info('register.start', ['email' => $c->email]);
$r = ($this->inner)($c);
$this->log->info('register.ok', ['id' => $r->userId]);
return $r;
}
}Hızlı Kontrol
"Bir e-posta benzersiz ve düzgün biçimlendirilmiş olmalıdır" kuralı nerede bulunmalıdır?
Özet
Çerçeveden bağımsız kullanım senaryoları temiz bir uygulama katmanı sağlar:
- Her işlem için, bir komut DTO'su alan ve bir sonuç DTO'su döndüren (veya bir çıktı bağlantı noktasına gönderen) tek bir tek eylemli sınıf kullanılır.
- Varlıklar ve değer nesneleri değişmezliklerin sahibidir; hizmet yalnızca düzenleme yapar — anemik modellerden kaçının.
- Kullanım senaryoları işlem sınırlarıdır; satır içine yazılmış
beginTransactionyerine dekoratörlerle sarılır. - Girdi doğrulamasını (adaptör/VO), alan doğrulamasından (varlıklar) ayırın.
- Alan olayları yan etkileri birbirinden ayırır; bağımlılıkları birleştirme kökü bağlar.
Sıkça Sorulan Sorular
“Kullanım Durumları ve Uygulama Hizmetleri” dersi ücretsiz mi?
Evet — “Kullanım Durumları ve Uygulama Hizmetleri” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve PHP Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. PHP Academy kursu toplamda 4 dersten oluşur.
“Kullanım Durumları ve Uygulama Hizmetleri” dersinde ne öğreneceğim?
İş eylemlerini çerçeveden bağımsız kullanım durumları olarak ifade edin. PHP Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
PHP Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te PHP Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“Kullanım Durumları ve Uygulama Hizmetleri” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu PHP Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her PHP Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Katmanlı Mimariden Temiz Mimariye
- Portlar ve Adaptörler Açıklaması
- Kullanım Durumları ve Uygulama Hizmetleri
- Bağımlılığın Tersine Çevrilmesi Uygulamada