İçeriğe geç
Muhammet Şafak
Diller 3 dk okuma

MVC'yi gerçekten anlamak: controller'ı şişirmeyi bırakmak

MVC'nin her katmanının gerçekte ne iş yaptığını ve controller'ı nasıl ince tutabileceğinizi anlatıyorum.


Bir süre sonra yazdığım controller dosyalarına bakıp “bu ne zaman bu kadar büyüdü?” diye soruyordum kendime. Veritabanı sorguları, iş mantığı, format dönüşümleri, e-posta gönderimi — hepsi aynı metodun içinde, iç içe geçmiş durumdaydı. MVC (Model-View-Controller) kalıbını kullandığımı sanıyordum; ama aslında controller’ı her şeyi yapan tek bir yer haline getirmiştim.

Bu yazıda MVC’nin üç katmanının gerçekte ne anlama geldiğini, sorumlulukları nereye taşımak gerektiğini anlatmaya çalışacağım. Konuya birkaç kez bakmam ve gerçek bir projede bunun acısını yaşamam gerekti; umarım sizin için daha kısa bir yol olur.

MVC nedir ve her katman ne yapar?

MVC (Model-View-Controller), uygulamayı üç ayrı katmana bölen bir yazılım mimarisi kalıbıdır.

  • Model: Uygulamanın verisi ve iş kurallarıdır. Veritabanıyla konuşur, veriyi doğrular, hesaplamaları yapar.
  • View (Görünüm): Kullanıcıya gösterilecek çıktıyı üretir. HTML, JSON, XML — ne olursa olsun, yalnızca sunum işi yapar.
  • Controller (Denetleyici): İstek ile yanıt arasındaki köprüdür. Gelen isteği alır, uygun model metodunu çağırır, sonucu view’a aktarır.

Kağıt üzerinde temiz görünüyor. Sorun, controller’ın “her şeyi bilen” bir yer haline gelmesinin çok kolay olmasında.

Controller neyi yapmamalı?

Bir HTTP isteği geldiğinde controller şunları yapmamalıdır:

  • Doğrudan SQL sorgusu çalıştırmak
  • İş mantığı kararları vermek (“eğer kullanıcı premium üyeyse şunu yap”)
  • E-posta ya da bildirim göndermek
  • Karmaşık veri dönüşümleri yapmak

Bunları controller içinde yazıp çalıştırmak mümkün; PHP size durdurmaz. Ama birkaç ay sonra o metodu tekrar açtığınızda 150 satır kod sizi karşılar ve hangisinin ne yaptığını çözmek için ciddi zaman harcarsınız.

Şişirilmiş bir controller metodu şuna benzer:

public function store(Request $request)
{
    // Doğrulama
    if (empty($request->input('email'))) {
        return redirect()->back()->with('error', 'E-posta zorunlu.');
    }

    // Veritabanına yazma
    $user = new User();
    $user->name  = $request->input('name');
    $user->email = $request->input('email');
    $user->save();

    // E-posta gönderme
    mail($user->email, 'Hoş geldiniz', 'Kayıt oldunuz.');

    return redirect('/dashboard');
}

Üç farklı sorumluluk tek bir metodun içinde. Doğrulama değişirse bu metodu açmak gerekiyor. E-posta şablonu değişirse yine buraya geliyor. Kullanıcı kayıt mantığı değişirse yine burada.

Model katmanına ne taşınmalı?

Kullanıcıyla ilgili tüm iş mantığı model tarafında durmalıdır. Basit bir örnek:

class User extends Model
{
    public static function kaydet(array $veri): self
    {
        $user        = new self();
        $user->name  = $veri['name'];
        $user->email = $veri['email'];
        $user->save();

        return $user;
    }

    public function hosGeldinGonder(): void
    {
        mail($this->email, 'Hoş geldiniz', 'Kayıt oldunuz.');
    }
}

Bu sayede controller sadece koordinasyon yapar:

public function store(Request $request)
{
    $user = User::kaydet($request->only('name', 'email'));
    $user->hosGeldinGonder();

    return redirect('/dashboard');
}

Controller artık ne yapıldığını değil, hangi sırayla çağrı yapıldığını gösteriyor. Okumak çok daha kolay.

View katmanını karıştırmamak

Aynı karışıklık view tarafında da olabilir. View içinde iş mantığı kararları vermek — “eğer kullanıcı admin ise bu butonu göster” gibi koşulların uzadığı şablonlar — yönetilmesi güç bir hal alır.

View yalnızca şunu sormalıdır: “Bana verilen veriyi nasıl göstereyim?” Hangi verinin gönderileceğine karar vermek controller’ın işidir. Verinin nasıl hesaplandığı ise model’in.

Küçük metodlar, tek sorumluluk

Controller metodlarını küçük tutmanın pratik bir yolu, her metodun yalnızca bir işi yapmasını sağlamaktır. Kayıt, güncelleme, silme — her biri ayrı metod, her metod birkaç satır. Bir metodun satır sayısı çok artmaya başladığında bu, bir sorunun habercisi olarak okunabilir.

Bunu uygulamaya başladığımda ilk etapta “nereye koyacağım bunu?” diye zorlandım. Cevap çoğunlukla modelde ya da ayrı bir yardımcı (helper) sınıfta oldu. Zamanla nereye bakacağımı ezberledim ve kodu takip etmek çok kolaylaştı.

MVC bir kural değil, bir kılavuzdur. Ama kılavuzun amacını anlamak, onu körce uygulamaktan çok daha faydalı.

Etiketler: #PHP
Paylaş:

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi