Il-ġimgħa li għaddiet ktibt
<?php
interface PostRepository
{
public function getById($id): Post;
public function save(Post $post);
public function delete($id);
}
Madankollu, fi proġetti reali, jekk ġie deċiż li jintużaw repożitorji, ħafna drabi jiżdiedu magħhom metodi għall-irkupru tar-rekords:
<?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);
}
Dawn il-metodi jistgħu jiġu implimentati permezz ta' ambiti Eloquent, iżda tagħbija żejda ta' klassijiet ta' entitajiet bir-responsabbiltà li jġibu lilhom infushom mhix l-aħjar idea, u li din ir-responsabbiltà titmexxa għal klassijiet ta' repożitorju tidher loġika. Huwa hekk? I speċifikament viżwalment maqsuma din l-interface f'żewġ partijiet. L-ewwel parti tal-metodi se tintuża f'operazzjonijiet ta 'kitba.
L-operazzjoni standard tal-kitba hija:
- kostruzzjoni ta 'oġġett ġdid u sfida PostRepository::salva
- PostRepository::getById, manipulazzjoni ta’ entità u taħrika PostRepository::salva
- sfida PostRepository::ħassar
L-operazzjonijiet tal-kitba ma jużawx metodi fetch. F'operazzjonijiet ta' qari, jintużaw biss metodi get*. Jekk taqra dwar Prinċipju tas-Segregazzjoni tal-Interface (ittra I в SOLIDU), allura jkun ċar li l-interface tagħna hija kbira wisq u twettaq mill-inqas żewġ responsabbiltajiet differenti. Wasal iż-żmien li taqsamha bi tnejn. Metodu getById huwa meħtieġ fit-tnejn, iżda hekk kif l-applikazzjoni ssir aktar kumplessa, l-implimentazzjonijiet tagħha se jkunu differenti. Dan se narawh ftit aktar tard. Ktibt dwar l-inutilità tal-parti tal-kitba f'artiklu preċedenti, għalhekk f'dan wieħed sempliċiment se ninsa dwarha.
Il-parti Aqra jidhirli mhux daqshekk inutli, peress li anke għal Eloquent jista 'jkun hemm diversi implimentazzjonijiet hawn. Xi isem il-klassi? Can ReadPostRepository, iżda għall-mudell Repożitorju hu diġà għandu ftit rilevanza. Tista 'biss PostQueries:
<?php
interface PostQueries
{
public function getById($id): Post;
public function getLastPosts();
public function getTopPosts();
public function getUserPosts($userId);
}
L-implimentazzjoni tagħha b'Eloquent hija pjuttost sempliċi:
<?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();
}
}
L-interface trid tkun assoċjata mal-implimentazzjoni, pereżempju fi AppServiceProvider:
<?php
final class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(PostQueries::class,
EloquentPostQueries::class);
}
}
Din il-klassi diġà hija utli. Huwa jirrealizza r-responsabbiltà tiegħu billi jeħles jew lill-kontrolluri jew lill-klassi tal-entità. F'kontrollur jista' jintuża bħal dan:
<?php
final class PostsController extends Controller
{
public function lastPosts(PostQueries $postQueries)
{
return view('posts.last', [
'posts' => $postQueries->getLastPosts(),
]);
}
}
Metodu PostsController::lastPosts titlob biss għal xi implimentazzjoni PostsQueries u jaħdem magħha. Fil-fornitur aħna konnessi PostQueries mal-klassi EloquentPostQueries u din il-klassi tiġi sostitwita fil-kontrollur.
Ejja nimmaġinaw li l-applikazzjoni tagħna saret popolari ħafna. Eluf ta’ utenti kull minuta jiftħu l-paġna bl-aħħar pubblikazzjonijiet. L-aktar pubblikazzjonijiet popolari jinqraw ukoll ħafna drabi. Databases ma jimmaniġġjawx tali tagħbijiet tajjeb ħafna, għalhekk jużaw soluzzjoni standard - cache. Minbarra d-database, ċertu snapshot tad-dejta hija maħżuna f'ħażna ottimizzata għal ċerti operazzjonijiet - memcached jew erġa ngħidu.
Il-loġika tal-caching normalment mhix daqshekk ikkumplikata, iżda l-implimentazzjoni tagħha f'EloquentPostQueries mhix korretta ħafna (jekk biss għax Prinċipju ta 'Responsabbiltà Unika). Huwa ħafna aktar naturali li tuża mudell Dekoratur u timplimenta l-caching bħala dekorazzjoni għall-azzjoni prinċipali:
<?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();
});
}
// другие методы практически такие же
}
Injora l-interface Repożitorju fil-kostruttur. Għal xi raġuni mhux magħrufa, huma ddeċidew li jsemmu l-interface għall-caching f'Laravel b'dan il-mod.
Klassi CachedPostQueries jimplimenta l-caching biss. $dan->cache->ftakar jiċċekkja jekk din id-dħul hijiex fil-cache u jekk le, imbagħad isejjaħ lura u jikteb il-valur lura fil-cache. Li jibqa 'huwa li timplimenta din il-klassi fl-applikazzjoni. Għandna bżonn il-klassijiet kollha li fl-applikazzjoni biex jitolbu implimentazzjoni tal-interface PostQueries beda jirċievi istanza tal-klassi CachedPostQueries. Madankollu, hu stess CachedPostQueries il-kostruttur għandu jirċievi klassi bħala parametru EloquentPostQueriesperess li ma jistax jaħdem mingħajr implimentazzjoni "reali". Nibdlu 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);
}
}
Ix-xewqat kollha tiegħi huma deskritti b'mod pjuttost naturali fil-fornitur. Għalhekk, implimentajna l-caching għat-talbiet tagħna biss billi ktibna klassi waħda u nbiddlu l-konfigurazzjoni tal-kontenitur. Il-bqija tal-kodiċi tal-applikazzjoni ma nbidilx.
Naturalment, biex timplimenta bis-sħiħ il-caching, huwa wkoll meħtieġ li tiġi implimentata l-invalidazzjoni sabiex l-artikolu mħassar ma jibqax fuq is-sit għal xi żmien, iżda jitħassar immedjatament. Iżda dawn huma affarijiet minuri.
Bottom line: użajna mhux wieħed, iżda żewġ mudelli. Kampjun Kmand Query Responsabbiltà Segregazzjoni (CQRS) jipproponi li l-operazzjonijiet tal-qari u tal-kitba jiġu separati kompletament fil-livell tal-interface. Wasalt għandu permezz Prinċipju tas-Segregazzjoni tal-Interface, li jissuġġerixxi li jien jimmanipula xejriet u prinċipji b'sengħa u nikseb wieħed mill-ieħor bħala teorema :) Naturalment, mhux kull proġett jeħtieġ astrazzjoni bħal din għall-għażla ta 'entitajiet, iżda se naqsam il-trick miegħek. Fl-istadju inizjali tal-applikazzjoni iżvilupp, tista 'sempliċement toħloq klassi PostQueries bl-implimentazzjoni tas-soltu permezz ta' Eloquent:
<?php
final class PostQueries
{
public function getById($id): Post
{
return Post::findOrFail($id);
}
// другие методы
}
Meta tqum il-ħtieġa għall-caching, b'ċaqliq sempliċi tista' toħloq interface (jew klassi astratta) minflok din il-klassi PostQueries, kopja l-implimentazzjoni tagħha fil-klassi EloquentPostQueries u mur fl-iskema li ddeskriviet qabel. Il-bqija tal-kodiċi tal-applikazzjoni m'għandux għalfejn jinbidel.
Dawn it-tricks kollha bi klassijiet, interfaces, Injezzjoni ta 'Dipendenza и CQRS deskritt fid-dettall fi
Sors: www.habr.com