PHP'de Trait Kullanımı

PHP
Trait, PHP 5.4.0 ile gelmiş, nesneye yönelik programlama konseptlerinden birisidir. Başka dillerde de trait kullanımı olmakla beraber, Perl(roles), Scala(trait), Ruby(modules), birçok kişi hala ne olduğunu tam olarak bilmemekte ve yeteri kadar kullanmamaktadır.

Trait'in basit bir tanımını yapacak olursam, interface gibi, bir class'ın(sınıfın) neler yapabileceğini belirten, aynı zamanda da, class gibi, yöntemleri, implemented (uygulanmış) şekilde, direkt sağlayabilen kısmi sınıf uygulaması diyebilirim.

Ne gibi durumlarda trait kullanmanız gerektiğini bir örnekle anlatayım. Düşünün ki User ve Article adında birbiriyle alakasız, amaçları farklı olan iki ayrı class'ınız var. Her ikisinde de slug(User için: Burak Özdemir -> burak-ozdemir, Article için: PHP'de Trait Kullanımı -> php-de-trait-kullanimi) üretmeniz lazım. Slug oluşturma yöntemini, nesneye yönelik programlama konseptleriyle gerçekleyecek olursanız, temel olarak üç farklı yönteminiz var.

llk başta aklınıza gelen yöntem, muhtemelen, abstract bir parent class oluşturup, slug oluşturma yöntemini, abstract class'ınız içerisinde uygulayıp, ondan inheritance(kalıtım) ile User ve Article class'larını oluşturmak üzerine olur. Bu her ne kadar problemi çözse de, kötü bir tasarım yöntemi olup, iki alakasız class'ın ancestor'ını(atasını) birbirine bağlayarak, birbirleriyle alakasız bir ilişki kurmuş olursunuz.

İkinci yöntem, Slug adında bir interface oluşturup, User ve Article classlarınızın bu interace'i uygulamaları üzerine kurulu olur. Ancak, interface'i bildiğiniz üzere, hem User, hem de Article class'larında, slug oluşturma yöntemini, ayrı ayrı oluşturarak uygulamanız gerekir ki bu da, kendimizi tekrarlamamak adına(DRY) pek iyi bir çözüm değil.

Üçüncü ve bana göre en iyi yöntem ise trait kullanmak üzerine kurulu. Nasıl uygulayabileceğiniz de alttaki gibi, slug oluşturma işleminin nasıl yapıldığını, basit görünmesi için eklemedim.
trait Slug {

    protected $slug = "";

    public function __construct($string)
    {
        echo $this->sluggify($string);
    }

    protected function sluggify($string)
    {
        // başka işlemler
        $this->slug = "Slug:" . $string . "\n";
        return $this->slug;
    }

}

class Article {
    use Slug;
}

class User {
    use Slug;
}

$article = new Article("PHP'de Trait Kullanımı");
$user = new User("Burak Özdemir");
Eğer slug işlemini kodunuz içerisinde gerçeklerseniz alttaki gibi bir çıktı alacaksınız.
Slug:php-de-trait-kullanimi
Slug:burak-ozdemir
Burada gerçekleşen olay aslında gayet basit. Trait içerisindeki yöntem ve değişkenler, use ile trait'i kullandığınız classlara, compile(derleme) anında aynen aktarılıyor. Böylece hem class'larınızı herhangi bir şekilde birbirine bağlamamış oluyorsunuz, hem de bu örnekteki gibi alakasız iki ayrı sınıfın ortak kullandığı bir yöntemi, kendinizi tekrar etmeden uygulayabiliyorsunuz.

Kısacası, ne zaman ki, birbirleriyle bağlantısı olamayacak kadar alakasız iki ya da daha fazla class'ınızın uygulaması gereken aynı yöntem veya yöntemler olduğunda, aklınıza ilk gelen trait kullanımı olmalıdır.