Model
Ko naša aplikacija raste, kmalu ugotovimo, da moramo podobne operacije podatkovne zbirke izvajati na različnih lokacijah in v različnih predvajalnikih, na primer pridobivanje najnovejših objavljenih člankov. Če našo aplikacijo izboljšamo tako, da člankom dodamo zastavico, ki označuje stanje dela v nastajanju, moramo prav tako iti skozi vsa mesta v naši aplikaciji in dodati klavzulo where, da se prepričamo, da so izbrani samo dokončani članki.
Na tej točki postane neposredno delo s podatkovno bazo nezadostno in pametneje si bo pomagati z novo funkcijo, ki vrača objavljene članke. In ko bomo pozneje dodali še eno klavzulo (na primer, da ne bomo prikazovali člankov s prihodnjim datumom), bomo svojo kodo urejali le na enem mestu.
Funkcijo bomo umestili v razred PostFacade
in jo poimenovali getPublicArticles()
.
V imeniku app/Model/
bomo ustvarili naš modelni razred PostFacade
, ki bo skrbel za naše
članke:
<?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');
}
}
V razredu posredujemo podatkovno zbirko Explorer. S tem bomo izkoristili moč vsebnika DI.
Preklopili bomo na HomePresenter
, ki ga bomo uredili tako, da se bomo znebili odvisnosti od
Nette\Database\Explorer
in jo nadomestili z novo odvisnostjo od našega novega razreda.
<?php
namespace App\UI\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);
}
}
V razdelku uporaba uporabljamo App\Model\PostFacade
, zato lahko kodo PHP skrajšamo na PostFacade
.
Ta objekt zahtevamo v konstruktorju, ga zapišemo v lastnost $facade
in ga uporabimo v metodi renderDefault.
Zadnji preostali korak je naučiti vsebnik DI, da ustvari ta objekt. To običajno storimo tako, da v datoteko
config/services.neon
v razdelku services
dodamo točko z navedbo polnega imena razreda in parametrov
konstruktorja. S tem ga tako rekoč registriramo in objekt se nato imenuje storitev. Zahvaljujoč čarovniji, ki se
imenuje samodejna vključitev, nam običajno ni treba
navesti parametrov konstruktorja, saj jih DI prepozna in posreduje samodejno. Tako bi bilo dovolj, če bi samo navedli ime
razreda:
...
services:
- App\Model\PostFacade
Vendar vam te vrstice tudi ni treba dodati. V razdelku search
na začetku services.neon
je
opredeljeno, da bo vse razrede, ki se končajo s -Facade
ali -Factory
, DI poiskal samodejno, kar velja
tudi za PostFacade
.
Povzetek
Razred PostFacade
v konstruktorju zahteva Nette\Database\Explorer
, in ker je ta razred registriran
v vsebniku DI, vsebnik ustvari ta primerek in ga posreduje. DI nam na ta način ustvari primerek PostFacade
in ga
v konstruktorju posreduje razredu HomePresenter, ki je zanj zaprosil. Nekakšna lutka Matrjoška v kodi :) Vse komponente
zahtevajo le tisto, kar potrebujejo, in jim je vseeno, kje in kako se ustvari. Za ustvarjanje poskrbi vsebnik DI.
Tukaj si lahko preberete več o vbrizgavanju odvisnosti in o konfiguraciji.