سرفصل‌های آموزشی
آموزش الگوهای طراحی (Design Pattern)
پیاده سازی الگوی طراحی Observer در laravel

پیاده سازی الگوی طراحی Observer در laravel

پیاده سازی در لاراول

در قسمت قبل، ساختار الگوی طراحی Observer و یک مثال ساده از آن را با یکدیگر بررسی کردیم. در این مقاله قصد داریم تا پیاده سازی هایی از این الگوی طراحی را در فریمورک لاراول بررسی کنیم. برای شروع می‌توانیم یک مثال از Eloquent ها در لاراول بزنیم. هر مدلی که در eloquent لاراول ایجاد می کنیم در داخل خود دارای این الگو است.

برای مثال ما یک مدل به نام Car ایجاد می کنیم. در این مدل ما نوع ماشین، رنگ ماشین، سال ساخت و توضیحات را داریم.

<?php


namespace App;


use Illuminate\Database\Eloquent\Model;


class Car extends Model

{
    //
}

برای ساختن یک observer می‌توانیم از دستور php artisan make:observer observer_name استفاده کنیم که به جای observer_name از یک نام دلخواه استفاده می کنیم.

این دستور یک کلاس php در مسیر app\observers می سازد که هیچ محتوایی ندارد.

به صورت زیر:

<?php


namespace App\Observers;


class CarObserver

{
    

}

در Eloquent لاراول یک سری توابع به صورت پیش‌فرض ساخته شده اند که ما می توانیم آن ها را بازنویسی کرده و از آن ها استفاده کنیم. لیست این توابع به صورت زیر می باشد:

  • Creating: این تابع قبل از این که رکورد جدیدی بسازیم صدا زده می‌شود.
  • Created: این تابع بعد از این که رکورد جدیدی ساخته شد صدا زده می‌شود.
  • Updating: این تابع قبل از این که رکوردی را به‌روزرسانی کنیم صدا زده می‌شود.
  • Updated: این تابع بعد از این که رکوردی را به‌روزرسانی کردیم صدا زده می‌شود.
  • Saving: این تابع قبل از این که رکوردی ذخیره شود صدا زده می‌شود. (یا ساخته شود یا به‌روزرسانی شود)
  • Saved: این تابع بعد از این که رکوردی ذخیره شد صدا زده می‌شود (یا ساخته شود یا به‌روزرسانی شود)
  • Deleting: این تابع قبل از این که رکوردی حذف شود صدا زده می‌شود.
  • Deleted: این تابع بعد از این که رکوردی حذف شد صدا زده می‌شود.
  • Restoring: این تابع قبل از این که رکوردی بازیابی شود صدا زده می‌شود.
  • Restored: این تابع بعد از این که رکوردی بازیابی شد صدا زده می‌شود.

بعد از ایجاد توابع با این نام‌ها، تنها باید به لاراول بگوییم که این فایل observer برای چه کلاسی است.

<?php


namespace App\Observers;


class CarObserver

{
    public function creating($model)
    {
        print "creating model" . PHP_EOL;
    }

    public function created($model)
    {
        print "Created model" . PHP_EOL;
    }

    public function updating($model)
    {
        print "Updating model" . PHP_EOL;
    }

    public function updated($model)
    {
        print "updated model" . PHP_EOL;
    }

    public function saving($model)
    {
        print "saving model" . PHP_EOL;
    }

    public function saved($model)
    {
        print "saved model" . PHP_EOL;
    }

    public function deleting($model)
    {
        print "deleting model" . PHP_EOL;
    }

    public function deleted($model)
    {
        print "deleted model" . PHP_EOL;
    }

    public function restoring($model)
    {
        print "restoring model" . PHP_EOL;
    }

    public function restored($model)
    {
        print "restored model" . PHP_EOL;
    }

}

برای این کار می توانیم در فایل AppServiceProvider بگوییم که این فایل observer برای چه مدلی می باشد. (برای این کار بهتر است یک Service Provider جدید ساخته و در آن جا تعریف شود)

<?php


namespace App\Providers;


use App\Car;

use App\Observers\CarObserver;

use Illuminate\Support\ServiceProvider;


class AppServiceProvider extends ServiceProvider

{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Car::observe(CarObserver::class);
    }

}

بعد از این کار خروجی کد های ما به این صورت می شود.

$car1 = new Car;
$car1->description = "cool car description";
$car1->color = 'black';
$car1->manufacturer = 'Honda';
$car1->year = '2012';

print "\nCreating new car\n";
$car1->save();

خروجی

Creating new car 
saving model
creating model 
Created model 
saved model

در مثالی دیگر

$car1 = Car::find(1);
$car1->color = 'blue';

print "\nSaving car #1 to database\n";
$car1->save();

خروجی

Saving car #1 to database
saving model
Updating model
updated model
saved model

نتیجه

معماری رویداد محور (Event-driven architecture) یک الگوی معماری نرم‌افزار است، که به وسیله آن می‌توان تمام اتفاقات را ضبط و پردازش کرده و ارتباط وقایع با یکدیگر را کنترل و پیاده‌سازی کنیم. در این الگوی طراحی یک سری اتفاقاتی انجام می‌شوند که به وسیله observe ها با یکدیگر ارتباط داده شده و یک سیستم یکپارچه را به وجود می‌آورند. 

منابع

https://refactoring.guru/design-patterns/observer

https://laracasts.com/series/design-patterns-in-php

https://webdevetc.com/blog/observer-design-pattern-in-php

https://www.oreilly.com/library/view/learning-python-design/9781785888038/ch06s06.html

https://dev.to/hsmobio/what-is-laravel-model-observers-4723

https://www.amazon.com/Design-Patterns-Laravel-Kelt-Dockins-ebook/dp/B01MS1PHYW

online-support-icon