ááŒá®ážáá²á·áá²á·á¡áááºá áá»áœááºáá±á¬áºáá±ážáááºá
<?php
interface PostRepository
{
public function getById($id): Post;
public function save(Post $post);
public function delete($id);
}
ááá¯á·áá¬ááœááºá ááá±á¬áá»ááºáá»á¬áž ááœááºá repositories ááᯠá¡áá¯á¶ážááŒá¯ááẠáá¯á¶ážááŒááºáá«áá ááŸááºáááºážáá»á¬áž ááŒááºáááºááá°ááẠáááºážáááºážáá»á¬ážááᯠáááºážááá¯á·áᶠáááŒá¬áá ááá·áºááœááºážáááº-
<?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 áááºáááºáá»á¬ážááŸáááá·áº á¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºáá±á¬áºáááºáž áááºážááá¯á·ááá¯ááºááá¯ááºááá°ááẠáá¬áááºááŸááá±á¬ entity class áá»á¬ážááᯠááœááºááœááºáá²áá²áá¯ááºááŒááºážááẠá¡áá±á¬ááºážáá¯á¶ážá áááºáá°ážááá¯ááºáá«á á€áá¬áááºááᯠrepository á¡áááºážáá»á¬ážááá¯á· ááŒá±á¬ááºážááœáŸá±á·ááŒááºážááẠáá¯áá¹ááááŸááá¯á¶ááááºá áá«áá²áá¬ážá áá»áœááºá¯ááºááẠá€á¡ááºáá¬áá±á·á áºááᯠá¡ááá¯ááºážááŸá áºááá¯ááºážá¡ááŒá Ạááá¯ááºážááŒá¬ážáá¬ážáááºá áááºážáááºážáá»á¬ážá áááááá¯ááºážááᯠáá±ážááẠáá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááœáẠá¡áá¯á¶ážááŒá¯áá«áááºá
á á¶áá»áááºá á¶ááœáŸááºážáá±ážáá¬ážááŒááºážáá¯ááºáá±á¬ááºáá»ááºááŸá¬-
- á¡áá¬ááá¹áá¯á¡áá áºáá áºáá¯áááºáá±á¬ááºááŒááºážááŸáá·áºá áááºáá±á«áºááŸá¯ PostRepository::ááááºážáááºážáá«á
- PostRepository::getByIdáá ááŒááºááŸááºááŒááºážááŸáá·áº áá±á«áºáá°ááŒááºáž PostRepository::ááááºážáááºážáá«á
- á áááºáá±á«áºááŸá¯áá áºáᯠPostRepository::áá»ááºáááº
áá±ážááẠáá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááẠá¡áá»áá°ážáááºážáá»á¬ážááᯠááá¯á¶ážáá«á áááºááŸá¯ááŒááºážáá¯ááºáááºážáá»á¬ážááœááºá get* áááºážáááºážáá»á¬ážááá¯áᬠá¡áá¯á¶ážááŒá¯áá«áááºá á¡ááŒá±á¬ááºážá á¯á¶áááºááẠá¡ááºáá¬áá±á·á Ạááœá²ááœááºááŒááºážááá¯ááºáᬠá¡ááŒá±áá¶áá° (á ᬠI в ááá¯ááºáá¬áá±á¬) ááá¯á·áá±á¬áẠáá»áœááºá¯ááºááá¯á·á á¡ááºáá¬áá±á·á áºááẠááŒá®ážááœááºážááŒá®áž á¡áááºážáá¯á¶áž ááá°áá®áá±á¬ áá¬áááºááŸá áºáá¯ááᯠáá¯ááºáá±á¬ááºááŒá±á¬ááºáž áááºááŸá¬ážáá¬áá«áááá·áºáááºá ááŸá áºááá¯ááºážááœá²ááá¯á· á¡áá»áááºáááºááŒá®á áááºážáááºáž getById ááŸá áºáá¯áá¯á¶ážá¡ááœáẠááá¯á¡ááºáá±á¬áºáááºáž á¡ááá®áá±ážááŸááºážááẠááá¯ááá¯ááŸá¯ááºááœá±ážáá¬áááºááŸáá·áºá¡áá»áŸ áááºážá á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá»á¬ážááŸá¬ ááœá²ááŒá¬ážáááºááŒá áºáááºá áá«ááᯠááááŒá¬á០ááœá±á·áá«áááºá á¡áááºá áá±á¬ááºážáá«ážááŸá¬ áá±ážáá²á·áá²á· á¡ááá¯ááºážáá²á· á¡áá¯á¶ážááá»ááŸá¯á¡ááŒá±á¬ááºáž áá±ážáá²á·áá°ážáá¬ááá¯á· áá®áá áºááá¯ááºážááᯠáá±á·áá¬ážááá¯ááºáá«á·áááºá
Read á¡ááá¯ááºážááẠáá»áœááºá¯ááºá¡ááœáẠá¡ááœááºá¡áá¯á¶ážááááºáᯠáááºááááºá Eloquent á¡ááœááºááẠá€áá±áá¬ááœáẠá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá»á¬ážá áœá¬ ááŸáááá¯ááºáá±á¬ááŒá±á¬áá·áº ááŒá áºáááºá á¡áááºážáá¬áááºá áá¬áá²á ááá¯ááºááá¬áž ReadPostRepositoryáá¯á¶á á¶ááœááºááá¯á· repository áá°á·ááŸá¬ áááºá ááºááŸá¯áááºážáááºážááŸááá±ááŒá®á ááá¯áá·áºáá¬áᬠáá¯ááºááá¯á·ááááºá PostQueries:
<?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);
}
}
áá®á¡áááºážá á¡áá¯á¶ážáááºáá±ááŒá®á controllers ááá¯á·ááá¯áẠentity class ááá¯á·ááᯠááŒá¯ááºáá»ááŒááºážááŒáá·áº áá°ááá¬áááºááᯠáá¬ážáááºáááºá Controller ááœááºáááºážááá¯á€áá²á·ááá¯á·á¡áá¯á¶ážááŒá¯ááá¯ááºáááºá
<?php
final class PostsController extends Controller
{
public function lastPosts(PostQueries $postQueries)
{
return view('posts.last', [
'posts' => $postQueries->getLastPosts(),
]);
}
}
áááºážáááºáž PostsController::lastPosts á¡áá±á¬ááºá¡áááºáá±á¬áºááá¯á· áá±á¬ááºážááá¯áá¯á¶áá«áá²á PostsQueries áááºážááŸáá·áºá¡áá¯ááºáá¯ááºáááºá áááºáá±á¬ááºááŸá¯áá±ážáá°ááœáẠáá»áœááºá¯ááºááá¯á·áá»áááºáááºáá¬ážáááºá PostQueries á¡áááºážááŸáá·áºá¡áá° EloquentPostQueries ááŒá®ážáá±á¬á· áá® class ááᯠcontroller áá²á· á¡á á¬ážááá¯ážáááºá
áá»áœááºá¯ááºááá¯á·á á¡ááá®áá±ážááŸááºážááẠá¡ááœááºáá±áááºážá á¬ážáá¬ááŒá±á¬ááºáž á áááºáá°ážááŒáá·áºááŒáá«á áá¯á·á áá áºáááá áºáá»áŸáẠáá±á¬ááºááŸáá·áºáá»á®áá±á¬ áá¯á¶ážá áœá²áá°áá»á¬ážááẠáá±á¬ááºáá¯á¶ážáá±á«áº áá¯ááºáá±ááŸá¯áá»á¬ážááŒáá·áº á á¬áá»ááºááŸá¬ááᯠááœáá·áºááŒáááºá áá±áááºážá¡á á¬ážáá¯á¶áž á á¬áá±áá»á¬ážááá¯áááºáž áááŒá¬áá áááºááŸá¯áá±á·ááŸááááºá áá±áá¬áá±á·á áºáá»á¬ážááẠááá¯áá²á·ááá¯á·áá±á¬ load áá»á¬ážááᯠáá±á¬ááºážááœááºá áœá¬ áááá¯ááºááœááºááá¯ááºáá±á¬ááŒá±á¬áá·áº á á¶ááŒá±ááŸááºážáá»áẠ- cache ááᯠá¡áá¯á¶ážááŒá¯ááŒáááºá áá±áá¬áá±á·á áºá¡ááŒááºá á¡áá»áá¯á·áá±á¬áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážá¡ááœáẠá¡áá±á¬ááºážáá¯á¶ážááŒá áºá¡á±á¬ááºááŒá¯áá¯ááºáá¬ážáá±á¬ ááá¯ááŸá±á¬ááºááŸá¯ááœáẠáá±áá¬áá»áŸááºáá áºááŒááºá¡áá»áá¯á·ááᯠááááºážáááºážáá¬ážáá«ááẠ- memcache ááá¯á·ááá¯áẠááŒááºááŒááºáááºá.
Caching logic ááẠá¡áá»á¬ážá¡á¬ážááŒáá·áº ááá¯áá»áŸáááŸá¯ááºááœá±ážáá±á¬áºáááºáž 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();
});
}
// ÐŽÑÑгОе ЌеÑÐŸÐŽÑ Ð¿ÑакÑОÑеÑкО ÑакОе же
}
á¡ááºáá¬áá±á·á áºááᯠáá»á áºáá»á°ááŸá¯áá«á repository constructor ááœááºá ááááá±á¬ á¡ááŒá±á¬ááºážá¡áááºážáá áºáá¯áá¯ááŒá±á¬áá·áº Laravel ááœáẠááááºážáááºážáááºá¡ááœáẠá¡ááºáá¬áá±á·á áºááᯠá€áááºážááŒáá·áº á¡áááºáááºááẠáá¯á¶ážááŒááºáá²á·áááºá
á¡áááºážá¡á á¬áž CachedPostQueries caching ááá¯áᬠáá¯ááºáá±á¬ááºáááºá $this->cache-> ááŸááºáá¬ážáá«á ဠentry ááẠcache ááœááºááŸááááŸáá á áºáá±ážááŒá®ážááá¯ááºáá«áá ááá¯á·áá±á¬áẠcallback áá±á«áºááŒá®áž cache ááá¯á·ááŒááºááá¯á·áá±á¬áááºááá¯ážááá¯áá±ážáá«á áá»ááºáá¬á¡á¬ážáá¯á¶ážá áá® class ááᯠapplication ááŸá¬á¡áá±á¬ááºá¡áááºáá±á¬áºááá¯á·áá«áá²á á¡ááºáá¬áá±á·á áºááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááẠáá±á¬ááºážááá¯ááẠá¡ááá®áá±ážááŸááºážááŸá á¡áááºážáá»á¬ážá¡á¬ážáá¯á¶áž ááá¯á¡ááºáá«áááºá PostQueries á¡áááºážáá¥ááá¬áá áºáá¯áááºáá¶áááŸááá¬áááºá CachedPostQueries. ááá¯á·áá±á¬áº áá°ááá¯ááºááá¯ááºááẠCachedPostQueries constructor ááẠclass áá áºáá¯ááᯠparameter áá áºáá¯á¡ááŒá Ạáááºáá¶ááá«áááºá 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);
}
}
áá»áœááºá¯ááºáááá¹áá¡á¬ážáá¯á¶ážááᯠáá¶á·ááá¯ážáá±ážáá°ááœáẠááá¬ááá»áá» áá±á¬áºááŒáá¬ážáá«áááºá ááá¯á·ááŒá±á¬áá·áºá áá»áœááºá¯ááºááá¯á·ááẠá¡áááºážáá áºáá¯á á¬áá±ážááŒá®áž container configuration ááá¯ááŒá±á¬ááºážáá²ááŒááºážááŒáá·áºáᬠáá»áœááºá¯ááºááá¯á·ááá±á¬ááºážááá¯ááŸá¯áá»á¬ážááᯠcaching ááŒá¯áá¯ááºáá²á·áá«áááºá áá»ááºáá²á· á¡ááá®áá±ážááŸááºážáá¯ááºá áááŒá±á¬ááºážáá°ážá
á¡ááŸááºáááºá áááºááŸáºááᯠá¡ááŒáá·áºá¡áá¡áá±á¬ááºá¡áááºáá±á¬áºáááºá áá»ááºááá¯ááºááá·áºáá±á¬ááºážáá«ážááẠááá¯ááºáá±á«áºááœáẠá¡áá»áááºá¡áá±á¬áºááŒá¬ áááá¯ááºážáááœááááºáá² áá»ááºááŒááºáž áá»ááºáá áºááẠááá¬ážááááºááŒá±á¬ááºážááá¯áááºáž á¡áá±á¬ááºá¡áááºáá±á¬áºááẠááá¯á¡ááºáá«áááºá áá«áá±ááá·áº áá«ááœá±á á¡áá±ážá¡ááœá²ááœá±áá«á
á¡á±á¬ááºááŒá±ááá¯ááºáž- áá»áœááºá¯ááºááá¯á·ááẠáá áºáá¯ááá¯ááºá ááá°áá¬ááŸá áºáá¯ááᯠá¡áá¯á¶ážááŒá¯áá¬ážáááºá ááá°áᬠCommand Query Responsibility Segregation (CQRS) á¡ááºáá¬áá±á·á áºá¡ááá·áºááœáẠáááºá á¬áá±ážááŒááºáž áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠáá¯á¶ážáá¯á¶ážáá»á¬ážáá»á¬áž ááœá²ááŒá¬ážááẠá¡ááá¯ááŒá¯áááºá áá»áœááºáá±á¬áº áá°á·áá®áá±á¬ááºáá¬áááºá á¡ááºáá¬áá±á·á Ạááœá²ááœááºááŒááºážááá¯ááºáᬠá¡ááŒá±áá¶áá°áá¯á¶á á¶áá»á¬ážááŸáá·áº á¡ááŒá±áá¶áá°áá»á¬ážááᯠáá»áœááºážáá»ááºá áœá¬ ááŒááºááŸááºááŒá®áž áá®á¡áá¯áá®áá áºáá¯á¡áá±ááŒáá·áº á¡ááŒá¬ážáá áºáá¯á០áá áºáá¯á¶ážááᯠáá¯ááºáá°ááŒá±á¬ááºáž á¡ááŒá¶ááŒá¯áá«áááºá :) ááá±á¬áá»ááºááá¯ááºážááœáẠááá¯ááá¯á·áá±á¬ abstraction ááᯠááœá±ážáá»ááºááŒááºážá¡ááœáẠáááá¯á¡ááºáá² ááŸáá·áºááœááºááᯠáááºááŸáá·áº áá»áŸáá±áá«áááºá áá»áŸá±á¬ááºááœáŸá¬á áááŠážá¡ááá·áºááœááºá ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯á áááºááá¯ážááŸááºážá áœá¬á¡áááºážáá áºáá¯áááºáá®ážááá¯ááºáááºá PostQueries Eloquent ááŸáá áºááá·áº áá¯á¶ááŸááºá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááŸáá·áºá¡áá°
<?php
final class PostQueries
{
public function getById($id): Post
{
return Post::findOrFail($id);
}
// ÐŽÑÑгОе ЌеÑПЎÑ
}
áááºááŸáºá¡ááœáẠááá¯á¡ááºáá¬áá±á¬á¡áá«ááœááºá ááá¯ážááŸááºážáá±á¬ááœáŸá±á·ááŒááºážááŒáá·áº á€á¡áááºážá¡á á¬áž interface (ááá¯á·ááá¯áẠabstract class) ááᯠáááºáá®ážááá¯ááºáááºá PostQueriesáááºážáá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠá¡áááºážááá¯á· áá°ážáá°áá«á EloquentPostQueries á á±á¬á á±á¬á áá±á¬áºááŒáá¬ážáá²á· á¡á á®á¡á ááºááᯠááœá¬ážáá«á áá»ááºáá²á· application code ááœá±ááᯠááŒá±á¬ááºážá áá¬áááá¯áá«áá°ážá
á¡áááºážáá»á¬ážá á¡ááºáá¬áá±á·á
áºáá»á¬ážááŒáá·áº á€ááŸáá·áºááœááºáá»á¬ážá¡á¬ážáá¯á¶ážá ááŸá®ááá¯ááá¯áž О CQRS ááœáẠá¡áá±ážá
áááºáá±á¬áºááŒáá¬ážáá«áááºá
source: www.habr.com