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::save
  • PostRepository::getById, நிறுவனம் கையாளுதல் மற்றும் அழைப்பு PostRepository::save
  • சவால் PostRepository ::நீக்கு

எழுத்து செயல்பாடுகள் பெறுதல் முறைகளைப் பயன்படுத்துவதில்லை. வாசிப்பு செயல்பாடுகளில், get* முறைகள் மட்டுமே பயன்படுத்தப்படுகின்றன. பற்றி படித்தால் இடைமுகம் பிரித்தல் கோட்பாடு (கடிதம் 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(),
        ]);
    }
} 

முறை PostsController::lastPosts சில செயல்படுத்த வேண்டும் என்று கேட்கிறது இடுகைகள் கேள்விகள் அவளுடன் வேலை செய். வழங்குநரில் நாங்கள் இணைத்துள்ளோம் இடுகை கேள்விகள் வகுப்போடு EloquentPostQueries மற்றும் இந்த வகுப்பு கட்டுப்படுத்தியில் மாற்றியமைக்கப்படும்.

எங்கள் பயன்பாடு மிகவும் பிரபலமாகிவிட்டது என்று கற்பனை செய்யலாம். நிமிடத்திற்கு ஆயிரக்கணக்கான பயனர்கள் சமீபத்திய வெளியீடுகளுடன் பக்கத்தைத் திறக்கிறார்கள். மிகவும் பிரபலமான வெளியீடுகளும் அடிக்கடி படிக்கப்படுகின்றன. தரவுத்தளங்கள் அத்தகைய சுமைகளைக் கையாள்வதில் மிகவும் சிறப்பாக இல்லை, எனவே அவை நிலையான தீர்வு - கேச் பயன்படுத்துகின்றன. தரவுத்தளத்துடன் கூடுதலாக, தரவுகளின் ஒரு குறிப்பிட்ட ஸ்னாப்ஷாட் சில செயல்பாடுகளுக்கு உகந்த சேமிப்பகத்தில் சேமிக்கப்படுகிறது - memcached அல்லது redis.

கேச்சிங் லாஜிக் பொதுவாக அவ்வளவு சிக்கலானதாக இருக்காது, ஆனால் 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 இல் தற்காலிக சேமிப்பிற்கான இடைமுகத்தை அழைக்க முடிவு செய்தனர்.

Класс CachedPostQueries தேக்ககத்தை மட்டுமே செயல்படுத்துகிறது. $this->cache->நினைவில் கொள்ளுங்கள் கொடுக்கப்பட்ட உள்ளீடு தற்காலிக சேமிப்பில் உள்ளதா எனச் சரிபார்த்து, இல்லையெனில், திரும்ப அழைக்கப்பட்டு, திரும்பிய மதிப்பை தற்காலிக சேமிப்பில் எழுதுகிறது. பயன்பாட்டில் இந்த வகுப்பை செயல்படுத்த மட்டுமே உள்ளது. பயன்பாட்டில் உள்ள அனைத்து வகுப்புகளும் இடைமுகத்தை செயல்படுத்துமாறு கேட்க வேண்டும் இடுகை கேள்விகள் வகுப்பின் உதாரணத்தைப் பெறத் தொடங்கினார் CachedPostQueries. எனினும், CachedPostQueries கட்டமைப்பாளருக்கான அளவுருவாக ஒரு வகுப்பைப் பெற வேண்டும் EloquentPostQueries, ஏனெனில் அது ஒரு "உண்மையான" செயல்படுத்தல் இல்லாமல் வேலை செய்ய முடியாது. நாங்கள் மாறுகிறோம் 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);
    }

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

கேச்சிங் தேவை ஏற்படும் போது, ​​இந்த வகுப்பிற்கு பதிலாக ஒரு இடைமுகத்தை (அல்லது சுருக்க வகுப்பு) உருவாக்குவது எளிது இடுகை கேள்விகள், அதன் செயலாக்கத்தை வகுப்பிற்கு நகலெடுக்கவும் EloquentPostQueries நான் முன்பு விவரித்த திட்டத்திற்குச் செல்லவும். மீதமுள்ள பயன்பாட்டுக் குறியீட்டை மாற்ற வேண்டியதில்லை.

வகுப்புகள், இடைமுகங்கள் கொண்ட இந்த தந்திரங்கள் அனைத்தும், சார்பு ஊசி и CQRS விரிவாக விவரிக்கப்பட்டுள்ளது எனது புத்தகம் சிக்கலான வலை பயன்பாடுகளின் கட்டிடக்கலை. அதே இடத்தில், இந்த கட்டுரைக்கான எடுத்துக்காட்டுகளில் எனது அனைத்து வகுப்புகளும் ஏன் இறுதி என்று குறிக்கப்பட்டுள்ளன என்ற புதிருக்கான தீர்வு.

ஆதாரம்: www.habr.com

கருத்தைச் சேர்