PHP'de Tasarım Modellerine Giriş (ve Drupal'dan yararlanarak)

Yayınlanan: 2022-07-05

Akıllı biri bir keresinde şöyle demişti - İyi kodlayıcılar kodu, harika yeniden kullanım.
Geliştiriciler genellikle kendilerini aynı tür sorunları tekrar tekrar çözerken bulurlar. Kodu yeniden kullanmak, gerçekten yazılım geliştirmenin kutsal kâsesidir. Ayrıca, iyi yapılandırılmış kod okumayı (ve yazmayı) kim sevmez? Girin - PHP'de desenler tasarlayın.

PHP Tasarım kalıplarının geliştiriciler için son derece yararlı olduğu kanıtlanmıştır ve büyük bir problem çözücüdür. En iyi uygulamaları takip etmek, verimli kod yazmak için çok önemlidir. PHP Tasarım desenleri, artık Drupal 9 projelerinde de kullanılan bir Nesne Yönelimli Programlama (OOP) konseptidir. Drupal'ın sürüm 8'den bu yana modern PHP ve OOP kavramlarını benimsemesiyle, daha temiz ve daha sağlam programlama için tasarım kalıplarından yararlanılabilir. Bu yazıda, PHP'de yaygın olarak kullanılan birkaç tasarım modelini ve Drupal'da bağımlılık enjeksiyonları gibi kalıpların nasıl kullanılacağını tartışacağız.

Hala Drupal 7'de mi? Drupal 9 geçişine hazırlanmanıza yardımcı olacak kullanışlı bir kontrol listesi bulmak için bu makaleyi okuyun.

PHP'de Tasarım Kalıpları

PHP'de Tasarım Kalıpları Nelerdir?

Yazılım mühendisliğinde bir Tasarım Modeli, yazılım Tasarımında yaygın olarak ortaya çıkan soruna genel tekrarlanabilir bir çözümdür. İyi Nesne yönelimli tasarımlar yeniden kullanılabilir, sürdürülebilir ve genişletilebilir olmalıdır ve PHP'deki Tasarım Kalıpları bunu yaparken çok yardımcı olabilir. Yalnızca sorunları çözmeye yardımcı olmakla kalmaz, aynı zamanda ortak zorluklara yönelik en uygun yolu ifade eder.

PHP Tasarım Modellerini neden kullanmalısınız?

PHP'de tasarım kalıplarını uygulamanın en önemli faydalarından bazıları şunlardır:

  • PHP Tasarım kalıpları, geliştirme sırasında karşılaşılan tekrarlayan sorunların çözülmesine yardımcı olur
  • PHP'de tasarım kalıplarını kullanmak, tasarımcılar ve geliştiriciler arasındaki iletişimi daha verimli hale getirir
  • Tasarım kalıplarını takip ettiği için diğer geliştiricilerin kodunuzu anlayacağından emin olabilirsiniz.
  • En iyi uygulamaları takip etmek, daha sağlam uygulamalar oluşturmaya yardımcı olur
  • Geliştirmeyi daha hızlı ve daha kolay hale getirmeye yardımcı olur

PHP'de Yaygın Olarak Kullanılan Tasarım Modelleri

Tasarım Modelleri, benzer sorunları çözmek için çeşitli durumlarda kullanılabilir. Genel olarak üç türe ayrılabilen 30'dan fazla tasarım deseni vardır - Yaratıcı, Yapısal ve Davranışsal desenler.

Yaratılış Kalıpları: Nesne oluşturma mekanizmalarında, onları uygulayan sistemden ayrılabilen nesneler oluşturmak için kullanılan tasarım kalıpları.

Yapısal Modeller: Bu, varlıklar arasındaki ilişkileri gerçekleştirmenin basit yollarını belirleyerek tasarımı kolaylaştırır.

Davranış Kalıpları: Nesneler arasındaki ilişkileri, sorumlulukları ve algoritmaları yönetmek için kullanılırlar.

Fabrika Modeli

Bir nesne oluşturmak için bir fabrika modeli kullanılır. Bu doğru - bir nesne oluşturun ve bir nesne oluşturmayın. Nesneyi oluşturduğumuzda, önce onu oluşturur ve ardından başlatırız. Genellikle belirli bir mantığın uygulanması ve birden çok adımın gerçekleştirilmesi gerekir. Bununla, tüm bunları tek bir yerde bulundurmak ve aynı şekilde yeni bir nesneye ihtiyaç duyduğunuzda yeniden kullanmak mantıklıdır. Temel olarak, fabrika modelinin kullanımı budur.
Fabrikamız için bir arayüze sahip olmak ve kodumuzun beton bir fabrikaya değil de buna bağlı olması harika bir fikir.

 interface FamilyFactoryInterface { public function create() : Family }

Ardından, fabrika arabirimini aşağıdaki sınıfla uygulayın:

 class FamilyFactory implements FamilyFactoryInterface { public function create() : Family { $family = new Family(); // initialize your family return $family; } }

Adaptör Modeli

Bağdaştırıcı Tasarım Modelinde bir sınıf, bir sınıfın arabirimini başka bir sınıfa dönüştürür. Bu örnekte, getTitle() ve getAuthor() yöntemlerine sahip bir TextBook sınıfımız var. İstemci bir getTitleAndAuthor() yöntemi bekler. SimpleBook'u demoAdapter'a "uyarlamak" için, TextBook örneğini alan ve kendi getTitleAndAuthor yönteminde TextBook getTitle() ve getAuthor() yöntemlerini kullanan BookAdapter adlı bir bağdaştırıcı sınıfımız var.

 <?php class TextBook { private $title; private $author; function __construct($title_in, $author_in) { $this->title = $title_in; $this->author = $author_in; } function getTitle() { return $this->title; } function getAuthor() { return $this->author; } } class BookAdapter { private $book; function __construct(TextBook $book_in) { $this->book = $book_in; } function getTitleAndAuthors() { return $this->book->getTitle().' by '.$this->book->getAuthor(); } } // client writeln('BEGIN TESTING ADAPTER PATTERN'); writeln(''); $book = new TextBook("Gamma, Helm, Johnson, and Vlissides", "Design Patterns"); $bookAdapter = new BookAdapter($book); writeln('Author and Title: '.$bookAdapter->getTitleAndAuthor()); writeln(''); writeln('END TESTING ADAPTER PATTERN'); function writeln($line_in) { echo $line_in."<br/>"; } ?>

PHP Tekil Kalıbı

Bir sınıfın örneğini tek bir nesneyle sınırlamak için PHP'de bir tekli desen kullanılır. Bu, sistem genelinde yalnızca bir nesneye ihtiyaç duyulduğunda faydalı olabilir. Web uygulamaları tasarlarken belirli bir sınıfın yalnızca bir örneğine erişime izin vermek mantıklıdır. Singleton model sınıfından nesnelerin açıkça oluşturulmasını önlemek için özel bir kurucu kullanılır.

 <?php class Singleton { public static function getInstance() { static $instance = null; if (null === $instance) { $instance = new static(); } return $instance; } protected function __construct() { } private function __clone() { } private function __wakeup() { } } class SingletonChild extends Singleton { } $obj = Singleton::getInstance(); var_dump($obj === Singleton::getInstance()); $obj2 = SingletonChild::getInstance(); var_dump($obj2 === Singleton::getInstance()); var_dump($obj2 === SingletonChild::getInstance()); ?>

PHP'de Gözlemci Modeli

PHP Observer modeli, sistemin geri kalanını belirli yerlerdeki belirli olaylar hakkında uyarmak için kullanılır.
Örneğin, eleştirmenlere film göstermek için bir Tiyatro oluşturmamız gerekiyorsa. Theatre sınıfını mevcut metodla tanımlıyoruz. Filmi sunmadan önce eleştirmenlerin cep telefonlarına mesaj göndermek istiyoruz. Ardından filmin ortasında eleştirmenlere bir ara verebilmek için filmi 5 dakika durdurmak istiyoruz. Son olarak, filmin bitiminden sonra eleştirmenlerden yanıtlarını bırakmalarını istiyoruz. Bu nedenle, PHP için gözlemci modelinde, gözlemci nesnesi yalnızca durum değiştiğinde bilgilendirilir.

Kod böyle görünüyor -

 class Theater { public function current(Movie $movie) : void { $critics = $movie->getCritics(); $this->message->send($critics, '...'); $movie->play(); $movie->pause(5); $this->progress->interval($critics) $movie->end(); $this->response->request($critics); } }

PHP için Dekoratör Kalıbı

Dekoratör deseni, çalışma zamanında bir nesnenin karakterini değiştirmek istediğinizde ve bununla birlikte gereksiz mirasları ve sınıf sayısını azaltmak istediğinizde kullanılır. Peki, örneklerle açıklanabilir. Diyelim ki Sofa ve Bed sınıflarımız var ve ikisi de SleeperInterface'i uyguluyor.

 interface SleeprInterface { public function sleep() : void; } class Sofa implements SleeperInterface { public function sleep() : void { // sleeps on sofa } } class Bed implements SleeperInterface { public function sleep() : void { // sleeps on bed } }

Hem kanepeler hem de yataklar aynı uyuma davranışına sahiptir. Artık, kullanıcılara kanepelerde veya yataklarda uyurken uyku takibini bildirecek ek işlevselliğe sahip başka kanepe ve yataklara ihtiyacımız var. Kalıtım ile bu sorunu şu şekilde çözebiliriz:

 class SmartSofa extends Sofa { public function sleep() : void { parent::sleep(); $this->sleepHours(); } } class SmartBed extends Window { public function sleep() : void { parent::sleep(); $this->sleepHours(); } }


Şimdi toplam 4 sınıfımız var. Ancak bu sorunu 3 class ile ancak Decorator pattern ile çözebildik. İşte nasıl:

 class SmartSleeper implements SleeperInterface { private $sleeper; public function __construct(SleeperInterface $sleeper) { $this->sleeper = $sleeper; } public function sleep() : void { $this->sleeper->sleep(); $this->sleepHours(); } } $sofa = new Sofa(); $bed = new Bed(); $smartSofa = new SmartSleeper($sofa); $smartBed = new SmartSleeper($bed);

Burada, bir proxy gibi davranan ancak üzerinde ekstra bir işlevsellik bulunan yeni bir travers türünü tanıttık.

Drupal 9'da Tasarım Modellerinden Yararlanma

Drupal 9'dan önce Drupal içinde zaten oluşturulmuş birçok tasarım deseni varken, şimdi daha önce kullanılamayan çok daha fazla desen var. Bu yeni kalıplardan bazıları eski kalıpların yerini tamamen alırken, diğerleri Drupal 9'a bazı yeni özellikler getiriyor.
Drupal 9'da kullanılan tasarım desenleri şunları içerir:

  • Nesneye Yönelik Programlama Modeli (OOP)
  • Bağımlılık Enjeksiyonları
  • Fabrika Modeli
  • Tekli Desen

OOP gerçekten tek bir kalıp değil, sadece tasarım kalıplarının ötesine geçen, kodu kavramsallaştırmanın ve yapılandırmanın tamamen radikal bir yoludur. Drupal 9'da kullanılanlar da dahil olmak üzere, günümüzde kullanılan birçok popüler yazılım tasarım modelinin temelidir. Drupal 7'de tanıtıldı, ancak yaygın olarak kullanılmadı ve gerekli değildi. Drupal 9'daki durum artık farklı, yaygın olarak kullanılıyor ve gerekli.

Bağımlılık Enjeksiyonları

Bağımlılık ekleme, sabit kodlanmış bağımlılıkları kaldırmanıza ve bunları çalışma zamanında veya derleme zamanında değiştirmenize olanak tanıyan bir yazılım tasarım modelidir. Bağımlılık enjeksiyonu eklemek kolaydır ve mevcut kodunuzla karışmaz. Drupal 8, yeniden kullanılabilir işlevleri ayırmak için hizmet kavramını tanıttı. core.services.yml , Drupal 9'daki bir bağımlılık ekleme örneğidir. Daha önce PHP'de Factory Pattern ve Singleton Pattern'den bahsetmiştik.

Şu anda Drupal'da, hizmetlere erişmek ve bunları kullanmak için bağımlılık enjeksiyonu tercih edilen yöntemdir ve mümkün olduğunda kullanılmalıdır. Hizmetler, global hizmetler kapsayıcısına çağrı yapmak yerine, bir kurucuya argüman olarak iletilir veya ayarlayıcı yöntemlerle enjekte edilir. Bir nesnenin bağlı olduğu hizmetleri açıkça iletmek, bağımlılık enjeksiyonu olarak adlandırılır . Bazı durumlarda, bağımlılıklar sınıf oluşturucularında açıkça iletilir.

Drupal çekirdeğinde mevcut tüm hizmetleri bulmak için bu sayfaya göz atın. Hizmetler hakkında daha fazla bilgiyi Drupal belgelerinde okuyabilirsiniz.

ID=1 olan düğümün başlığını almak için örnek olarak 'entity_type.manager' servisini ele alalım. Özel servisimize enjekte etmek için, servis adını almamız ve aşağıda gösterildiği gibi my_module_name.services.yml dosyasında bir argüman olarak geçirmemiz gerekiyor:

my_module_name.services.yml

 services: my_module_name.helper: class: Drupal\my_module_name\MyModuleHelper arguments: ['@entity_type.manager']

ve ardından hizmet sınıfımızda hizmeti _ _construct yönteminde almamız ve aşağıdaki gibi bir değişkende saklamamız gerekir:

MyModuleHelper.php

 <?php namespace Drupal\my_module_name; use Drupal\Core\Entity\EntityTypeManagerInterface; /** * MyModuleHelper is a simple example of a Drupal 9 service. */ class MyModuleHelper { /** * The entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * Part of the DependencyInjection magic happening here. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. */ public function __construct(EntityTypeManagerInterface $entity_type_manager) { $this->entityTypeManager = $entity_type_manager; } /** * Returns a title for node_id = 1. */ public function getFirstNodeTitle() { $node = $this->entityTypeManager->getStorage('node')->load(1); return $node->getTitle(); } }

ve sonra varlık türü yöneticisi hizmetini kullanabilir ve getFirstNodeTitle yönteminde nid=1 olan düğümün başlığını alabiliriz.

Makaleyi güncellememize yardımcı olan görüşleri için Ankitha Shetty'ye çok teşekkürler.