Sanırım kabul edilen İyi / En İyi uygulamaları öğrenmek için bir süredir Özellikleri olan dillere bakmak gerekecek. Özellik hakkındaki şu anki fikrim, onları yalnızca aynı işlevi paylaşan diğer sınıflarda çoğaltmanız gereken kod için kullanmanız gerektiğidir.
Bir Logger özelliği örneği:
interface Logger
{
public function log($message, $level);
}
class DemoLogger implements Logger
{
public function log($message, $level)
{
echo "Logged message: $message with level $level", PHP_EOL;
}
}
trait Loggable
{
protected $logger;
public function setLogger(Logger $logger)
{
$this->logger = $logger;
}
public function log($message, $level)
{
$this->logger->log($message, $level);
}
}
class Foo implements Logger
{
use Loggable;
}
Ve sonra yaparsın ( demo )
$foo = new Foo;
$foo->setLogger(new DemoLogger);
$foo->log('It works', 1);
Nitelikleri kullanırken dikkate alınması gereken önemli şey, bunların gerçekten sınıfa kopyalanan kod parçaları olmalarıdır. Bu, örneğin yöntemlerin görünürlüğünü değiştirmeye çalıştığınızda kolayca çatışmalara yol açabilir, örn.
trait T {
protected function foo() {}
}
class A {
public function foo() {}
}
class B extends A
{
use T;
}
Yukarıdakiler bir hatayla ( demo ) sonuçlanacaktır . Aynı şekilde, kullanım sınıfında zaten bildirilmiş olan özellikte bildirilen herhangi bir yöntem, sınıfa kopyalanmayacaktır, örn.
trait T {
public function foo() {
return 1;
}
}
class A {
use T;
public function foo() {
return 2;
}
}
$a = new A;
echo $a->foo();
2 ( demo ) yazdıracaktır . Bunlar, hataları bulmayı zorlaştırdığı için kaçınmak isteyeceğiniz şeylerdir. Ayrıca, onu kullanan sınıfın özellikleri veya yöntemleri üzerinde çalışan özelliklere şeyler koymaktan da kaçınmak isteyeceksiniz, örn.
class A
{
use T;
protected $prop = 1;
protected function getProp() {
return $this->prop;
}
}
trait T
{
public function foo()
{
return $this->getProp();
}
}
$a = new A;
echo $a->foo();
çalışır ( demo ) ancak şimdi özellik A ile yakından ilişkilidir ve yatay yeniden kullanım fikri tamamen kaybolur.
Arayüz Ayrımı İlkesini izlediğinizde birçok küçük sınıf ve arayüze sahip olacaksınız. Bu, Traits'i bahsettiğiniz şeyler için ideal bir aday yapar, örneğin endişeleri kesiştirmek , ancak nesneleri oluşturmak için değil (yapısal anlamda). Yukarıdaki Logger örneğimizde, özellik tamamen izole edilmiştir. Somut sınıflara bağımlılığı yoktur.
Ortaya çıkan aynı sınıfı elde etmek için toplama / kompozisyon kullanabiliriz (bu sayfada başka bir yerde gösterildiği gibi), ancak toplama / kompozisyon kullanmanın dezavantajı, proxy / temsilci yöntemlerini her sınıfa manuel olarak eklememiz gerekecek olmasıdır. giriş yapabilmek. Özellikler bunu güzel bir şekilde, standart metnini tek bir yerde tutmama ve gerektiğinde onu seçerek uygulamama izin vererek çözüyor.
Not: Özelliklerin PHP'de yeni bir kavram olduğu düşünüldüğünde, yukarıda ifade edilen tüm görüşler değişebilir. Henüz konsepti kendim değerlendirmek için fazla zamanım olmadı. Ama umarım size düşünecek bir şey verecek kadar iyidir.