演講影片
簡單介紹
- 三大類設計模式:建立型,用於建立類的例項,隱藏建立的細節;結構性,基於繼承,不同的物件有相同的作用(功能);行為型,解決物件之間的通訊。
- laravel中的設計模式:工廠模式、建造者模式、策略模式、提供者模式
工廠模式
好比做披薩,需要一些原料比如芝士、蕃茄。芝士是用牛奶製成的,所以需要有奶牛,需要飼養它、擠奶、加工成芝士等等。本來你只想做披薩,結果不得不把大量的關注點花在如何製作芝士上,用工廠模式就可以很好的解決這類問題。工廠模式用於建立複雜的物件,用統一的方法去例項化它(後期的維護點也只在這裡),於是就實現了“披薩”和“芝士”之間的耦合。
laravel中的檢視就用了工廠模式,view()方法的原始碼:
function view($view = null, $data = [], $mergeData = [])
{
$factory = app(ViewFactory::class);
if (func_num_args() === 0) {
return $factory;
}
return $factory->make($view, $data, $mergeData);
}
建造者模式
好比開一個披薩店,買各式各樣的披薩,每種披薩需要不同的原料、不同的製作工序來製作。既然是開披薩店,當然不能整天忙於製作各種披薩的細節中,你還需要宣傳店面、做活動、招呼顧客等等。建造者模式是更高階的工廠模式,它好比是披薩師,他有著製作各種披薩的經驗,他會解決做披薩的各種問題,這樣做披薩的任務交給他就行了。建造者模式關注於如何一步一步的建立例項,最後總能返回一個你需要的物件。
laravel中的這些服務都是用的建造者模式:
- Illuminate\Auth\AuthManager
- Illuminate\Broadcasting\BroadcastManager
- Illuminate\Cache\CacheManager
- Illuminate\Filesystem\FilesystemManager
- Illuminate\Mail\MailManager
- Illuminate\Notifications\ChannelManager
- Illuminate\Queue\QueueManager
- Illuminate\Session\SessionManager
以Illuminate\Mail\MailManager為例(我用的laravel 7,所以不是影片講的Illuminate\Mail\TransportManager)。Mail門面對應的實體是Illuminate\Mail\MailManager,即mail物件的建造者。呼叫Mail::to()的時候,實際上是呼叫:
public function __call($method, $parameters)
{
// 建立一個mailer物件(透過環境變數MAIL_MAILER指定),並且傳送郵件
return $this->mailer()->$method(...$parameters);
}
策略模式
好比給客戶送披薩,你可以用人去送,可以用無人機,可以騎車去送,用什麼方式送不重要,只要送到就可以了。策略模式就是這樣,有不同的策略,不同的實現方式,只要按時送到準確地點就行。策略模式定義一類可替換的實現方式,授權給可用的、不同的演算法(實現方式)。
laravel的多語言翻譯模組用到了策略模式,Illuminate\Translation\TranslationServiceProvider中:
public function register()
{
$this->registerLoader();
$this->app->singleton('translator', function ($app) {
$loader = $app['translation.loader'];
// 這裡的loader雖然已經寫死,但是是可以替換的,只要實現了\Illuminate\Contracts\Translation\Loader即可
$trans = new Translator($loader, $locale);
$trans->setFallback($app['config']['app.fallback_locale']);
return $trans;
});
}
提供者模式
好比披薩加盟店,你並不懂怎麼製作披薩,你可以加盟連鎖店,他們告訴你如何製作披薩,原料、製作方法他們會提供給你,他們就相當於供應商。提供者模式,很好的體現了“tell, do not ask”的程式設計原則。有了提供者模式,我們可以方便的以“服務”的方式擴充套件我們的應用,就像連上了第三方服務,laravel稱之為“元件”。
提供者模式,能夠讓我們擴充套件系統,或新增更多的服務,laravel整個框架都是基於這個模式建立起來的。
laravel配置檔案的app.providers裡面都是大量的服務提供者,都可以算是提供者模式。舉例使用一個第三方服務debugbar,看一下Barryvdh\Debugbar\ServiceProvider的register方法(做了簡化):
// 服務註冊的時候做了一系列事情,供後續使用
public function register()
{
$configPath = __DIR__ . '/../config/debugbar.php';
$this->mergeConfigFrom($configPath, 'debugbar');
$this->app->alias(
DataFormatter::class,
DataFormatterInterface::class
);
$this->app->singleton(LaravelDebugbar::class, function () {
$debugbar = new LaravelDebugbar($this->app);
return $debugbar;
}
);
$this->app->alias(LaravelDebugbar::class, 'debugbar');
$this->app->singleton('command.debugbar.clear',
function ($app) {
return new Console\ClearCommand($app['debugbar']);
}
);
$this->commands(['command.debugbar.clear']);
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結