PHPPamokos.lt


11. Contracts ir Interfaces

Pakalbėkime apie projektų architektūrą, lankstumą ir apie logikos atskyrimą - tokie dalykai dabar vis labiau aptarinėjami, tame tarpe ir Laravel pasaulyje, dar labiau su Laravel 5 versija, kur įsigaliojo kontraktai (Contracts).

Iš principo, kontraktai yra tiesiog kitaip vadinami interfeisai. Laravel 5 versijoje svarbiausios sisteminės klasės iškeltos į atskirą "sluoksnį" Contracts, kur aprašomos taisyklės, kokius metodus ir savybes turi turėti tos klasės. Tikslas - kad galėtumėte ateityje pakeisti vieną klasę kitokia arba sukurti savo klasę. Populiariausias pavyzdys - sakykime, norėsite pakeisti duomenų bazės sluoksnį ir naudoti kitą biblioteką. Arba el.pašto siuntimui. Arba kešavimiui. Visas "kontrakterių" sąrašas yra patalpintas kataloge Illuminate\Contracts ir atrodo štai taip:

Laravel 5 Contract: Illuminate\Contracts\... Laravel 4 sistemos atitinkamas Facade (jei yra)
Auth\Guard Auth
Auth\PasswordBroker Password
Bus\Dispatcher Bus
Cache\Repository Cache
Cache\Factory Cache::driver()
Config\Repository Config
Container\Container App
Cookie\Factory Cookie
Cookie\QueueingFactory Cookie::queue()
Encryption\Encrypter Crypt
Events\Dispatcher Event
Filesystem\Cloud
Filesystem\Factory File
Filesystem\Filesystem File
Foundation\Application App
Hashing\Hasher Hash
Logging\Log Log
Mail\Mailer Mail
Mail\MailQueue Mail::queue()
Queue\Queue Queue
Queue\Factory Queue::driver()
Redis\Database Redis
Routing\Registrar Route
Routing\ResponseFactory Response
Routing\UrlGenerator URL
Support\Arrayable
Support\Jsonable
Support\Renderable
Validation\Factory Validator::make()
Validation\Validator
View\View
View\Factory View::make()

Neišsigąskite, šito sąrašo mintinai mokintis nereikia. Tiesą pasakius, yra didelė tikimybė, kad jums iš viso niekada jo neprireiks, jis labiau iš serijos "pravartu žinoti". Bet jeigu jau kiltų poreikis pasinaudoti Contracts struktūra, tai apžvelkime kaip tai galime padaryti.

Iš objektinio programavimo teorijos prisiminkime, kas yra interfeisai: tai, iš esmės, yra klasių aprašymai - kokios viduje turi būti savybės, kokie turi būti metodai, kokie jų parametrai. Ir klasės, realizuodamos interfeisą (implements), privalo turėti būtent tokius metodus ir savybes, kaip interfeise. Tai, pasikartojant, tokia Laravel struktūra leidžia nusakyti, kokių taisyklių turi laikyti kiti išoriniai klasių gamintojai, jei norės pasigaminti savo klasę kokiai Validacijai ar Kešavimui. Iš principo, į Contracts iškelta viskas, kas turi tikimybę keistis ateityje.

Dependency injection ir lankstumas

Pereinant prie visiškai realaus panaudojimo atvejo - reikia prisiminti dar vieną terminą dependency injection. Priminsiu - tai yra dar vienas lankstumo užtikrinimo būdas, kai rašoma klasė naudoja kažkokią išorinę klasę kaip parametrą, perduodamą per __construct() metodą - tokiu būdu ateityje kaip parametrą galima paduoti ir visiškai kitokią klasę.

Ok, užteks teorijos, pažiūrėkime į kodą:

1. Paprastas, nelankstus kešavimo būdas:

class SomeClass {

    public function find($id)
    {
        if (Cache::has($id))
        {
            // krauname duomenis iš kešo
        }
    }

}

Viskas kaip ir gerai, ir kodas veiks, ir visi bus laimingi. Bet šiuo atveju jūsų kodas priklausomas nuo Cache bibliotekos, ir jūs negalite paprastai jos pakeisti kažkokia kita. Tai darome žingsnį pirmyn.

2. Dependency injection panaudojimas:

class SomeClass {

    // Kešavimo mechanizmas - kaip kintamasis
    protected $cache;

    public function __construct(\SomePackage\Cache\Memcached $cache)
    {
        $this->cache = $cache;
    }

    public function find($id)
    {
        if ($this->cache->has($id))
        {
            // krauname duomenis iš kešo
        }
    }

}

Šitame pavyzdyje jau yra lankstumo - galime perduoti kaip parametrą bet kokį objektą iš tipo \SomePackage\Cache\Memcached. Ir pagal Laravel 5 logiką galime žengti dar toliau link visiško lankstumo - panaudoti kontraktą ir būtent jo objektą perduodi kaip parametrą - tokiu būdu galėsime vėliau tą pakeisti į bet kokią klasę, kuri veiks pagal tą patį kontraktą.

3. Laravel 5 Contracts panaudojimas

use Illuminate\Contracts\Cache\Repository as Cache;

class SomeClass {

    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }

}


(c) 2015-2018. Visais klausimais kreipkitės povilas@laraveldaily.com