แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒ แƒกแƒแƒชแƒแƒ•แƒ˜ Eloquent-แƒ˜แƒ—?

แƒฌแƒ˜แƒœแƒ แƒ™แƒ•แƒ˜แƒ แƒแƒก แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒ” แƒกแƒขแƒแƒขแƒ˜แƒ Eloquent แƒžแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก Repository-แƒ˜แƒก แƒจแƒแƒ‘แƒšแƒแƒœแƒ˜แƒก แƒฃแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒแƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘แƒ—แƒฃแƒ›แƒชแƒ, แƒ“แƒแƒ›แƒžแƒ˜แƒ แƒ“แƒ, แƒ แƒแƒ› แƒ›แƒ˜แƒ—แƒฎแƒ แƒ, แƒ แƒแƒ’แƒแƒ  แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ แƒœแƒแƒฌแƒ˜แƒšแƒแƒ‘แƒ แƒ˜แƒ• แƒ—แƒแƒ•แƒ˜แƒก แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒแƒ“. แƒแƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก แƒ›แƒ” แƒจแƒ”แƒ•แƒ”แƒชแƒ“แƒ”แƒ‘แƒ˜ แƒ’แƒแƒ•แƒแƒแƒœแƒแƒšแƒ˜แƒ–แƒ, แƒ—แƒฃ แƒ แƒแƒ’แƒแƒ  แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ”แƒก แƒจแƒแƒ‘แƒšแƒแƒœแƒ˜ แƒฉแƒ•แƒ”แƒฃแƒšแƒ”แƒ‘แƒ แƒ˜แƒ• แƒžแƒ แƒแƒ”แƒฅแƒขแƒ”แƒ‘แƒจแƒ˜. แƒกแƒแƒชแƒแƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒกแƒแƒญแƒ˜แƒ แƒ แƒ›แƒ”แƒ—แƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒœแƒ˜แƒ›แƒแƒšแƒฃแƒ แƒ˜ แƒœแƒแƒ™แƒ แƒ”แƒ‘แƒ˜:

<?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 แƒกแƒ™แƒแƒžแƒ”แƒ‘แƒ˜แƒก แƒ›แƒ”แƒจแƒ•แƒ”แƒแƒ‘แƒ˜แƒ—, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ”แƒ แƒ—แƒ”แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ™แƒšแƒแƒกแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ แƒกแƒแƒ™แƒฃแƒ—แƒแƒ แƒ˜ แƒ—แƒแƒ•แƒ˜แƒก แƒแƒฆแƒ”แƒ‘แƒ˜แƒก แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒกแƒ›แƒ’แƒ”แƒ‘แƒšแƒแƒ‘แƒ˜แƒ— แƒแƒ  แƒแƒ แƒ˜แƒก แƒกแƒแƒฃแƒ™แƒ”แƒ—แƒ”แƒกแƒ แƒ˜แƒ“แƒ”แƒ แƒ“แƒ แƒแƒ› แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒกแƒ›แƒ’แƒ”แƒ‘แƒšแƒแƒ‘แƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒ™แƒšแƒแƒกแƒ”แƒ‘แƒ–แƒ” แƒ’แƒแƒ“แƒแƒขแƒแƒœแƒ แƒšแƒแƒ’แƒ˜แƒ™แƒฃแƒ แƒ˜แƒ. แƒแƒกแƒ”แƒ? แƒ›แƒ” แƒ™แƒแƒœแƒ™แƒ แƒ”แƒขแƒฃแƒšแƒแƒ“ แƒ•แƒ˜แƒ–แƒฃแƒแƒšแƒฃแƒ แƒแƒ“ แƒ’แƒแƒ•แƒงแƒแƒ•แƒ˜ แƒ”แƒก แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜ แƒแƒ  แƒœแƒแƒฌแƒ˜แƒšแƒแƒ“. แƒ›แƒ”แƒ—แƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒœแƒแƒฌแƒ˜แƒšแƒ˜ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒจแƒ˜.

แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒกแƒขแƒแƒœแƒ“แƒแƒ แƒขแƒฃแƒšแƒ˜ แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒแƒ:

  • แƒแƒฎแƒแƒšแƒ˜ แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ˜แƒก แƒ›แƒจแƒ”แƒœแƒ”แƒ‘แƒšแƒแƒ‘แƒ แƒ“แƒ แƒ’แƒแƒ›แƒแƒฌแƒ•แƒ”แƒ•แƒ PostRepository:: แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ
  • PostRepository::getById, แƒกแƒฃแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ˜แƒก แƒ›แƒแƒœแƒ˜แƒžแƒฃแƒšแƒ˜แƒ แƒ”แƒ‘แƒ แƒ“แƒ แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒ PostRepository:: แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ
  • แƒ’แƒแƒ›แƒแƒฌแƒ•แƒ”แƒ•แƒ PostRepository:: แƒฌแƒแƒจแƒšแƒ

แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒจแƒ˜ แƒแƒ  แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒขแƒแƒœแƒ˜แƒก แƒ›แƒ”แƒ—แƒแƒ“แƒ”แƒ‘แƒ˜. แƒฌแƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ˜แƒก แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒจแƒ˜ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ get* แƒ›แƒ”แƒ—แƒแƒ“แƒ”แƒ‘แƒ˜. แƒ—แƒฃ แƒฌแƒแƒ˜แƒ™แƒ˜แƒ—แƒฎแƒแƒ•แƒ— แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜แƒก แƒกแƒ”แƒ’แƒ แƒ”แƒ’แƒแƒชแƒ˜แƒ˜แƒก แƒžแƒ แƒ˜แƒœแƒชแƒ˜แƒžแƒ˜ (แƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ I ะฒ แฒ›แฒงแฒแฒ แฒ˜), แƒ›แƒแƒจแƒ˜แƒœ แƒ’แƒแƒ˜แƒ แƒ™แƒ•แƒ”แƒ•แƒ, แƒ แƒแƒ› แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜ แƒซแƒแƒšแƒ˜แƒแƒœ แƒ“แƒ˜แƒ“แƒ˜แƒ แƒ“แƒ แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒก แƒ›แƒ˜แƒœแƒ˜แƒ›แƒฃแƒ› แƒแƒ  แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ”แƒ‘แƒฃแƒš แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒกแƒ›แƒ’แƒ”แƒ‘แƒšแƒแƒ‘แƒแƒก. แƒ“แƒ แƒแƒ แƒ’แƒแƒ•แƒงแƒแƒ— แƒแƒ แƒ–แƒ”. แƒ›แƒ”แƒ—แƒแƒ“แƒ˜ getById แƒแƒฃแƒชแƒ˜แƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒแƒ แƒ˜แƒ•แƒ”แƒจแƒ˜, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ แƒแƒช แƒฃแƒคแƒ แƒ แƒ แƒ—แƒฃแƒšแƒ˜ แƒฎแƒ“แƒ”แƒ‘แƒ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ, แƒ›แƒ˜แƒกแƒ˜ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ“แƒ”แƒ‘แƒ. แƒแƒ›แƒแƒก แƒชแƒแƒขแƒ แƒ›แƒแƒ’แƒ•แƒ˜แƒแƒœแƒ”แƒ‘แƒ˜แƒ— แƒ•แƒœแƒแƒฎแƒแƒ•แƒ—. แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒœแƒแƒฌแƒ˜แƒšแƒ˜แƒก แƒฃแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒแƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒ” แƒฌแƒ˜แƒœแƒ แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜ แƒฃแƒ‘แƒ แƒแƒšแƒแƒ“ แƒ“แƒแƒ•แƒ˜แƒ•แƒ˜แƒฌแƒงแƒ”แƒ‘ แƒ›แƒแƒก.

แƒฌแƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ˜แƒก แƒœแƒแƒฌแƒ˜แƒšแƒ˜ แƒแƒ แƒช แƒ—แƒฃ แƒ˜แƒกแƒ” แƒฃแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒ แƒ›แƒ”แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ, แƒ แƒแƒ“แƒ’แƒแƒœ Eloquent-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒกแƒแƒช แƒ™แƒ˜ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ แƒ˜แƒงแƒแƒก แƒแƒฅ. แƒ แƒ แƒ“แƒแƒ•แƒแƒ แƒฅแƒ•แƒ แƒ™แƒšแƒแƒกแƒก? แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒ ReadPostRepository, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ—แƒแƒ แƒ’แƒ–แƒ” แƒกแƒแƒชแƒแƒ•แƒ˜ แƒ›แƒแƒก แƒฃแƒ™แƒ•แƒ” แƒ›แƒชแƒ˜แƒ แƒ” แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ แƒแƒฅแƒ•แƒก. แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒ แƒฃแƒ‘แƒ แƒแƒšแƒแƒ“ แƒžแƒแƒกแƒขแƒจแƒ”แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ”แƒ‘แƒ˜:

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

แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜ แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒแƒกแƒ—แƒแƒœ, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“ 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 แƒฃแƒ‘แƒ แƒแƒšแƒแƒ“ แƒ˜แƒ—แƒฎแƒแƒ•แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒแƒก PostsQuery แƒ“แƒ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก แƒ›แƒแƒกแƒ—แƒแƒœ. แƒฉแƒ•แƒ”แƒœ แƒ›แƒ˜แƒ”แƒ  แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒฃแƒš แƒžแƒ แƒแƒ•แƒแƒ˜แƒ“แƒ”แƒ แƒจแƒ˜ แƒžแƒแƒกแƒขแƒจแƒ”แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ”แƒ‘แƒ˜ แƒ™แƒšแƒแƒกแƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“ EloquentPostQueries แƒ“แƒ แƒ”แƒก แƒ™แƒšแƒแƒกแƒ˜ แƒจแƒ”แƒ˜แƒชแƒ•แƒšแƒ”แƒ‘แƒ แƒ™แƒแƒœแƒขแƒ แƒแƒšแƒ”แƒ แƒจแƒ˜.

แƒฌแƒแƒ แƒ›แƒแƒ•แƒ˜แƒ“แƒ’แƒ˜แƒœแƒแƒ—, แƒ แƒแƒ› แƒฉแƒ•แƒ”แƒœแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ แƒซแƒแƒšแƒ˜แƒแƒœ แƒžแƒแƒžแƒฃแƒšแƒแƒ แƒฃแƒšแƒ˜ แƒ’แƒแƒฎแƒ“แƒ. แƒแƒ—แƒแƒกแƒแƒ‘แƒ˜แƒ— แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒฌแƒฃแƒ—แƒจแƒ˜ แƒฎแƒกแƒœแƒ˜แƒก แƒ’แƒ•แƒ”แƒ แƒ“แƒก แƒฃแƒแƒฎแƒšแƒ”แƒกแƒ˜ แƒžแƒฃแƒ‘แƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒ—. แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒžแƒแƒžแƒฃแƒšแƒแƒ แƒฃแƒšแƒ˜ แƒžแƒฃแƒ‘แƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒช แƒซแƒแƒšแƒ˜แƒแƒœ แƒฎแƒจแƒ˜แƒ แƒแƒ“ แƒ˜แƒ™แƒ˜แƒ—แƒฎแƒ”แƒ‘แƒ. แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ”แƒ‘แƒ˜ แƒ™แƒแƒ แƒ’แƒแƒ“ แƒ•แƒ”แƒ  แƒฃแƒ›แƒ™แƒšแƒแƒ•แƒ“แƒ”แƒ‘แƒ˜แƒแƒœ แƒแƒกแƒ”แƒ— แƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ”แƒ‘แƒก, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ”แƒœ แƒกแƒขแƒแƒœแƒ“แƒแƒ แƒขแƒฃแƒš แƒ’แƒแƒ“แƒแƒฌแƒงแƒ•แƒ”แƒขแƒแƒก - แƒฅแƒ”แƒจแƒก. แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ˜แƒก แƒ’แƒแƒ แƒ“แƒ, แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒกแƒฃแƒ แƒแƒ—แƒ˜ แƒ˜แƒœแƒแƒฎแƒ”แƒ‘แƒ แƒกแƒแƒชแƒแƒ•แƒจแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒžแƒขแƒ˜แƒ›แƒ˜แƒ–แƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒ˜ แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก - 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();
            });
    }

    // ะดั€ัƒะณะธะต ะผะตั‚ะพะดั‹ ะฟั€ะฐะบั‚ะธั‡ะตัะบะธ ั‚ะฐะบะธะต ะถะต
}

แƒ˜แƒ’แƒœแƒแƒ แƒ˜แƒ แƒ”แƒ‘แƒ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜ แƒกแƒแƒชแƒแƒ•แƒ˜ แƒ™แƒแƒœแƒกแƒขแƒ แƒฃแƒฅแƒขแƒแƒ แƒจแƒ˜. แƒ’แƒแƒฃแƒ แƒ™แƒ•แƒ”แƒ•แƒ”แƒšแƒ˜ แƒ›แƒ˜แƒ–แƒ”แƒ–แƒ˜แƒก แƒ’แƒแƒ›แƒ, แƒ›แƒแƒ— แƒ’แƒแƒ“แƒแƒฌแƒงแƒ•แƒ˜แƒขแƒ”แƒก แƒ“แƒแƒ”แƒ แƒฅแƒ•แƒแƒ— แƒฅแƒ”แƒจแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜ 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);
    }
}

แƒงแƒ•แƒ”แƒšแƒ แƒฉแƒ”แƒ›แƒ˜ แƒกแƒฃแƒ แƒ•แƒ˜แƒšแƒ˜ แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ‘แƒฃแƒœแƒ”แƒ‘แƒ แƒ˜แƒ•แƒแƒ“ แƒแƒ แƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ แƒžแƒ แƒแƒ•แƒแƒ˜แƒ“แƒ”แƒ แƒจแƒ˜. แƒแƒ›แƒ แƒ˜แƒ’แƒแƒ“, แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒœแƒ•แƒแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ— แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒก แƒฅแƒ”แƒจแƒ˜แƒ แƒ”แƒ‘แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ”แƒ แƒ—แƒ˜ แƒ™แƒšแƒแƒกแƒ˜แƒก แƒ“แƒแƒฌแƒ”แƒ แƒ˜แƒ— แƒ“แƒ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ˜แƒก แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒชแƒ•แƒšแƒ˜แƒ—. แƒ“แƒแƒœแƒแƒ แƒฉแƒ”แƒœแƒ˜ แƒ’แƒแƒœแƒแƒชแƒฎแƒแƒ“แƒ˜แƒก แƒ™แƒแƒ“แƒ˜ แƒแƒ  แƒจแƒ”แƒชแƒ•แƒšแƒ˜แƒšแƒ.

แƒ แƒ แƒ—แƒฅแƒ›แƒ แƒฃแƒœแƒ“แƒ, แƒฅแƒ”แƒจแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒกแƒ แƒฃแƒšแƒงแƒแƒคแƒ˜แƒšแƒแƒ“ แƒ’แƒแƒœแƒกแƒแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒšแƒแƒ“, แƒแƒกแƒ”แƒ•แƒ” แƒแƒฃแƒชแƒ˜แƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ‘แƒแƒ—แƒ˜แƒšแƒแƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ, แƒ แƒแƒ—แƒ แƒฌแƒแƒจแƒšแƒ˜แƒšแƒ˜ แƒกแƒขแƒแƒขแƒ˜แƒ แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒ˜ แƒ“แƒ แƒแƒ˜แƒ— แƒแƒ  แƒ“แƒแƒ™แƒ˜แƒ“แƒแƒก แƒกแƒแƒ˜แƒขแƒ–แƒ”, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ“แƒแƒฃแƒงแƒแƒ•แƒœแƒ”แƒ‘แƒšแƒ˜แƒ• แƒฌแƒแƒ˜แƒจแƒแƒšแƒแƒก. แƒ›แƒแƒ’แƒ แƒแƒ› แƒ”แƒก แƒฃแƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒ แƒ แƒแƒ› แƒแƒ แƒ˜แƒก.

แƒ“แƒ”แƒ“แƒแƒแƒ–แƒ แƒ˜: แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ— แƒแƒ แƒ แƒ”แƒ แƒ—แƒ˜, แƒแƒ แƒแƒ›แƒ”แƒ“ แƒแƒ แƒ˜ แƒจแƒแƒ‘แƒšแƒแƒœแƒ˜. แƒœแƒ˜แƒ›แƒฃแƒจแƒ˜ Command Query Responsibility Segregation (CQRS) แƒ’แƒ•แƒ—แƒแƒ•แƒแƒ–แƒแƒ‘แƒก แƒกแƒ แƒฃแƒšแƒแƒ“ แƒ’แƒแƒœแƒชแƒแƒšแƒ™แƒ”แƒ•แƒ“แƒ”แƒก แƒฌแƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ˜แƒกแƒ แƒ“แƒ แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜แƒก แƒ“แƒแƒœแƒ”แƒ–แƒ”. แƒ›แƒ” แƒ›แƒแƒกแƒ—แƒแƒœ แƒ›แƒ˜แƒ•แƒ”แƒ“แƒ˜ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜แƒก แƒกแƒ”แƒ’แƒ แƒ”แƒ’แƒแƒชแƒ˜แƒ˜แƒก แƒžแƒ แƒ˜แƒœแƒชแƒ˜แƒžแƒ˜, แƒ แƒแƒช แƒ’แƒ•แƒแƒคแƒ˜แƒฅแƒ แƒ”แƒ‘แƒ˜แƒœแƒ”แƒ‘แƒก, แƒ แƒแƒ› แƒแƒกแƒขแƒแƒขแƒฃแƒ แƒแƒ“ แƒ•แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘ แƒจแƒแƒ‘แƒšแƒแƒœแƒ”แƒ‘แƒก แƒ“แƒ แƒžแƒ แƒ˜แƒœแƒชแƒ˜แƒžแƒ”แƒ‘แƒก แƒ“แƒ แƒ”แƒ แƒ—แƒ˜ แƒ›แƒ”แƒแƒ แƒ˜แƒกแƒ’แƒแƒœ แƒ—แƒ”แƒแƒ แƒ”แƒ›แƒแƒก แƒกแƒแƒฎแƒ˜แƒ— แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ•แƒแƒœ :) แƒ แƒ แƒ—แƒฅแƒ›แƒ แƒฃแƒœแƒ“แƒ, แƒงแƒ•แƒ”แƒšแƒ แƒžแƒ แƒแƒ”แƒฅแƒขแƒก แƒแƒ  แƒกแƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒแƒกแƒ”แƒ—แƒ˜ แƒแƒ‘แƒกแƒขแƒ แƒแƒฅแƒชแƒ˜แƒ แƒกแƒฃแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ แƒฉแƒ”แƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ’แƒแƒ’แƒ˜แƒ–แƒ˜แƒแƒ แƒ”แƒ‘แƒ— แƒฎแƒ แƒ˜แƒ™แƒก.แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒกแƒแƒฌแƒงแƒ˜แƒก แƒ”แƒขแƒแƒžแƒ–แƒ” แƒ’แƒแƒœแƒ•แƒ˜แƒ—แƒแƒ แƒ”แƒ‘แƒ, แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒฃแƒ‘แƒ แƒแƒšแƒแƒ“ แƒจแƒ”แƒฅแƒ›แƒœแƒแƒ— แƒ™แƒšแƒแƒกแƒ˜ แƒžแƒแƒกแƒขแƒจแƒ”แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ”แƒ‘แƒ˜ แƒฉแƒ•แƒ”แƒฃแƒšแƒ”แƒ‘แƒ แƒ˜แƒ•แƒ˜ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ˜แƒ— Eloquent-แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—:

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

    // ะดั€ัƒะณะธะต ะผะตั‚ะพะดั‹
}

แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒฉแƒœแƒ“แƒ”แƒ‘แƒ แƒฅแƒ”แƒจแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒญแƒ˜แƒ แƒแƒ”แƒ‘แƒ, แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜ แƒœแƒแƒ‘แƒ˜แƒฏแƒ˜แƒ— แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒจแƒ”แƒฅแƒ›แƒœแƒแƒ— แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜ (แƒแƒœ แƒแƒ‘แƒกแƒขแƒ แƒแƒฅแƒขแƒฃแƒšแƒ˜ แƒ™แƒšแƒแƒกแƒ˜) แƒแƒ› แƒ™แƒšแƒแƒกแƒ˜แƒก แƒœแƒแƒชแƒ•แƒšแƒแƒ“. แƒžแƒแƒกแƒขแƒจแƒ”แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ”แƒ‘แƒ˜, แƒ“แƒแƒแƒ™แƒแƒžแƒ˜แƒ แƒ”แƒ— แƒ›แƒ˜แƒกแƒ˜ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ แƒ™แƒšแƒแƒกแƒจแƒ˜ EloquentPostQueries แƒ“แƒ แƒ’แƒแƒ“แƒแƒ“แƒ˜แƒ— แƒแƒ“แƒ แƒ” แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒš แƒกแƒฅแƒ”แƒ›แƒแƒ–แƒ”. แƒ“แƒแƒœแƒแƒ แƒฉแƒ”แƒœแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ™แƒแƒ“แƒ˜ แƒแƒ  แƒกแƒแƒญแƒ˜แƒ แƒแƒ”แƒ‘แƒก แƒจแƒ”แƒชแƒ•แƒšแƒแƒก.

แƒงแƒ•แƒ”แƒšแƒ แƒ”แƒก แƒฎแƒ แƒ˜แƒ™แƒ˜ แƒ™แƒšแƒแƒกแƒ”แƒ‘แƒ˜แƒ—, แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ”แƒ‘แƒ˜แƒ—, แƒ“แƒแƒ›แƒแƒ™แƒ˜แƒ“แƒ”แƒ‘แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ˜แƒœแƒ”แƒฅแƒชแƒ˜แƒ ะธ CQRS แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒแƒ“ แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜แƒ แƒฉแƒ”แƒ›แƒ˜ แƒฌแƒ˜แƒ’แƒœแƒ˜ "แƒ™แƒแƒ›แƒžแƒšแƒ”แƒฅแƒกแƒฃแƒ แƒ˜ แƒ•แƒ”แƒ‘ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ". แƒแƒกแƒ”แƒ•แƒ” แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒ’แƒแƒ›แƒแƒกแƒแƒ•แƒแƒšแƒ˜ แƒ’แƒแƒ›แƒแƒชแƒแƒœแƒ˜แƒ“แƒแƒœ, แƒ—แƒฃ แƒ แƒแƒขแƒแƒ› แƒแƒ แƒ˜แƒก แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ”แƒ‘แƒจแƒ˜ แƒฉแƒ”แƒ›แƒ˜ แƒงแƒ•แƒ”แƒšแƒ แƒ™แƒšแƒแƒกแƒ˜ แƒ›แƒแƒœแƒ˜แƒจแƒœแƒฃแƒšแƒ˜ แƒ แƒแƒ’แƒแƒ แƒช แƒกแƒแƒ‘แƒแƒšแƒแƒ.

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ