Repositories mahasoa miaraka amin'ny Eloquent?

Nanoratra aho tamin'ny herinandro lasa lahatsoratra momba ny tsy fahampian'ny môdely Repository ho an'ny enti-mody Eloquent, na izany aza, dia nampanantena izy fa hilaza amiko ny fomba hampiasana azy io amin'ny ampahany amin'ny tombontsoany. Mba hanaovana izany, dia hiezaka ny hamakafaka ny fomba ampiasana ity môdely ity amin'ny tetikasa aho. Ny fomba kely indrindra takiana amin'ny tahiry iray:

<?php
interface PostRepository
{
    public function getById($id): Post;
    public function save(Post $post);
    public function delete($id);
}

Na izany aza, amin'ny tetikasa tena izy, raha nanapa-kevitra ny hampiasa trano fitehirizam-bokatra, dia matetika no ampidirina amin'izy ireo ny fomba famerenana ny firaketana:

<?php
interface PostRepository
{
    public function getById($id): Post;
    public function save(Post $post);
    public function delete($id);

    public function getLastPosts();
    public function getTopPosts();
    public function getUserPosts($userId);
}

Ireo fomba ireo dia azo ampiharina amin'ny alàlan'ny scopes Eloquent, fa ny kilasy enti-mitondra be loatra miaraka amin'ny andraikitry ny maka ny tenany dia tsy hevitra tsara indrindra, ary toa mitombina ny famindrana io andraikitra io amin'ny kilasy fitahirizana. Izany ve? Nozaraiko manokana ho fizarana roa ity interface ity. Ny ampahany voalohany amin'ny fomba dia hampiasaina amin'ny asa fanoratana.

Ny asa fanoratana mahazatra dia:

  • fananganana zavatra vaovao sy fanamby PostRepository::save
  • PostRepository::getById, fanodikodinam-pahefana sy fiantsoana PostRepository::save
  • fanamby PostRepository ::mamafa

Ny asa fanoratana dia tsy mampiasa fomba fakana. Amin'ny asa vakiana, ny fomba get* ihany no ampiasaina. Raha mamaky momba ny Fitsipika fanavakavahana amin'ny interface (taratasy I в mafy), dia ho hita mazava fa lehibe loatra ny interface misy antsika ary manatanteraka andraikitra roa samihafa farafahakeliny. Fotoana izao hizarana azy roa. FOMBA getById ilaina amin'ny roa tonta, fa rehefa mihasarotra ny fampiharana dia tsy mitovy ny fampiharana azy. Ho hitantsika aoriana kely izany. Nanoratra momba ny tsy maha-zava-dehibe ny ampahany amin'ny fanoratana aho tao amin'ny lahatsoratra teo aloha, ka amin'ity iray ity dia hanadino fotsiny izany aho.

Ny ampahany Read dia toa tsy misy ilana azy loatra, satria na ho an'ny Eloquent aza dia mety misy fampiharana maromaro eto. Inona no anarana nomena ny kilasy? afaka ReadPostRepository, fa amin'ny môdely repository efa misy ifandraisany kely izy. Afaka fotsiny ianao PostQueries:

<?php
interface PostQueries
{
    public function getById($id): Post;
    public function getLastPosts();
    public function getTopPosts();
    public function getUserPosts($userId);
}

Ny fampiharana azy amin'ny Eloquent dia tsotra:

<?php
final class EloquentPostQueries implements PostQueries
{
    public function getById($id): Post
    {
        return Post::findOrFail($id);
    }

    /**
    * @return Post[] | Collection
    */
    public function getLastPosts()
    {
        return Post::orderBy('created_at', 'desc')
            ->limit(/*some limit*/)
            ->get();
    }
    /**
    * @return Post[] | Collection
    */
    public function getTopPosts()
    {
        return Post::orderBy('rating', 'desc')
            ->limit(/*some limit*/)
            ->get();
    }

    /**
    * @param int $userId
    * @return Post[] | Collection
    */
    public function getUserPosts($userId)
    {
        return Post::whereUserId($userId)
            ->orderBy('created_at', 'desc')
            ->get();
    }
}

Ny interface dia tsy maintsy mifandray amin'ny fampiharana, ohatra amin'ny AppServiceProvider:

<?php
final class AppServiceProvider extends ServiceProvider 
{
    public function register()
    {
        $this->app->bind(PostQueries::class, 
            EloquentPostQueries::class);
    }
}

Ity kilasy ity dia efa ilaina. Tsapany ny andraikiny amin'ny alalan'ny fanamaivanana na ny mpanara-maso na ny saranga enti-manana. Ao amin'ny controller dia azo ampiasaina toy izao:

<?php
final class PostsController extends Controller
{
    public function lastPosts(PostQueries $postQueries)
    {
        return view('posts.last', [
            'posts' => $postQueries->getLastPosts(),
        ]);
    }
} 

fomba PostsController::lastPosts mangataka fampiharana kely fotsiny PostsQueries ary miara-miasa aminy. Ao amin'ny mpamatsy nampifandraisinay PostQueries miaraka amin'ny kilasy EloquentPostQueries ary ity kilasy ity dia hosoloina ho mpifehy.

Alao sary an-tsaina hoe lasa malaza be ny fampiharana ataontsika. Mpampiasa an'arivony isa-minitra no manokatra ny pejy miaraka amin'ny famoahana farany. Vakina matetika koa ny boky be mpitia indrindra. Ny angon-drakitra dia tsy mitantana tsara ny entana toy izany, noho izany dia mampiasa vahaolana mahazatra izy ireo - cache. Ho fanampin'ny angon-drakitra, misy snapshot data sasany dia voatahiry ao anaty fitahirizana natao ho an'ny asa sasany - memcached na redis.

Ny lojikan'ny cache dia matetika tsy sarotra, fa ny fampiharana azy amin'ny EloquentPostQueries dia tsy marina loatra (raha satria Fitsipika momba ny andraikitra tokana). Ara-dalàna kokoa ny mampiasa môdely decorator ary ampiharo ny caching ho haingo amin'ny hetsika lehibe:

<?php
use IlluminateContractsCacheRepository;

final class CachedPostQueries implements PostQueries
{
    const LASTS_DURATION = 10;

    /** @var PostQueries */
    private $base;

    /** @var Repository */
    private $cache;

    public function __construct(
        PostQueries $base, Repository $cache) 
    {
        $this->base = $base;
        $this->cache = $cache;
    }

    /**
    * @return Post[] | Collection
    */
    public function getLastPosts()
    {
        return $this->cache->remember('last_posts', 
            self::LASTS_DURATION, 
            function(){
                return $this->base->getLastPosts();
            });
    }

    // другие методы практически такие же
}

Aza miraharaha ny interface repository ao amin'ny constructor. Noho ny antony tsy fantatra dia nanapa-kevitra ny hanome anarana ny interface ho an'ny caching ao amin'ny Laravel izy ireo.

kilasy CachedPostQueries manatanteraka cache ihany. $this->cache->tadidio manamarina raha ao amin'ny cache io fidirana io ary raha tsy izany dia miantsoa ny fiverenana ary manoratra ny sanda miverina amin'ny cache. Ny hany sisa tavela dia ny fampiharana ity kilasy ity amin'ny fampiharana. Mila ny kilasy rehetra ao amin'ny fampiharana izahay mba hangataka fampiharana ny interface PostQueries nanomboka nahazo ohatra iray tao amin'ny kilasy CachedPostQueries. Na izany aza, ny tenany CachedPostQueries ny constructor dia tsy maintsy mahazo kilasy ho toy ny parameter EloquentPostQueriessatria tsy afaka miasa raha tsy misy fampiharana "tena". Miova isika AppServiceProvider:

<?php
final class AppServiceProvider extends ServiceProvider 
{
    public function register()
    {
        $this->app->bind(PostQueries::class, 
            CachedPostQueries::class);

        $this->app->when(CachedPostQueries::class)
            ->needs(PostQueries::class)
            ->give(EloquentPostQueries::class);
    }
}

Ny faniriako rehetra dia voafaritra mazava tsara ao amin'ny mpamatsy. Noho izany, nampihatra caching ho an'ny fangatahanay izahay tamin'ny fanoratana kilasy iray sy ny fanovana ny fandrindrana container. Ny sisa amin'ny kaody fampiharana dia tsy niova.

Mazava ho azy, mba hampiharana tanteraka ny caching, dia ilaina ihany koa ny mampihatra ny fanafoanana mba tsy hihantona amin'ny tranokala mandritra ny fotoana fohy ny lahatsoratra voafafa, fa voafafa avy hatrany. Saingy zavatra madinika ireo.

Fehiny: tsy iray no nampiasanay fa modely roa. Santionany Fizarana andraikitra amin'ny fangatahana baiko (CQRS) manolo-kevitra ny hanasaraka tanteraka ny asa famakiana sy fanoratana eo amin'ny sehatry ny interface. Tonga tany aminy aho Fitsipika fanavakavahana amin'ny interface, izay milaza fa mahay manodinkodina ireo lamina sy fitsipika aho ary maka ny iray avy amin'ny iray hafa ho toy ny theorem :) Mazava ho azy fa tsy ny tetikasa rehetra no mila abstraction toy izany amin'ny fisafidianana ireo singa, fa hizara ny fika aminao aho amin'ny dingana voalohany amin'ny fampiharana fampandrosoana, afaka mamorona kilasy fotsiny ianao PostQueries miaraka amin'ny fampiharana mahazatra amin'ny alàlan'ny Eloquent:

<?php
final class PostQueries
{
    public function getById($id): Post
    {
        return Post::findOrFail($id);
    }

    // другие методы
}

Rehefa ilaina ny caching dia afaka mamorona interface (na kilasy abstract) amin'ny toeran'ity kilasy ity ianao. PostQueries, adika amin'ny kilasy ny fampiharana azy EloquentPostQueries ary mandehana any amin'ilay tetika nolazaiko teo aloha. Ny sisa amin'ny kaody fampiharana dia tsy mila ovaina.

Ireo tetika rehetra ireo miaraka amin'ny kilasy, interface, Tsindrona fiankinan-doha и CQRS voafaritra amin’ny antsipiriany ao amin’ny ny bokiko “Architecture of Complex Web Applications”. Misy ihany koa ny vahaolana amin'ny ankamantatra hoe nahoana ireo kilasiko rehetra ao amin'ny ohatra amin'ity lahatsoratra ity dia voamarika ho farany.

Source: www.habr.com

Add a comment