laracon 2018 演讲《Laravel 当中的编程设计模式》笔记
演讲视频
简单介绍
- 三大类设计模式:创建型,用于创建类的实例,隐藏创建的细节;结构性,基于继承,不同的对象有相同的作用(功能);行为型,解决对象之间的通讯。
- 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 协议》,转载必须注明作者和本文链接
最近也在学习设计模式,在此推荐一个相关网站给大家: refactoringguru