使用facade(尤其是realtimefacade)让代码更优雅Code&RealTimeFacades,属于课程《Laravel底层核心技术实战揭秘》的篇《laravel底层核心概念解析》的延伸阅读。Laravel5.4引入了实时门面功能,即任何类都可以随时作为门面,只要在其命名空间前加上Facades前缀即可。当然,这个特性不能随处使用,但偶尔可以使用它来实现更简洁、优雅、易于测试的代码方案。下面的例子虽然说的是laravel5.4的realtimefacade,但是之前的版本也可以用,因为所谓的realtimefacade无非就是系统自动把你注册为facade。鉴于这个功能,不可能到处都用到,所以即使是老版本,如果你觉得这个门面的代码实现比较吸引人,那么自己手动注册一个门面是完全可以的。下面以LaravelForge为例,laravelForge是laravel官方推出的laravel项目部署管理平台。使用Forge时,你必须在Forge后台填写你的服务器提供商的账户信息,然后交给Forge进行具体管理。所以,这里假设我们有一个Model叫Provider,对应不同的hostprovider,比如国外的DigitalOcean,国内的阿里云。factory=$factory;}publicfunctionstore(Request$request,Provider$provider){$service=$this->factory->make($provider->type);$response=$service->createServer($request->name,$request->size);//}}但是,我觉得这样还是有点麻烦,我觉得这样用多好啊?service()->createServer($request->name,$request->size);//}}我们只是想简单的调用Provider实例上的service方法,然后我们就可以得到它背后对应的provider,然后我们就可以直接写createServer了,这种方式可能更像是我们最直接的思考过程日常生活,虽然你可能不明白它是如何在幕后实现的。那么如何实现呢?假设我们不需要facade,我们可以这样做:)->制作($this->type);}}似乎工作。但是这样一来,因为这个工厂类是直接在服务方法内部实例化的,这样不好,后面我们不能用它来进行mock测试。那么如果你使用实时门面会发生什么?type);}}}现在,不仅看起来更简洁优雅,而且可以测试,因为门面可以被模拟,例如:create(['id'=>1,'type'=>'DigitalOcean',]);$service=Mockery::mock(ServerProvider::class);ServerProviderFactory::shouldReceive('make')->with('DigitalOcean')->andReturn($service);$service->shouldRereceive('createServer')->once()->with('web','2GB')->andReturn('server-id');$response=$this->json('POST','/api/providers/1/server',['name'=>'web','size'=>'2GB',]);$response->assertStatus(201);}}你会发现实时外观最有用最好的地方是构建简洁优雅的对象API,而不影响代码的可测试性。希望能给大家的实际开发带来一些启发。
