Trait Nedir?

Bir önceki yazımda, yazdığım kodda sürekli tekrar eden kod parçasını Trait içine alıp, güzelleştirdiğimi iddia etmiştim. Peki kodu güzelleştirdiğimi iddia ettiğim bu trait tam olarak nedir?

Kelime anlamına baktığımızda, trait; bir kişinin karakteristik özelliği anlamına gelir. Birebir çevirdiğimizde ise özellik, kişisel özellik diyebiliriz. Programlama özelinde baktığımızda ise, bir sınıfa özellik/yetenek yüklemek için kullanılan kod diyebiliriz.

PHP’de bir sınıf, yalnızca bir üst sınıfa sahip olabilir. Daha anlaşılır bir deyişle, “bir sınıf yalnızca tek bir sınıftan türetilebilir(extend edilebilir)”. Sınıftan türetme işlemini, genellikle türetilen sınıfın özelliklerini(fonksiyonların/methodlarını/değişkenlerini) kullanabilmek için yaparız.

<?php

class Admin extends User {}

class Admin extends User, Human {} //böyle bir kullanım yok

Fakat zaman zaman yazdığımız sınıfın, birden fazla sınıfın özelliklerine sahip olması gerektiğini görürüz. Yukarıdaki örnekte gördüğümüz üzre, Admin sınıfımız User sınıfından türetilmiş. User’ın tüm özelliklerini kullanabileceğiz demektir. Fakat aynı zamanda Human sınıfının da özelliklerine sahip olmasını istiyoruz. İkinci satırdaki kullanım mümkün değil.

PHP 5.4 ile hayatımıza dahil olan traitler, bu duruma bir nebze çözüm olabilmektedir. Tabi tek amacı buna çözüm olmak değildir. Aynı zamanda kod tekrarının önüne geçmek konusunda bize oldukça yardımcı olur ki, bir önceki yazımda Trait kullanarak tam olarak bunu hedeflemiştim.

Traitlere bir bakış atalım:

<?php

trait ValidatesRequests {
   
    public function validate($data)
    {
        //parametre olarak gönderilen veriyi burada validate edelim.
    }

}

Bir trait, abstract class gibi işlem görür. Yani bir traitten yeni bir obje oluşturamazsınız. new ValidatesRequests() işe yaramaz. Traitleri bir sınıfı içerisinde ise, Use keywordu ile kullanırız.

<?php 

class BilmemneController {
 
    use ValidatesRequests;

    public function deneme()
    {
         $data = ['test']
         $this->validate($data);
    }

}

Yukarıdaki örnekte açıkça görüleceği gibi, ValidatesRequests traitini use ile dahil ettik. Ve deneme fonksiyonumuz içinde, traitte tanımladığımız validate methodunu kullanabilir duruma geldik.

Çalışma mantığını ise kopyala yapıştır gibi düşünebiliriz. Traiti sınıfa dahil ettiğimiz anda, içerisindeki methodları sanki dahil ettiğimiz sınıfa kopyalayıp yapıştırıyormuş gibi düşünün. Örneğin bu validate methodunu 5 controller dosyasında kullanacağımızı varsayalım.

Her bir dosyaya aynı methodu kopyalamak yerine, bu 5 sınıfa traiti dahil ediyoruz. Böylece kod tekrarının önüne geçiyoruz. Ve tabii ki yazdığımız kodun bakımı/tekrar çok daha kolay oluyor.

Traitlerin isimlendirilmesi

Genelde bu tarz bir paragraf göremezsiniz fakat ben oldukça önemsiyorum. Trait kullanımı Laravel’de yoğun ve bence Laravel isimlendirme konusunda oldukça başarılı. Traitlerin karakteristik/kişisel özellik anlamında geldiğini söylemiştik. Trait, kullanılan sınıfa yeni özellikler katar. Laravel’in Controller örneğine bakalım. 2 trait kullanılıyor:
use AuthorizesRequests, ValidatesRequests;
Bir controllera bu 2 traiti dahil ettiğimizde insan dilinde(ama türkçe değil) şu cümleleri kurabiliyoruz:

“Bu controller, requestleri(istekleri) authorize eder(yetkilerini onaylar).”
“Bu controller, requestleri(isteklerin) validate eder(geçerliliğini kontrol eder).”

Bu iki traiti detaylıca incelediğimizde birisinde authorization ile ilgili methodların, diğerinde ise validation ile ilgili methodların bulunduğunu görürsünüz. Yazılımda en zor şeylerden birisi isimlendirmedir, malumunuz. Ne kadar insan diline yakın isimler verebilirseniz, o kadar başarılı olursunuz (bence).

Sevgiyle kalın.

<?php
trait Love()
{
    public function love(Human $human) {

    }
}

trait Hate()
{
    public function hate(Human $human) {

    }
}

class Human()
{
    use Love;
}

 

4 Comments

  1. Hiç haberim yoktu bundan, hatta bıkkınlık düzeyine geldiğim bir durumdu biliyor musun? İki ayrı sınıfta aynı işi yapan bir işlemim var.. Güncelleme yaptığımda birini diğerini güncellemeyi unutuyorum genelde ve hep sonradan farkedip başıma dert oluyordu..

    Üzerine giderim bu Trait’in

    • Ben de ilk gördüğüm zamanlarda çok mesafeli yaklaşmıştım. Halbuki çok pratik birşeymiş. Kullandıkça sevdim.

  2. Anlatımınız çok güzel hocam. Laravel dökümantasyonunda sizin yazılarınızdan yararlanılmalı bence.

Leave a Reply to shibbyCancel Reply

Your email address will not be published. Required fields are marked *