MVC (Laravel) nereye mantık eklenir


137

Diyelim ki bir CRUD işlemi yaptığımda veya bir ilişkiyi belirli bir şekilde değiştirdiğimde başka bir şey yapmak istiyorum. Örneğin, bir kişi her yayın gönderdiğinde, analiz için bir tabloya bir şeyler kaydetmek istiyorum. Belki en iyi örnek değil ama genel olarak bu "gruplandırılmış" işlevselliklerin çoğu var.

Normalde bu tip mantığın kontrolörlere konulduğunu görüyorum. Bu işlevselliği birçok yerde yeniden oluşturmak istediğinize kadar bu bir züppe. Kısmi parçalara girmeye, bir API oluşturmaya ve kukla içerik oluşturmaya başladığınızda, şeyleri KURU tutmakla ilgili bir sorun haline gelir.

Bunu yönetmek için gördüğüm yollar olaylar, depolar, kütüphaneler ve modellere ekleme. İşte her biri benim anlayışlarım:

Hizmetler: Burası çoğu insanın muhtemelen bu kodu koyacağı yerdir. Hizmetlerle ilgili asıl sorunum, bazen belirli işlevler bulmak zor ve insanların Eloquent kullanmaya odaklandıklarında unutuldukları hissediyorum. publishPost()Sadece yapabildiğimde kütüphanedeki bir yöntemi çağırmam gerektiğini nasıl bilebilirim $post->is_published = 1?

Bu iyi çalışır görmek tek koşul SADECE hizmetleri (ve ideal bir şekilde Eloquent erişilemez bir şekilde hep birlikte denetleyicileri yapmak) olmasıdır.

Nihayetinde, istekleriniz genellikle model yapınızı takip ederse, bu bir sürü ekstra gereksiz dosya yaratacaktır.

Depolar: Anladığım kadarıyla bu temelde bir hizmet gibidir, ancak bir arayüz var, böylece ihtiyacım olmayan ORM'ler arasında geçiş yapabilirsiniz.

Olaylar: Bunu bir anlamda en zarif sistem olarak görüyorum çünkü model olaylarınızın her zaman Eloquent yöntemlerinde çağrıldığını biliyorsunuz, böylece kontrol cihazlarınızı normalde yaptığınız gibi yazabilirsiniz. Bunların yine de dağınık olduğunu görebiliyorum ve herhangi birinin kritik bağlantı için olayları kullanan büyük projelerden örnekleri varsa görmek istiyorum.

Modeller: Geleneksel olarak CRUD yapan ve eleştirel bağlantıyı ele alan derslerim olurdu. Bu aslında işleri kolaylaştırdı çünkü CRUD + çevresindeki tüm işlevsellikleri biliyordunuz.

Basit, ama MVC mimarisinde bu normalde gördüğüm şey değil. Bir anlamda, hizmetleri biraz daha tercih ettiğimden ve takip edilmesi gereken daha az dosya olduğu için bunu hizmetleri tercih etsem de. Yine de biraz dağınık olabilir. Bu yönteme ve neden çoğu insanın bunu yapmadığına dair düşüşler duymak istiyorum.

Her yöntemin avantajları / dezavantajları nelerdir? Bir şey mi kaçırıyorum?


3
Sorunuzu en aza indirebilir misiniz?
Alfa

3
Ayrıca bunu kontrol edebilirsiniz .
Alfa

1
"Ben sadece $ post-> is_published = 1 yapabildiğimde bir kütüphanede bir yöntem PublishPost () çağırmak gerektiğini nasıl bilebilirim?" Belgeler?
ceejayoz

etkili ve ORMS ile ilgili güzelliklerden biri, onlarla çok fazla doküman olmadan çalışmak daha kolay mı?
Sabrina Leggett

1
Bunu gönderdiğiniz için teşekkürler. Aynı sorunlarla mücadele ediyorum ve mesajınızı buldum ve yanıtınızı inanılmaz faydalı buldum. Sonuçta Laravel'in hızlı ve kirli Ruby-on-Rails web sitesinin ötesine uzanan bir şey için iyi bir mimari sağlamadığına karar verdim. Her yerde hareket eder, sınıf işlevlerini bulmada zorluk ve her yerde tonlarca otomatik sihirli çöp. ORM hiç çalışmadı ve kullanıyorsanız, muhtemelen NoSQL kullanıyor olmalısınız.
Alex Barker

Yanıtlar:


171

Sunulan tüm desenlerin / mimarilerin, SOLID ilkelerine uyduğunuz sürece çok yararlı olduğunu düşünüyorum .

İçin mantığı eklemek için nerede ben başvurmak için önemli olduğunu düşünüyorum Tek Sorumluluk Prensibi . Ayrıca, cevabım orta / büyük bir proje üzerinde çalıştığınızı düşünüyor. Sayfada bir şey atma projesi ise, bu cevabı unutun ve hepsini denetleyicilere veya modellere ekleyin.

Kısa cevap: Sizin için mantıklı olduğu yer (hizmetler ile) .

Uzun cevap:

Kontrolörler : Kontrolörlerin sorumluluğu nedir? Elbette, tüm mantığınızı bir denetleyiciye koyabilirsiniz, ancak denetleyicinin sorumluluğu bu mu? Ben öyle düşünmüyorum.

Benim için, denetleyici bir istek almalı ve veri döndürmelidir ve burası onaylar, çağrı db yöntemleri vb.

Modeller : Bu, bir kullanıcı bir kaydın kaydını yaptığında veya bir oylamanın oy sayısını güncellediğinde hoş geldiniz e-postası göndermek gibi bir mantık eklemek için iyi bir yer mi? Kodunuzdaki başka bir yerden aynı e-postayı göndermeniz gerekirse ne olur? Statik bir yöntem oluşturuyor musunuz? Bu e-postaların başka bir modelden bilgiye ihtiyacı varsa ne olur?

Modelin bir varlığı temsil etmesi gerektiğini düşünüyorum. Laravel ile, ben sadece gibi şeyler eklemek için modeli sınıfını kullanın fillable, guarded, table(aksi modeli de olurdu, ben Depo Desen kullandığından bu ve ilişkileri save, update, findvb yöntemleri).

Depolar (Depo Deseni) : Başlangıçta bununla kafam çok karışmıştı. Ve senin gibi "iyi, MySQL kullanıyorum ve işte bu." Diye düşündüm.

Ancak, Repository Pattern'i kullanmanın artılarını ve eksilerini dengeledim ve şimdi kullanıyorum. Ben düşünüyorum şimdi , tam şu anda, sadece MySQL kullanmak gerekecektir. Ancak, üç yıl sonra MongoDB gibi bir şeye geçmem gerekiyorsa, işlerin çoğu yapılır. Tüm ekstra bir arayüz pahasına ve bir $app->bind(«interface», «repository»).

Olaylar ( Gözlemci Deseni ): Olaylar, herhangi bir zamanda herhangi bir sınıfta atılabilecek şeyler için kullanışlıdır. Örneğin, bir kullanıcıya bildirim göndermeyi düşünün. İhtiyacınız olduğunda, başvurunuzun herhangi bir sınıfına bildirim göndermek için etkinliği tetiklersiniz. Ardından, UserNotificationEventskullanıcı bildirimleri için tüm tetiklenen etkinliklerinizi işleyen böyle bir sınıfınız olabilir .

Hizmetler : Şimdiye kadar kontrolörlere veya modellere mantık ekleme seçeneğiniz var. Benim için, Hizmetleri içerisine mantığı eklemek mantıklı . Kabul edelim, Hizmetler sınıflar için süslü bir isim. Ve uygulamanızda sizin için anlamlı olduğu kadar çok sınıfa sahip olabilirsiniz.

Bu örneği ele alalım: Kısa bir süre önce Google Formlar gibi bir şey geliştirdim. Ben ile başladı CustomFormServiceve ile sona erdi CustomFormService, CustomFormRender, CustomFieldService, CustomFieldRender, CustomAnswerServiceve CustomAnswerRender. Neden? Çünkü bu bana mantıklı geldi. Eğer bir takımla çalışıyorsanız, mantığınızı takıma mantıklı bir yere koymalısınız.

Hizmetler ve Denetleyiciler / Modeller kullanmanın avantajı, tek bir Denetleyici veya tek bir Model tarafından kısıtlanmamanızdır. Uygulamanızın tasarımına ve ihtiyaçlarına göre gerektiği kadar çok hizmet oluşturabilirsiniz. Buna, uygulamanızın herhangi bir sınıfında bir Hizmet çağırmanın avantajını da ekleyin.

Bu uzun sürüyor, ancak başvurumu nasıl yapılandırdığımı size göstermek istiyorum:

app/
    controllers/
    MyCompany/
        Composers/
        Exceptions/
        Models/
        Observers/
        Sanitizers/
        ServiceProviders/
        Services/
        Validators/
    views
    (...)

Her klasörü belirli bir işlev için kullanıyorum. Örneğin,Validators dizini içeren BaseValidatorgöre doğrulama işleme sorumlu sınıf, $rulesve $messages(her model için, genellikle bir adet), belirli doğrulayıcılarının. Kolayca bu kodu bir Hizmet içine koymak olabilir, ama sadece hizmet içinde (şimdilik) kullanılsa bile bu için belirli bir klasör olması bana mantıklı.

Size bazı şeyleri daha iyi açıklayabilecekleri için aşağıdaki makaleleri okumanızı tavsiye ederim:

Kalıbı Dayle Rees ile Kırma ( yazarı): Gereksinimlerimi karşılamak için birkaç şeyi değiştirmeme rağmen, hepsini bir araya getirdim.

Chris Goosey tarafından Depolar ve Hizmetler kullanılarak Laravel'de kodunuzun ayrıştırılması: Bu yazı, Hizmet ve Depo Deseni'nin ne olduğunu ve bunların birbirine nasıl uyduğunu açıklamaktadır.

Laracasts ayrıca pratik örnekler ile iyi kaynaklar olan Basitleştirilmiş Depolar ve Tek Sorumluluk'a sahiptir (ödemek zorunda olsanız bile).


3
harika bir açıklama. İşte şu anda durduğum yer - şu anki projede iş mantığımı modellere koyuyorum ve aslında çok iyi çalışıyor. Kesinlikle SOLID'i biraz yumuşatmamız gerekiyor, ama henüz bizi belaya sokmadı. Hızlı, biraz kirli, ama şu ana kadar projemiz çok sürdürülebilir çünkü çok KURU. İşi hallettikleri için şu an onlara bağlı kalıyorum, ancak gelecekteki herhangi bir projede muhtemelen sadece standart olan her şeye gideceğim, ki depolar gibi geliyor.
Sabrina Leggett

2
Size mantıklı gelen bir yol bulduğunuza sevindim. Bugün yaptığınız varsayımlara dikkat edin . 3+ yıl boyunca bir proje üzerinde çalıştım ve 5000+ kodlu kontrolörler ve modeller ile sona erdim. Projenizde iyi şanslar.
Luís Cruz

Ayrıca biraz kirli ama modelleri devasa önlemek için özellikleri kullanmayı düşünüyordum. Bu şekilde onları biraz ayırabilirim
Sabrina Leggett

Bu makalede, hizmetlerin kullanılması mantıklı olduğu zaman iyi bir şekilde ifade edilmektedir. Form örneğinizde hizmetleri kullanmak mantıklıdır, ancak hizmetin nasıl yapıldığını açıklar; mantık doğrudan bu modele koyduğu bir modelle ilişkilidir. justinweiss.com/articles/where-do-you-put-your-code
Sabrina Leggett

Açıklamayı gerçekten çok seviyorum. Bir sorum var: denetleyiciye doğrulama yapmamanızdan bahsettiniz, bu yüzden doğrulama yapmak için en iyi yer neresi sizce? Birçoğu bunu genişletilmiş Request sınıfına koymayı önerir (ve şu anda ne yapıyoruz), ama sadece http isteğinde değil, aynı zamanda esnaf komutunda, vb.
kingshark

24

Kendi soruma cevap vermek istedim. Günlerce bunun hakkında konuşabilirim, ama kalktığımdan emin olmak için bunu hızlı bir şekilde yayınlamaya çalışacağım.

Laravel'in sağladığı mevcut yapıyı kullandım, yani dosyalarımı Model, Görünüm ve Denetleyici olarak sakladım. Ayrıca, gerçekten model olmayan yeniden kullanılabilir bileşenler için bir Kitaplıklar klasörünüz var.

MODELLERİMİ HİZMETLERE / KÜTÜPHANELERE SARMADI . Sağlanan tüm nedenler% 100 beni hizmet kullanmanın yararına ikna etmedi. Yanılmama rağmen, gördüğüm kadarıyla, sadece modellerle çalışırken oluşturmam ve aralarında geçiş yapmam gereken tonlarca ekstra neredeyse boş dosyaya neden oluyorlar ve ayrıca eloquent kullanmanın faydasını gerçekten azaltıyorlar (özellikle RETRIEVING modelleri söz konusu olduğunda) ör. sayfalama, kapsamlar vb. kullanarak).

İş mantığını MODELLERE yerleştirdim ve doğrudan kontrolörlerimden güzelce erişiyorum. İş mantığının atlanmadığından emin olmak için bir dizi yaklaşım kullanıyorum:

  • Erişimciler ve mutasyoncular: Laravel'in harika erişimciler ve mutasyoncular var. Bir gönderi taslağından yayınlanmaya her taşındığında bir eylem gerçekleştirmek isterseniz bunu setIsPublishedAttribute işlevini oluşturarak ve mantığı oraya dahil ederek çağırabilirim
  • Oluşturma / Güncelleme vb. Geçersiz kılma: Özel işlevsellik eklemek için modellerinizdeki Her Zamanki yöntemleri geçersiz kılabilirsiniz. Bu şekilde herhangi bir CRUD işleminde işlevselliği çağırabilirsiniz. Düzenleme: Ben yeni Laravel sürümlerinde oluşturma geçersiz kılma ile bir hata olduğunu düşünüyorum (bu yüzden şimdi önyükleme kayıtlı olayları kullanmak)
  • Doğrulama: Doğrulamamı aynı şekilde bağlarım, örneğin, gerekirse CRUD işlevlerini ve ayrıca erişimcileri / mutatörleri geçersiz kılarak doğrulamayı çalıştıracağım. Daha fazla bilgi için Esensi veya dwightwatson / validating konusuna bakın.
  • Sihirli Yöntemler: Modellerimin __get ve __set yöntemlerini uygun olan yerlerde işlevselliğe bağlamak için kullanıyorum
  • Eloquent'i Genişletme: Tüm güncelleme / oluşturma işlemlerini gerçekleştirmek istediğiniz bir eylem varsa, hatta eloquent'i genişletebilir ve birden fazla modele uygulayabilirsiniz.
  • Olaylar: Bu oldukça basittir ve genellikle bunu yapmak için kararlaştırılmıştır. Olaylarla ilgili en büyük dezavantaj, istisnaların takip edilmesinin zor olduğunu düşünüyorum (Laravel'in yeni olay sistemindeki yeni durum olmayabilir). Ayrıca, etkinliklerimi çağrıldıklarında yaptıklarına göre gruplandırmayı da seviyorum ... örneğin, posta gönderen olayları dinleyen bir MailSender abonesi var.
  • Pivot / BelongsToMany Etkinlikleri Ekleme: En uzun süre mücadele ettiğim şeylerden biri, belongsToMany ilişkilerinin modifikasyonuna nasıl davranış ekleneceğiydi. Örneğin, bir kullanıcı bir gruba her katıldığında bir eylem gerçekleştirme. Bunun için özel bir kütüphaneyi cilalamak üzereydim. Henüz yayınlamadım ama işlevsel! Yakında bir bağlantı göndermeye çalışacağız. EDIT Tüm pivotlarımı normal modellere dönüştürdüm ve hayatım çok daha kolay oldu ...

İnsanların modelleri kullanma konusundaki endişelerini gidermek:

  • Organizasyon: Evet, modellere daha fazla mantık eklerseniz, daha uzun olabilirler, ancak genel olarak modellerimin% 75'inin hala oldukça küçük olduğunu gördüm. Daha büyük olanları organize etmeyi seçtiğimde, özellikleri kullanarak yapabilirim (örneğin, PostScopes, PostAccessors, PostValidation, vb. Gibi daha fazla dosya içeren model için bir klasör oluşturun). Bu özelliklerin ne için gerekli olduğunu biliyorum ama bu sistem sorunsuz çalışıyor.

Ek Not: Modellerinizi servislere sarmak, bir sürü ordu bıçağına sahip, bir sürü araçla ve etrafında aynı şeyi yapan başka bir bıçak inşa etmek gibi bir şey mi hissediyorum? Evet, bazen bir bıçağı bantlamak veya iki bıçağın birlikte kullanıldığından emin olmak isteyebilirsiniz ... ancak bunu yapmanın tipik başka yolları da vardır ...

HİZMETLERİ NE ZAMAN KULLANACAĞINIZ : Bu makalede, hizmetlerin ne zaman kullanılacağı konusunda BÜYÜK örnekler bulunmaktadır ( ipucu: çok sık değil ). Temel olarak, nesneniz yaşam döngülerinin garip kısımlarında birden fazla model veya model kullandığında mantıklı olduğunu söylüyor . http://www.justinweiss.com/articles/where-do-you-put-your-code/


2
İlginç ve geçerli düşünceler. Ama merak ediyorum - Eloquent'a bağlı, veritabanına bağlı modellere bağlıysa iş mantığınızı nasıl birim test ediyorsunuz?
JustAMartin

code.tutsplus.com/tutorials/… ya da daha fazla yıkmak istiyorsanız dediğim gibi olayları kullanabilirsiniz
Sabrina Leggett

1
@JustAMartin, birim testlerinizde sadece veritabanını kullanamayacağınızdan emin misiniz? Bunu yapmamanın nedeni nedir? Birçok kişi, birim testlerinde veritabanını kullanmanın genellikle uygun olduğunu kabul eder. (Martin Fowler, martinfowler.com/bliki/UnitTest.html : "Dış kaynaklar için iki katını mutlak bir kural olarak kullanmayı düşünmüyorum. Kaynakla konuşmak sizin için yeterince istikrarlı ve hızlıysa, yapmamanız için hiçbir neden yok birim testlerinizde ")
Alex P.

@ AlexP11223 Evet, bu mantıklı. SQLite'ı test veritabanım olarak entegre etmeye çalıştım ve SQLite Laravel geçişleri ve özel sorgularda (varsa) hesaba katılması gereken bazı ciddi sınırlamalara sahip olmasına rağmen genel olarak iyi gitti. Tabii ki, bunlar kesinlikle birim testler değil, fonksiyonel testlerdir, ancak bu şekilde daha da etkilidir. Yine de, modelinizi tamamen izole etmek istiyorsanız (katı bir birim testi olarak), dikkat çekici miktarda ek kod (alaylar vb.) Gerektirebilir.
JustAMartin

22

Denetleyiciler ve modeller arasında mantık oluşturmak için kullandığım şey bir hizmet katmanı oluşturmaktır . Temel olarak, bu benim app içinde herhangi bir eylem için benim akış:

  1. Denetleyici kullanıcının istediği eylemi alır ve parametreleri gönderir ve her şeyi bir hizmet sınıfına devreder.
  2. Hizmet sınıfı, işlemle ilgili tüm mantığı yapar: giriş doğrulama, olay günlüğü tutma, veritabanı işlemleri, vb.
  3. Model, alan bilgileri, veri dönüşümü ve öznitelik doğrulama tanımlarını içerir.

Bunu nasıl yaparım:

Bir şey oluşturmak için bir denetleyicinin yöntemi:

public function processCreateCongregation()
{
    // Get input data.
    $congregation                 = new Congregation;
    $congregation->name           = Input::get('name');
    $congregation->address        = Input::get('address');
    $congregation->pm_day_of_week = Input::get('pm_day_of_week');
    $pmHours                      = Input::get('pm_datetime_hours');
    $pmMinutes                    = Input::get('pm_datetime_minutes');
    $congregation->pm_datetime    = Carbon::createFromTime($pmHours, $pmMinutes, 0);

    // Delegates actual operation to service.
    try
    {
        CongregationService::createCongregation($congregation);
        $this->success(trans('messages.congregationCreated'));
        return Redirect::route('congregations.list');
    }
    catch (ValidationException $e)
    {
        // Catch validation errors thrown by service operation.
        return Redirect::route('congregations.create')
            ->withInput(Input::all())
            ->withErrors($e->getValidator());
    }
    catch (Exception $e)
    {
        // Catch any unexpected exception.
        return $this->unexpected($e);
    }
}

Bu işlemle ilgili mantığı yapan hizmet sınıfıdır:

public static function createCongregation(Congregation $congregation)
{
    // Log the operation.
    Log::info('Create congregation.', compact('congregation'));

    // Validate data.
    $validator = $congregation->getValidator();

    if ($validator->fails())
    {
        throw new ValidationException($validator);
    }

    // Save to the database.
    $congregation->created_by = Auth::user()->id;
    $congregation->updated_by = Auth::user()->id;

    $congregation->save();
}

Ve bu benim modelim:

class Congregation extends Eloquent
{
    protected $table = 'congregations';

    public function getValidator()
    {
        $data = array(
            'name' => $this->name,
            'address' => $this->address,
            'pm_day_of_week' => $this->pm_day_of_week,
            'pm_datetime' => $this->pm_datetime,
        );

        $rules = array(
            'name' => ['required', 'unique:congregations'],
            'address' => ['required'],
            'pm_day_of_week' => ['required', 'integer', 'between:0,6'],
            'pm_datetime' => ['required', 'regex:/([01]?[0-9]|2[0-3]):[0-5]?[0-9]:[0-5][0-9]/'],
        );

        return Validator::make($data, $rules);
    }

    public function getDates()
    {
        return array_merge_recursive(parent::getDates(), array(
            'pm_datetime',
            'cbs_datetime',
        ));
    }
}

Bu yol hakkında daha fazla bilgi için Laravel uygulaması için kodumu düzenlemek üzere kullanıyorum: https://github.com/rmariuzzo/Pitimi


Postalarımda kütüphane olarak adlandırdığım hizmetler gibi görünüyor. Birden fazla ORMS kullanmanız gerekmiyorsa, bunun depolardan daha iyi olduğunu düşünüyorum, ancak sorun, tüm projenizi (olaylarla ilgili olmak zorunda değilsiniz) taşımak zorunda olduğunuz ve bu gibi görünüyor. Model yapısını yansıtmaya başlıyor, böylece tüm bu ekstra dosyalara sahipsiniz. Neden sadece modellere dahil edilmiyor? En azından bu şekilde fazladan dosyalarınız yok.
Sabrina Leggett

Bu ilginç bir soru @SabrinaGelbart, modellerin veritabanı varlıklarını temsil etmesine izin vermesi ve herhangi bir mantık taşımaması öğretildi. Hizmetler olarak adlandırılan bu ekstra dosyaları yaratmamın nedeni budur: tüm mantığı ve ekstra işlemleri tutmak. Daha önce tanımladığınız olayların bütün anlamının ne olduğundan emin değilim, ama hizmetlerle ve Laravel'in olaylarını kullanarak başlangıçta ve sonunda olayları başlatmak için tüm hizmet yöntemlerini yapabiliriz. Bu şekilde herhangi bir olay mantıktan tamamen ayrılabilir. Ne düşünüyorsun?
Rubens Mariuzzo

Bana modeller hakkında da öğretildi ... neden (belki bağımlılık sorunları) için iyi bir açıklama almak güzel olurdu?
Sabrina Leggett

Bu yaklaşımı seviyorum! Modelin mantığını nasıl ele almamız gerektiğine dair bir fikir edinmek için internet aradım, Depolara baktım ama biraz kullanım için çok karmaşık ve işe yaramaz görünüyordu. Hizmetler iyi bir fikirdir. Benim sorum app klasöründe bir Hizmetler klasörü oluşturduktan sonra, git bulamadım çünkü bootstrap / start.php veya önyükleme için herhangi bir yere dahil etmek zorunda mı? @RubensMariuzzo. Uygulama olmadan otomatik olarak kullanılabilir mi? böylece sadece CongregationService :: getCongregations (); ??
Oğuzhan

1
Yaptığın tek şey $congregation->save();belki de Depolara ihtiyacın olmayacaksa. Ancak, veri erişim ihtiyaçlarınızın zamanla arttığını görebilirsiniz. Sen için ihtiyaçları bulunduğu başlayabilir $congregation->destroyByUser()veya $congregationUsers->findByName($arrayOfSelectedFields);vb. Neden hizmetlerinizi veri erişim gereksinimlerinden ayırmıyorsunuz? Uygulamanızın geri kalanının depolardan döndürülen nesneler / dizilerle çalışmasına izin verin ve sadece manipüle / biçimlendirme / vb.
prograhammer

12

Bence Laravel, iş mantığınızı saklamanız için zaten birçok seçeneğe sahip.

Kısa cevap:

  • Girişinizi Requestotomatik olarak doğrulamak için laravel'in nesnelerini kullanın ve ardından istekte bulunan verileri devam ettirin (modeli oluşturun). Tüm kullanıcı girişi istekte doğrudan bulunduğundan , bunu burada yapmanın mantıklı olduğuna inanıyorum.
  • JobBağımsız bileşenler gerektiren görevleri gerçekleştirmek için laravel'in nesnelerini kullanın , sonra bunları gönderin. Sanırım Jobhizmet sınıflarını kapsıyor. İş mantığı gibi bir görev yaparlar.

Uzun (er) cevap:

Gerektiğinde Rezervuar Kullanın: Havuzlar aşırı şişirilmelidir ve çoğu zaman accessormodel için basitçe kullanılır . Kesinlikle biraz faydası varmış gibi hissediyorum, ama tamamen denemek, havuzlardan uzak durmak için bu kadar esneklik gerektiren büyük bir uygulama geliştirmiyorsanız . Daha sonra kendinize teşekkür edeceksiniz ve kodunuz çok daha basit olacak.

PHP çerçevelerini veya laravel'in desteklemediği bir veritabanı türünü değiştirme olasılığınız olup olmadığını kendinize sorun .

Cevabınız "Muhtemelen hayır" ise, depo modelini uygulamayın.

Yukarıdakilere ek olarak, lütfen Eloquent gibi mükemmel bir ORM'nin üzerine bir desen atmayın. Sadece gerekli olmayan karmaşıklığı ekliyorsunuz ve size hiç faydası olmayacak.

Hizmetleri idareli kullanın: Bana verilen hizmet sınıfları, belirli bir görevi yerine getirmek için iş mantığının depolandığı bir yerdir. Laravel bunları 'İşler' olarak adlandırıyor ve özel bir Servis sınıfından çok daha fazla esnekliğe sahip.

Laravel'in MVCmantık problemi için çok yönlü bir çözümü olduğunu hissediyorum . Bu sadece bir mesele veya organizasyon.

Misal:

İstek :

namespace App\Http\Requests;

use App\Post;
use App\Jobs\PostNotifier;
use App\Events\PostWasCreated;
use App\Http\Requests\Request;

class PostRequest extends Request
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title'       => 'required',
            'description' => 'required'
        ];
    }

    /**
     * Save the post.
     *
     * @param Post $post
     *
     * @return bool
     */
    public function persist(Post $post)
    {
        if (!$post->exists) {
            // If the post doesn't exist, we'll assign the
            // post as created by the current user.
            $post->user_id = auth()->id();
        }

        $post->title = $this->title;
        $post->description = $this->description;

        // Perform other tasks, maybe fire an event, dispatch a job.

        if ($post->save()) {
            // Maybe we'll fire an event here that we can catch somewhere else that
            // needs to know when a post was created.
            event(new PostWasCreated($post));

            // Maybe we'll notify some users of the new post as well.
            dispatch(new PostNotifier($post));

            return true;
        }

        return false;
    }
}

Denetleyici :

namespace App\Http\Controllers;

use App\Post;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{

   /**
    * Creates a new post.
    *
    * @return string
    */
    public function store(PostRequest $request)
    {
        if ($request->persist(new Post())) {
            flash()->success('Successfully created new post!');
        } else {
            flash()->error('There was an issue creating a post. Please try again.');
        }

        return redirect()->back();
    }

   /**
    * Updates a post.
    *
    * @return string
    */
    public function update(PostRequest $request, $id)
    {
        $post = Post::findOrFail($id);

        if ($request->persist($post)) {
            flash()->success('Successfully updated post!');
        } else {
            flash()->error('There was an issue updating this post. Please try again.');
        }

        return redirect()->back();
    }
}

Yukarıdaki örnekte, istek girişi otomatik olarak doğrulanır ve tek yapmamız gereken persist yöntemini çağırmak ve yeni bir Gönderi aktarmaktır. Bence okunabilirlik ve sürdürülebilirlik her zaman karmaşık ve gereksiz tasarım kalıplarını sarsmalıdır.

Daha sonra gönderilerin güncellenmesi için de aynı kalıcı yöntemi kullanabilirsiniz, çünkü gönderinin zaten var olup olmadığını kontrol edebilir ve gerektiğinde alternatif mantık gerçekleştirebiliriz.


ancak - işlerin sıraya alınması gerekmiyor mu? Bazen muhtemelen sıraya alınmasını isteriz, ama her zaman değil. Bunun yerine neden komutları kullanmıyorsunuz? Komut veya olay olarak veya kuyruğa alınmış olarak çalıştırılabilecek bir iş mantığı yazmak isterseniz ne olur?
Sabrina Leggett

1
İşlerin sıraya alınmasına gerek yoktur. Arayüzü ShouldQueueLaravel'in sağladığı işe uygulayarak belirtirsiniz. İş mantığını bir komut veya etkinliğe yazmak istiyorsanız, işi bu olayların / komutların içine atın. Laravels işleri son derece esnektir, ancak sonunda sadece basit hizmet sınıflarıdır.
Steve Bauman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.