د مفصلو سره ګټور ذخیره؟

تیره اونۍ ما لیکلي د فصیحه ادارو لپاره د ذخیره کولو ټیمپلیټ بې ګټې کیدو په اړه مقالهپه هرصورت، هغه ژمنه وکړه چې ما ته به ووایي چې څنګه یې د خپلې ګټې لپاره یو څه برخه وکاروئ. د دې کولو لپاره، زه به هڅه وکړم چې تحلیل کړم چې دا ټیمپلیټ معمولا په پروژو کې کارول کیږي. د ذخیره کولو لپاره لږترلږه اړین میتودونه:

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

په هرصورت، په ریښتینې پروژو کې، که دا پریکړه شوې وه چې د ذخیره کولو کارولو لپاره، د ریکارډونو د ترلاسه کولو میتودونه ډیری وختونه دوی ته اضافه کیږي:

<?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);
}

دا میتودونه د فصاحت سکوپونو له لارې پلي کیدی شي ، مګر د ځان د راوړلو مسؤلیت سره د ادارې ټولګیو ډیر بار کول غوره نظر ندی ، او د ذخیره کولو ټولګیو ته د دې مسؤلیت لیږدول منطقي ښکاري. داسې ده؟ ما په ځانګړي ډول دا انٹرفیس په دوه برخو ویشلی. د میتودونو لومړۍ برخه به د لیکلو عملیاتو کې وکارول شي.

د لیکلو معیاري عملیات دا دي:

  • د نوي اعتراض او ننګونو جوړول PostRepository::Save
  • PostRepository::getById، د ادارې لاسوهنه او احضار کول PostRepository::Save
  • یوه ننګونه PostRepository :: ړنګول

د لیکلو عملیات د راوړلو میتودونه نه کاروي. د لوستلو په عملیاتو کې، یوازې د ترلاسه کولو میتودونه کارول کیږي. که تاسو په اړه ولولئ د انٹرفیس جلا کولو اصول (لیک I в سولیډ) ، نو دا به روښانه شي چې زموږ انٹرفیس خورا لوی دی او لږترلږه دوه مختلف مسؤلیتونه ترسره کوي. دا وخت دی چې دا په دوه ویشل شي. طریقه getById په دواړو کې اړین دی، مګر لکه څنګه چې غوښتنلیک خورا پیچلی کیږي، د هغې پلي کول به توپیر ولري. موږ به دا لږ وروسته وګورو. ما په تیرو مقاله کې د لیکلو برخې د بې ګټې په اړه لیکلي، نو پدې کې به زه په ساده ډول د هغې په اړه هیر کړم.

لوستل شوې برخه ماته دومره بې ګټې نه ښکاري ، ځکه چې حتی د فصاحت لپاره دلته ډیری پلي کیدی شي. ټولګي ته څه نوم ورکړو؟ کولی شي ReadPostRepository, مګر د ټیمپلیټ ته ذخیره هغه لا دمخه لږ تړاو لري. تاسو کولی شئ یوازې پوسټ پوښتنې:

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

د فصاحت سره یې پلي کول خورا ساده دي:

<?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();
    }
}

انٹرفیس باید د تطبیق سره تړاو ولري، د بیلګې په توګه د AppServiceProvider:

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

دا ټولګی لا دمخه ګټور دی. هغه د کنټرولرانو یا د ادارې طبقې په راحت کولو سره خپل مسؤلیت احساسوي. په کنټرولر کې دا په لاندې ډول کارول کیدی شي:

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

میتود پوسټونه کنټرولر::وروستی پوسټونه یوازې د یو څه پلي کولو غوښتنه کول پوسټونه پوښتنې او ورسره کار کوي. په چمتو کونکي کې چې موږ لینک کړی پوسټ پوښتنې له ټولګي سره په زړه پورې پوسټ پوښتنې او دا ټولګي به په کنټرولر کې ځای په ځای شي.

راځئ چې تصور وکړو چې زموږ غوښتنلیک خورا مشهور شوی. په هره دقیقه کې زرګونه کاروونکي د وروستیو خپرونو سره پاڼه پرانیزي. ترټولو مشهورې خپرونې هم ډیر ځله لوستل کیږي. ډیټابیسونه دا ډول بارونه په ښه توګه نه اداره کوي، نو دوی یو معیاري حل کاروي - یو کیچ. د ډیټابیس سربیره، یو ځانګړی ډیټا سنیپ شاټ په ذخیره کې زیرمه شوی چې د ځانګړو عملیاتو لپاره مطلوب دی - منل شوی او یا تکرار.

د کیچ کولو منطق معمولا دومره پیچلی ندی ، مګر په EloquentPostQuerys کې یې پلي کول خورا سم ندي (که یوازې ځکه چې د مسؤلیت یوازینی اصول). دا خورا طبیعي ده چې د ټیمپلیټ کارول سينګار کوونکی او کیشینګ د اصلي عمل لپاره د سینګار په توګه پلي کړئ:

<?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();
            });
    }

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

انٹرفیس ته پام وکړئ ذخیره په جوړونکي کې. د ځینو نامعلومو دلیلونو لپاره، دوی پریکړه وکړه چې په لارویل کې د کیچ کولو لپاره انٹرفیس په دې ډول نوم کړي.

کللس کیش شوي پوسټ پوښتنې یوازې کیشینګ پلي کوي. $this->cache->په یاد ولرئ ګوري چې ایا دا ننوتل په کیچ کې دي او که نه، بیا کال بیک ته زنګ ووهي او بیرته راستنیدونکي ارزښت کیچ ته لیکي. ټول هغه څه چې پاتې دي دا ټولګي په غوښتنلیک کې پلي کول دي. موږ ټولو ټولګیو ته اړتیا لرو چې په غوښتنلیک کې د انٹرفیس پلي کولو غوښتنه وکړي پوسټ پوښتنې د ټولګي یوه بیلګه ترلاسه کول پیل کړل کیش شوي پوسټ پوښتنې. په هرصورت، هغه پخپله کیش شوي پوسټ پوښتنې جوړونکی باید د پیرامیټر په توګه ټولګي ترلاسه کړي په زړه پورې پوسټ پوښتنېځکه چې دا د "ریښتیني" پلي کولو پرته کار نشي کولی. موږ بدلون کوو د 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);
    }
}

زما ټولې هیلې په طبیعي ډول په چمتو کونکي کې بیان شوي. پدې توګه ، موږ یوازې د یوې ټولګي لیکلو او د کانټینر ترتیب بدلولو سره زموږ د غوښتنو لپاره کیشینګ پلي کړ. د غوښتنلیک پاتې کوډ نه دی بدل شوی.

البته، د کیشینګ په بشپړ ډول پلي کولو لپاره، دا هم اړینه ده چې باطلول پلي کړئ ترڅو حذف شوې مقاله د یو څه وخت لپاره په سایټ کې ځړول نشي، مګر سمدلاسه حذف کیږي. مګر دا کوچني شیان دي.

لاندینۍ کرښه: موږ یو نه، مګر دوه ټیمپلیټونه کارولي. نمونه د قوماندې پوښتنې مسؤلیت جلا کول (CQRS) د انٹرفیس په کچه د لوستلو او لیکلو عملیاتو بشپړ جلا کولو وړاندیز کوي. زه له لارې هغه ته راغلم د انٹرفیس جلا کولو اصول، کوم چې وړاندیز کوي چې زه په مهارت سره نمونې او اصول تنظیموم او یو له بل څخه د تیورم په توګه اخلم :) البته ، هره پروژه د ادارو غوره کولو لپاره داسې خلاصون ته اړتیا نلري ، مګر زه به یې تاسو سره د غوښتنلیک په لومړي مرحله کې شریک کړم. پراختیا، تاسو کولی شئ په ساده ډول یو ټولګی جوړ کړئ پوسټ پوښتنې د فصاحت له لارې د معمول پلي کولو سره:

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

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

کله چې د کیچ کولو اړتیا رامینځته شي ، د ساده حرکت سره تاسو کولی شئ د دې ټولګي پرځای انٹرفیس (یا خلاصې ټولګي) رامینځته کړئ پوسټ پوښتنې، د هغې پلي کول ټولګي ته کاپي کړئ په زړه پورې پوسټ پوښتنې او هغه سکیم ته لاړ شئ چې ما مخکې تشریح کړی. د غوښتنلیک پاتې کوډ بدلولو ته اړتیا نلري.

دا ټول چلونه د ټولګیو، انٹرفیسونو سره، د انحصار انجکشن и CQRS په تفصیل سره تشریح شوی زما کتاب "د پیچلو ویب غوښتنلیکونو جوړښت". د دې معما حل هم شتون لري چې ولې د دې مقالې لپاره په مثالونو کې زما ټول ټولګي د وروستي په توګه نښه شوي.

سرچینه: www.habr.com

Add a comment