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

እነዚህ ዘዴዎች በEloquent scopes ሊተገበሩ ይችላሉ፣ ነገር ግን የአካል ክፍሎችን በራሳቸው የማምጣት ሃላፊነት ከመጠን በላይ መጫን የተሻለ ሀሳብ አይደለም፣ እና ይህንን ሃላፊነት ወደ ማከማቻ ክፍሎች መውሰድ ምክንያታዊ ይመስላል። እንደዚያ ነው? ይህንን በይነገጽ በተለይ በእይታ ለሁለት ከፍዬዋለሁ። የስልቶቹ የመጀመሪያ ክፍል በፅሁፍ ስራዎች ውስጥ ጥቅም ላይ ይውላሉ.

መደበኛ የጽሑፍ አሠራር የሚከተለው ነው-

  • አዲስ ነገር ግንባታ እና ፈተና PostRepository::አስቀምጥ
  • ድህረ ማከማቻ :: getById, አካል ማጭበርበር እና መጥሪያ PostRepository::አስቀምጥ
  • ተፈታታኝ ነው። PostRepository :: ሰርዝ

የጽሑፍ ስራዎች የማምጣት ዘዴዎችን አይጠቀሙም. በንባብ ስራዎች፣ የማግኘት* ዘዴዎች ብቻ ጥቅም ላይ ይውላሉ። ካነበብክ የበይነገጽ መለያየት መርህ (ደብዳቤ I в SOLID), ከዚያ የእኛ በይነገጽ በጣም ትልቅ እና ቢያንስ ሁለት የተለያዩ ኃላፊነቶችን እንደሚፈጽም ግልጽ ይሆናል. ለሁለት ለመከፋፈል ጊዜው አሁን ነው. ዘዴ getByID በሁለቱም ውስጥ አስፈላጊ ነው, ነገር ግን አፕሊኬሽኑ ይበልጥ ውስብስብ እየሆነ ሲመጣ, አፈፃፀሙ ይለያያል. ይህንን ትንሽ ቆይተን እናየዋለን። በቀድሞው መጣጥፍ ውስጥ ስለ የመፃፍ ክፍሉ ምንም ጥቅም እንደሌለው ጽፌ ነበር ፣ ስለዚህ በዚህ ውስጥ በቀላሉ እረሳዋለሁ።

ለኤሎኬንት እንኳን እዚህ ብዙ ትግበራዎች ሊኖሩ ስለሚችሉ የንባብ ክፍል ለእኔ ምንም ፋይዳ የሌለው አይመስለኝም። ክፍሉን ምን መሰየም? ይችላል የፖስት ማከማቻ አንብብ፣ ግን ወደ አብነት የማጠራቀሚያ እሱ ቀድሞውኑ ትንሽ ጠቀሜታ አለው። ብቻ ትችላለህ የድህረ ጥያቄዎች:

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

በEloquent መተግበር በጣም ቀላል ነው፡-

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

በይነገጹ ከመተግበሩ ጋር የተያያዘ መሆን አለበት, ለምሳሌ በ AppService አቅራቢ:

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

ዘዴ PostsController :: LastPosts የተወሰነ ትግበራ ብቻ በመጠየቅ PostsQueries እና ከእሱ ጋር ይሰራል. በአቅራቢው ውስጥ አገናኘን የድህረ ጥያቄዎች ከክፍል ጋር ብዙ የፖስት መጠይቆች እና ይህ ክፍል በመቆጣጠሪያው ውስጥ ይተካዋል.

የእኛ መተግበሪያ በጣም ተወዳጅ ሆኗል ብለን እናስብ። በደቂቃ በሺዎች የሚቆጠሩ ተጠቃሚዎች ገጹን በቅርብ ጊዜ ህትመቶች ይከፍታሉ። በጣም ታዋቂዎቹ ህትመቶችም ብዙ ጊዜ ይነበባሉ። የውሂብ ጎታዎች እንደዚህ አይነት ሸክሞችን በደንብ አይያዙም, ስለዚህ መደበኛ መፍትሄ ይጠቀማሉ - መሸጎጫ. ከመረጃ ቋቱ በተጨማሪ የተወሰነ የውሂብ ቅጽበታዊ ገጽ እይታ ለተወሰኑ ስራዎች በተመቻቸ ማከማቻ ውስጥ ተከማችቷል - memcached ወይም ደገመ.

የመሸጎጫ አመክንዮ ብዙውን ጊዜ ያን ያህል የተወሳሰበ አይደለም፣ ነገር ግን በ 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();
            });
    }

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

በይነገጹን ችላ በል የማጠራቀሚያ በገንቢው ውስጥ. ባልታወቀ ምክንያት በላራቬል ውስጥ ለመሸጎጫ የሚሆን በይነገጽ በዚህ መንገድ ለመሰየም ወሰኑ።

ክፍል የተሸጎጡ የፖስታ ጥያቄዎች መሸጎጫ ብቻ ተግባራዊ ያደርጋል። $this->መሸጎጫ->አስታውስ ይህ ግቤት በመሸጎጫው ውስጥ መሆኑን ያረጋግጣል እና ካልሆነ፣ መልሶ ጥሪውን ይደውሉ እና የተመለሰውን እሴት ወደ መሸጎጫው ይጽፋል። የቀረው ይህንን ክፍል ወደ ማመልከቻው መተግበር ብቻ ነው። የበይነገጽ ትግበራን ለመጠየቅ በመተግበሪያው ውስጥ ያሉትን ሁሉንም ክፍሎች እንፈልጋለን የድህረ ጥያቄዎች የክፍሉን ምሳሌ መቀበል ጀመረ የተሸጎጡ የፖስታ ጥያቄዎች. ሆኖም እሱ ራሱ የተሸጎጡ የፖስታ ጥያቄዎች ገንቢው እንደ መለኪያ ክፍል መቀበል አለበት ብዙ የፖስት መጠይቆችያለ "እውነተኛ" ትግበራ ሊሠራ ስለማይችል. እንለውጣለን AppService አቅራቢ:

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

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

የመሸጎጫ አስፈላጊነት በሚነሳበት ጊዜ በቀላል እንቅስቃሴ በዚህ ክፍል ምትክ በይነገጽ (ወይም የአብስትራክት ክፍል) መፍጠር ይችላሉ የድህረ ጥያቄዎች, አተገባበሩን ወደ ክፍል ይቅዱ ብዙ የፖስት መጠይቆች እና ቀደም ሲል የገለጽኩትን እቅድ ይሂዱ. የተቀረው የመተግበሪያ ኮድ መቀየር አያስፈልግም.

እነዚህ ሁሉ ብልሃቶች ከክፍሎች ፣ በይነገጽ ፣ የጥገኛ መርፌ и CQRS ውስጥ በዝርዝር ተገልጿል የእኔ መጽሐፍ “ውስብስብ የድር መተግበሪያዎች አርክቴክቸር”. ለዚህ ጽሁፍ በምሳሌዎች ውስጥ ያሉት ሁሉም ክፍሎቼ የመጨረሻ ተብለው ምልክት የተደረገባቸው ለምን እንደሆነ ለእንቆቅልሹ መፍትሄም አለ።

ምንጭ: hab.com

አስተያየት ያክሉ