Repositoria utilia cum eloquenti?

Ultima septimana scripsi articulus de inutilitate Repositorii templates Eloquenti entiatamen pollicitus est me ex parte uti suo commodo. Quod ut facias, conantur enucleare quomodo haec templates in inceptis adhiberi solet. Minimum requisitum methodorum repositio:

<?php
interface PostRepository
{
    public function getById($id): Post;
    public function save(Post $post);
    public function delete($id);
}

Attamen in inceptis realibus, si repositoria uti placuit, rationes recuperandi rationes illis saepe adiciuntur;

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

Hae methodi per ambitum disertum perfici possent, sed oneratis entitatis generibus cum officio se recipiendi optima notio non est, et hoc munus movens ad repositoria classes logica videtur. Itane est? Hoc instrumento in duas partes specialiter visibiliter distinxi. Prima pars modorum scribendarum adhibebitur operationum.

Vexillum scribe operatio est:

  • constructione de novo objecto et provocatione PostRepository :: nisi
  • PostRepository :: getByIdens manipulatio et vocatio PostRepository :: nisi
  • voca PostRepository :: delete

Scribere operationes non adhibent modos adducendi. In operationibus legere, modos modos adhibe. Si legeris Interface Segregation Principle (littera I в LIQUIDUS), tunc patebit nostrum interface nimis amplum esse ac saltem in duobus diversis officiis fungi. Sed tempus ut dui. Methodus getById in utroque necessarium est, sed quia applicatio incomplexior fit, exsecutiones differunt. Hoc paulo post videbimus. De inutilitate scribentis in superiore articulo scripseram, ita in hoc uno tantum obliviscar tui.

Lecta pars mihi non adeo inutilis videtur, cum etiam pro Eloquenti plura hic inserantur. Quid genus nominare? Can ReadPostRepositorysed ad template Demo Repository ille iam parum refert. Potes iustus PostQueries:

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

Eloquens id implens est admodum simplex;

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

Interface coniungi debet cum exsecutione, exempli gratia in AppServiceProvider:

<?php
final class AppServiceProvider extends ServiceProvider 
{
    public function register()
    {
        $this->app->bind(PostQueries::class, 
            EloquentPostQueries::class);
    }
}

Hoc genus iam utile est. Officium suum cognoscit sublevando vel moderatoris vel entitatis genus. In moderatore sic adhiberi potest:

<?php
final class PostsController extends Controller
{
    public function lastPosts(PostQueries $postQueries)
    {
        return view('posts.last', [
            'posts' => $postQueries->getLastPosts(),
        ]);
    }
} 

modum PostsController :: lastPosts sicut quidam implementation petendo PostsQueries et operatur cum eo. In provisor nos coniunctum PostQueries cum genus " EloquentPostQueries et haec classis in moderatorem substituetur.

Fingamus nostram applicationem valde popularem factam esse. Milia usorum per minute aperi paginam cum publicationibus recentioribus. In festis publicationibus etiam saepissime legitur. Database non bene tractant talia onera, ut solutione normae utuntur - cella. Praeter database, quaedam data snapshot reposita in repositione certarum operationum optimized - memcached aut redis.

Caching logica plerumque non est perplexa, sed eam in EloquentPostQueries non admodum recte exsequendam (si modo quia Officia unum principium). Multo magis naturale est uti a template Decorator et ad ornamentum principale actionis efficiendi caching:

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

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

Ignore interface Demo Repository in constructor. Aliqua causa ignota, statuerunt nominare interfaciem de caching in Laravel hoc modo.

Класс CachedPostQueries instrumentum caching tantum. $ This-> cache-> memento an hic introitus in cella sistit et an non, callback vocat et scribit valorem redditum ad cella. Reliquum est ut hoc genus in applicatione efficere possit. Omnibus generibus indigemus ut in applicatione ad exsequendam instrumenti quaestionem petendam PostQueries ad exemplum ordinis CachedPostQueries. Sed ipse CachedPostQueries constructor accipiendum genus pro modulo EloquentPostQueriesquia sine exsecutione "reali" operari non potest. Nos mutare 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);
    }
}

Omnia vota mea in provisore satis naturaliter descripta sunt. Itaque petitiones nostras tantum implevimus scribendo unam classem et mutando continentis figuram. Reliqua schedula in codice non mutata est.

Utique, ut caching plene instrumento, etiam ad infirmationem deducendam necessarium est ut articulus deletus non aliquandiu in situ pendeat, sed statim deleatur. Sed haec sunt minora.

Solum versus: non unum, sed duo exemplaria usi sumus. Sample Mandatum Query Cura Segregationis (CQRS) proponit operationes legere et scribere penitus in gradu interface. Veni ad eum per Interface Segregation Principlequae insinuat me sollerter exempla et principia manipulare et unum ab altero pro theoremate derivare :) Scilicet, non omne consilium eget tali abstractione entia eligenda, sed dolum tecum communicabo. progressio, simpliciter classem creare potes PostQueries solita exsecutione per Eloquens:

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

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

Cum necessitas caching oritur, simplici motui interfaciem (vel genus abstractum) creare potes in loco huius classis. PostQueries, effingo suum genus ad exsecutionem EloquentPostQueries et ad schema de quo supra dictum est. Reliqua schedula codicis mutanda non est.

Omnes hae doli cum classibus, valvis, Dependentia Iniectio и CQRS in speciali descriptus est liber meus "Architecture of Complex Applications Web". Etiam problema solutionis est cur omnes meae classes in exemplis huius articuli tamquam finales notentur.

Source: www.habr.com

Add a comment