Model
Uygulamamız büyüdükçe, benzer veritabanı işlemlerini çeşitli yerlerde ve çeşitli presenter'larda yapmamız
gerektiğini kısa sürede fark ederiz; örneğin en son yayımlanan gönderileri almak. Uygulamamızı geliştirir, örneğin
gönderilere taslak olup olmadıklarını gösteren bir bayrak eklersek, uygulamamızda gönderilerin veritabanından alındığı
tüm yerleri de gözden geçirip yalnızca taslak olmayan gönderilerin seçilmesini sağlayacak bir where koşulu
eklememiz gerekir.
Bu noktada doğrudan veritabanıyla çalışmak yetersizleşir ve yayımlanmış gönderileri döndüren yeni bir metot kullanmak daha akıllıca olur. Sonradan başka bir koşul eklediğimizde de (örneğin ileri tarihli gönderileri göstermemek) kodumuzu yalnızca tek bir yerde düzenleriz.
Metodu PostFacade sınıfına koyacak ve ona getPublicArticles() adını vereceğiz.
Gönderilerimizi üstlenecek PostFacade model sınıfımızı app/Model/ dizininde
oluşturacağız:
<?php
namespace App\Model;
use Nette;
final class PostFacade
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
public function getPublicArticles()
{
return $this->database
->table('posts')
->where('created_at < ', new \DateTime)
->order('created_at DESC');
}
}
Sınıfta, veritabanı Explorer nesnesini yapıcı üzerinden isteriz. Bu, DI container'ın gücünden yararlanır.
HomePresenter sınıfına geçeceğiz; onu, Nette\Database\Explorer bağımlılığından kurtulup
yerine yeni sınıfımıza yeni bir bağımlılık koyarak değiştireceğiz.
<?php
namespace App\Presentation\Home;
use App\Model\PostFacade;
use Nette;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private PostFacade $facade,
) {
}
public function renderDefault(): void
{
$this->template->posts = $this->facade
->getPublicArticles()
->limit(5);
}
}
use bölümünde App\Model\PostFacade var, dolayısıyla PHP kodundaki yazımı
PostFacade olarak kısaltabiliriz. Bu nesneyi yapıcıda ister, $facade özelliğine yazar ve
renderDefault metodunda kullanırız.
Son adım, DI container'a bu nesneyi üretmeyi öğretmektir. Bu genellikle, config/services.neon dosyasının
services bölümüne tam sınıf adını ve yapıcı parametrelerini belirten bir öğe eklenerek yapılır. Bu, onu
kaydeder ve nesneye o zaman servis denir. Autowiring sihri sayesinde yapıcı parametrelerini genellikle
belirtmemize gerek kalmaz; çünkü DI onları tanır ve otomatik aktarır. Böylece yalnızca sınıf adını vermek yeterli
olurdu:
...
services:
- App\Model\PostFacade
Ancak bu satırı da eklemenize gerek yok. services.neon dosyasının search bölümünde,
-Facade ya da -Factory ile biten tüm sınıfların DI tarafından otomatik bulunacağı tanımlıdır;
PostFacade da bu duruma girer.
Özet
PostFacade sınıfı yapıcısında Nette\Database\Explorer ister ve bu sınıf DI container'da
kayıtlı olduğundan, container bu örneği oluşturup aktarır. DI böylece bizim için bir PostFacade örneği
oluşturur ve onu isteyen HomePresenter sınıfına yapıcıda aktarır. Matruşka bebeği gibi. :) Herkes yalnızca
ne istediğini söyler ve onun nerede ya da nasıl oluşturulduğuyla ilgilenmez. Oluşturmayı DI container üstlenir.
Bağımlılık enjeksiyonu ve yapılandırma hakkında daha fazlasını burada okuyabilirsiniz.