نماها
معرفی
نماها یک رابط "ایستا" را برای کلاس هایی که در کانتینر سرویس برنامه در دسترس هستند ارائه می کنند . لاراول دارای نماهای زیادی است که تقریباً به تمام ویژگی های لاراول دسترسی دارد. نماهای لاراول به عنوان "پراکسی های استاتیک" برای کلاس های زیرین در کانتینر سرویس عمل می کنند و از یک نحو مختصر و رسا استفاده می کنند و در عین حال تست پذیری و انعطاف پذیری بیشتری نسبت به روش های استاتیک سنتی حفظ می کنند.
تمام نماهای لاراول در
Illuminate\Support\Facades
فضای نام تعریف شده اند.
بنابراین، ما به راحتی می توانیم به نماهایی مانند این دسترسی داشته باشیم:
use Illuminate\Support\Facades\Cache; Route::get('/cache', function () { return Cache::get('key');});
در سراسر مستندات لاراول، بسیاری از نمونه ها از نماها برای نشان دادن ویژگی های مختلف چارچوب استفاده می کنند.
زمان استفاده از نما
نماها مزایای زیادی دارند. آنها یک نحو مختصر و به یاد ماندنی ارائه می دهند که به شما امکان می دهد از ویژگی های لاراول بدون به خاطر سپردن نام کلاس های طولانی استفاده کنید که باید به صورت دستی تزریق یا پیکربندی شوند. علاوه بر این، به دلیل استفاده منحصر به فرد آنها از روش های پویا PHP، آزمایش آنها آسان است.
با این حال در استفاده از نما باید کمی دقت کرد. خطر اولیه نماها خزش محدوده طبقه است. از آنجایی که استفاده از نماها بسیار آسان است و نیازی به تزریق ندارند، می توان به راحتی اجازه داد کلاس های شما به رشد خود ادامه دهند و از نماهای زیادی در یک کلاس استفاده کنند. با استفاده از تزریق وابستگی، این پتانسیل با بازخورد بصری که یک سازنده بزرگ به شما می دهد که کلاس شما بیش از حد بزرگ می شود، کاهش می یابد. پس در استفاده از نما به اندازه کلاس خود توجه ویژه ای داشته باشید تا دامنه مسئولیت آن باریک بماند.
هنگام ساخت یک بسته شخص ثالث که با لاراول در تعامل است، بهتر است به جای استفاده از نما، قراردادهای لاراول را تزریق کنید. از آنجایی که بستهها خارج از خود لاراول ساخته میشوند، به کمککنندگان تست نمای لاراول دسترسی نخواهید داشت.
نماها در مقابل تزریق وابستگی
یکی از مزایای اولیه تزریق وابستگی، امکان تعویض پیاده سازی کلاس تزریق شده است. این در حین آزمایش مفید است زیرا میتوانید یک مدل ساختگی یا خرد تزریق کنید و ادعا کنید که روشهای مختلفی در مقاله خرد خوانده شده است.
به طور معمول، تقلید یا خرد کردن یک روش کلاس واقعاً ایستا ممکن نیست. با این حال، از آنجایی که نماها از روشهای پویا برای فراخوانی روش پراکسی به اشیاء حلشده از کانتینر سرویس استفاده میکنند، ما در واقع میتوانیم نماها را دقیقاً مانند نمونه کلاس تزریقی آزمایش کنیم. به عنوان مثال، با توجه به مسیر زیر:
use Illuminate\Support\Facades\Cache; Route::get('/cache', function () { return Cache::get('key');});
میتوانیم تست زیر را بنویسیم تا تأیید کنیم که
Cache::get
متد با آرگومان مورد انتظار فراخوانی شده است:
use Illuminate\Support\Facades\Cache; /** * A basic functional test example. * * @return void */public function testBasicExample(){ Cache::shouldReceive('get') ->with('key') ->andReturn('value'); $this->visit('/cache') ->see('value');}
نماها در مقابل توابع کمکی
علاوه بر نماها، لاراول شامل انواع مختلفی از توابع کمکی است که می تواند وظایف رایجی مانند تولید نماها، شلیک رویدادها، ارسال کارها یا ارسال پاسخ های HTTP را انجام دهد. بسیاری از این توابع کمکی همان عملکرد یک نمای مربوطه را انجام می دهند. برای مثال، این فراخوانی نما و فراخوانی کمکی معادل هستند:
return View::make('profile'); return view('profile');
مطلقاً هیچ تفاوت عملی بین نما و عملکرد کمکی وجود ندارد. هنگام استفاده از توابع کمکی، همچنان می توانید آنها را دقیقاً مانند نمای مربوطه آزمایش کنید. به عنوان مثال، با توجه به مسیر زیر:
Route::get('/cache', function () { return cache('key');});
در زیر کاپوت،
cache
کمک کننده قرار است
get
متد را در کلاس زیرین
Cache
نما فراخوانی کند.
بنابراین، حتی اگر از تابع helper استفاده میکنیم، میتوانیم تست زیر را
بنویسیم تا تأیید کنیم که متد با آرگومان مورد انتظار فراخوانی شده است:
use Illuminate\Support\Facades\Cache; /** * A basic functional test example. * * @return void */public function testBasicExample(){ Cache::shouldReceive('get') ->with('key') ->andReturn('value'); $this->visit('/cache') ->see('value');}
نحوه کار نماها
در برنامه لاراول، نما کلاسی است که دسترسی به یک شی را از کانتینر فراهم می
کند.
ماشین آلاتی که این کار را می کند در
Facade
کلاس است.
نماهای لاراول و هر نمای سفارشی که ایجاد می کنید،
Illuminate\Support\Facades\Facade
کلاس پایه را گسترش می دهد.
کلاس پایه از
روش جادویی برای به تعویق انداختن تماس ها از نمای شما به یک شی که از
کانتینر حل شده است
Facade
استفاده می کند .
__callStatic()
در مثال زیر، یک تماس با سیستم کش لاراول برقرار شده است.
با نگاهی اجمالی به این کد، می توان فرض کرد که متد static
get
در کلاس فراخوانی می شود
Cache
:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller;use Illuminate\Support\Facades\Cache; class UserController extends Controller{ /** * Show the profile for the given user. * * @param int $id * @return Response */ public function showProfile($id) { $user = Cache::get('user:'.$id); return view('profile', ['user' => $user]); }}
توجه داشته باشید که در نزدیکی بالای فایل ما در حال "وارد کردن"
Cache
نما هستیم.
این نما به عنوان یک پروکسی برای دسترسی به پیاده سازی اساسی رابط عمل می
کند
Illuminate\Contracts\Cache\Factory
.
هر تماسی که با استفاده از نما انجام دهیم به نمونه اصلی سرویس کش لاراول
منتقل می شود.
اگر به آن کلاس نگاه کنیم
Illuminate\Support\Facades\Cache
، خواهید دید که هیچ متد ثابتی وجود ندارد
get
:
class Cache extends Facade{ /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'cache'; }}
در عوض،
Cache
نما کلاس پایه را گسترش می دهد
Facade
و روش را تعریف می کند
getFacadeAccessor()
.
وظیفه این روش برگرداندن نام یک کانتینر سرویس است.
هنگامی که کاربر به هر روش ایستا در
Cache
نما ارجاع می دهد، لاراول
cache
اتصال از
کانتینر سرویس
را حل می کند و متد درخواستی (در این مورد،
get
) را بر روی آن شی اجرا می کند.
نماهای بلادرنگ
با استفاده از نماهای بلادرنگ، ممکن است با هر کلاسی در برنامه خود به گونه
ای رفتار کنید که گویی یک نما است.
برای نشان دادن اینکه چگونه می توان از آن استفاده کرد، بیایید یک جایگزین
را بررسی کنیم.
برای مثال، فرض کنید
Podcast
مدل ما یک
publish
روش دارد.
با این حال، برای انتشار پادکست، باید یک
Publisher
نمونه را تزریق کنیم:
<?php namespace App; use App\Contracts\Publisher;use Illuminate\Database\Eloquent\Model; class Podcast extends Model{ /** * Publish the podcast. * * @param Publisher $publisher * @return void */ public function publish(Publisher $publisher) { $this->update(['publishing' => now()]); $publisher->publish($this); }}
تزریق یک اجرای ناشر به متد به ما این امکان را می دهد که به راحتی روش را
به صورت مجزا آزمایش کنیم زیرا می توانیم ناشر تزریق شده را تقلید کنیم.
با این حال، از ما میخواهد که همیشه هر بار که متد را فراخوانی میکنیم، یک
نمونه ناشر ارسال کنیم
publish
.
با استفاده از نماهای بلادرنگ، میتوانیم همان تستپذیری را حفظ کنیم، در
حالی که نیازی به تصویب صریح یک
Publisher
نمونه نیست.
برای ایجاد یک نمای بلادرنگ، فضای نام کلاس وارد شده را با پیشوند
Facades
:
<?php namespace App; use Facades\App\Contracts\Publisher;use Illuminate\Database\Eloquent\Model; class Podcast extends Model{ /** * Publish the podcast. * * @return void */ public function publish() { $this->update(['publishing' => now()]); Publisher::publish($this); }}
وقتی از نمای بلادرنگ استفاده میشود، پیادهسازی ناشر با استفاده از بخشی
از رابط یا نام کلاس که بعد از پیشوند ظاهر میشود، خارج از ظرف سرویس حل میشود
Facades
.
هنگام آزمایش، میتوانیم از کمککنندههای تست نمای داخلی لاراول برای تقلید
این فراخوانی استفاده کنیم:
<?php namespace Tests\Feature; use App\Podcast;use Facades\App\Contracts\Publisher;use Illuminate\Foundation\Testing\RefreshDatabase;use Tests\TestCase; class PodcastTest extends TestCase{ use RefreshDatabase; /** * A test example. * * @return void */ public function test_podcast_can_be_published() { $podcast = factory(Podcast::class)->create(); Publisher::shouldReceive('publish')->once()->with($podcast); $podcast->publish(); }}
مرجع کلاس نما
در زیر هر نما و طبقه زیرین آن را خواهید یافت. این یک ابزار مفید برای کاوش سریع در اسناد API برای ریشه نما معین است. کلید صحافی کانتینر سرویس نیز در صورت لزوم گنجانده شده است.