Eloquent سان ڪارائتو ذخيرو؟

گذريل هفتي مون لکيو مضمون فصاحت ادارن لاءِ مخزن ٽيمپليٽ جي بيڪار هجڻ بابتبهرحال، هن مون کي ٻڌائڻ جو واعدو ڪيو ته ڪيئن جزوي طور ان کي پنهنجي فائدي لاءِ استعمال ڪيو. هن کي ڪرڻ لاء، مان تجزيو ڪرڻ جي ڪوشش ڪندس ته هي ٽيمپليٽ عام طور تي منصوبن ۾ ڪيئن استعمال ٿيندو آهي. مخزن لاءِ گهٽ ۾ گهٽ گهربل طريقن جو سيٽ:

<?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 ::getById، اداري جي هٿرادو ۽ طلب ڪرڻ پوسٽ ريپوزٽري:: محفوظ ڪريو
  • هڪ چئلينج PostRepository::delete

لکڻ جي عملن کي حاصل ڪرڻ جا طريقا استعمال نٿا ڪن. پڙهڻ جي عملن ۾، صرف حاصل * طريقا استعمال ڪيا ويندا آهن. جيڪڏھن توھان پڙھندا آھيو انٽرفيس الڳ ڪرڻ جو اصول (خط 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(),
        ]);
    }
} 

طريقو پوسٽ ڪنٽرولر::آخري پوسٽون صرف ڪجهه عمل ڪرڻ لاء پڇي پوسٽس سوال ۽ ان سان گڏ ڪم ڪري ٿو. مهيا ڪندڙ ۾ اسان ڳنڍيل آهي پوسٽ سوال ڪلاس سان فصيح پوسٽ سوال ۽ هن طبقي کي ڪنٽرولر ۾ تبديل ڪيو ويندو.

اچو ته تصور ڪريو ته اسان جي ايپليڪيشن تمام مقبول ٿي چڪي آهي. هزارين صارفين في منٽ تازه ترين اشاعتن سان صفحو کوليندا آهن. تمام مشهور اشاعت پڻ اڪثر پڙهيا ويندا آهن. ڊيٽابيسس اهڙيون لوڊشيڊنگ کي چڱي طرح نه ٿا ڪن، تنهنڪري اهي هڪ معياري حل استعمال ڪن ٿا - هڪ ڪيش. ڊيٽابيس کان علاوه، هڪ خاص ڊيٽا سنيپ شاٽ اسٽوريج ۾ محفوظ ڪئي وئي آهي خاص آپريشن لاءِ بهتر ڪيل. يادگار يا ورجائي.

ڪيشنگ منطق عام طور تي ايترو پيچيده نه آهي، پر EloquentPostQueries ۾ ان کي لاڳو ڪرڻ بلڪل صحيح ناهي (جيڪڏهن صرف ان ڪري اڪيلو ذميداري جو اصول). ٽيمپليٽ استعمال ڪرڻ تمام گهڻو قدرتي آهي سينگار ڪندڙ ۽ بنيادي عمل لاءِ سجاڳي جي طور تي ڪيشنگ کي لاڳو ڪريو:

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

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

انٽرفيس کي نظر انداز ڪريو مخزن تعمير ڪندڙ ۾. ڪجهه اڻڄاتل سببن لاء، انهن هن طريقي سان Laravel ۾ ڪيشنگ لاء انٽرفيس جو نالو ڏيڻ جو فيصلو ڪيو.

ڪلاس CachedPostQuerys صرف ڪيشنگ کي لاڳو ڪري ٿو. $this->cache->ياد رکو چيڪ ڪري ٿو ته ڇا هي داخلا ڪيش ۾ آهي ۽ جيڪڏهن نه، پوء ڪال بيڪ کي سڏي ٿو ۽ واپس ڪيل قيمت کي ڪيش ۾ لکي ٿو. باقي رهي ٿو هن طبقي کي ايپليڪيشن ۾ لاڳو ڪرڻ. اسان کي سڀني طبقن جي ضرورت آهي جيڪي ايپليڪيشن ۾ انٽرفيس تي عمل درآمد جي درخواست ڪرڻ لاءِ پوسٽ سوال ڪلاس جو هڪ مثال حاصل ڪرڻ شروع ڪيو CachedPostQuerys. بهرحال، هو پاڻ کي CachedPostQuerys تعمير ڪندڙ کي لازمي طور تي هڪ ڪلاس حاصل ڪرڻ گهرجي فصيح پوسٽ سوالڇاڪاڻ ته اهو "حقيقي" عمل جي بغير ڪم نٿو ڪري سگهي. اسان تبديل ڪريون ٿا 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) انٽرفيس سطح تي پڙهڻ ۽ لکڻ جي عملن کي مڪمل طور تي الڳ ڪرڻ جي تجويز پيش ڪري ٿو. مان هن جي ذريعي آيو آهيان انٽرفيس الڳ ڪرڻ جو اصول، جنهن مان معلوم ٿئي ٿو ته آئون مهارت سان نمونن ۽ اصولن کي هٿي وٺان ٿو ۽ هڪ ٻئي مان هڪ نظريي جي طور تي حاصل ڪريان ٿو :) يقينن، هر منصوبي کي ادارن جي چونڊ لاءِ اهڙي تجريد جي ضرورت ناهي، پر آئون توهان سان اها چال شيئر ڪندس درخواست جي شروعاتي مرحلي ۾ ترقي، توهان صرف هڪ ڪلاس ٺاهي سگهو ٿا پوسٽ سوال Eloquent ذريعي عام عمل سان:

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

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

جڏهن ڪيشنگ جي ضرورت محسوس ٿئي ٿي، هڪ سادي حرڪت سان توهان هن ڪلاس جي جاءِ تي هڪ انٽرفيس (يا خلاصو ڪلاس) ٺاهي سگهو ٿا پوسٽ سوال، ان جي عمل درآمد کي ڪلاس ۾ نقل ڪريو فصيح پوسٽ سوال ۽ ان اسڪيم ڏانھن وڃو جيڪو مون اڳ بيان ڪيو آھي. باقي ايپليڪيشن ڪوڊ کي تبديل ڪرڻ جي ضرورت ناهي.

اهي سڀئي چالون طبقن سان، انٽرفيس، انحصار ڪندڙ انجيڪشن и سي ق آر ايس ۾ تفصيل سان بيان ڪيو ويو آهي منهنجو ڪتاب ”آرڪيٽيڪچر آف ڪمپليڪس ويب ايپليڪيشن“. اتي به هڪ حل آهي ته ڇو هن مضمون جي مثالن ۾ منهنجي سڀني طبقن کي حتمي طور نشان لڳايو ويو آهي.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو