资讯专栏INFORMATION COLUMN

通过facade(尤其是realtime facade)来使代码更优雅

Eric / 3226人阅读

摘要:那么如果用的方式会怎么样呢现在,不仅看起来更简洁优雅,而且也可以测试了,因为可以进行,比如说这样你会发现最有用的地方就是构建简洁优雅的,同时呢又不会影响到代码的可测试性。

本文来自pilishen.com----原文链接; 欢迎作客我们的php&Laravel学习群:109256050

该篇翻译整理自laravel创始人Taylor的文章:Expressive Code & Real Time Facades,属于《Laravel底层核心技术实战揭秘》这一课程《laravel底层核心概念解析》这一章的扩展阅读。

laravel 5.4引入了realtime facade的功能,也即任何一个class都可以随时拿来当facade用,只要在其namespace前面加上Facades前缀即可。当然这个功能不可能随处都用到,但是偶尔呢,用它可以实现更简洁优雅、易于测试的代码方案。虽然下面的例子讲的是laravel 5.4的realtime facade,但是呢,其实也完全可以用在之前的版本上,因为所谓的realtime facade,无非就是系统自动给你注册成facade而已,鉴于这个功能又不可能到处用到,所以即使在老的版本里,如果你发现facade的这种代码实现方式更有吸引力,那么自己手动注册一个facade也完全可以的。

接下来的示例是关于Laravel Forge的,laravel Forge是laravel官方推出的laravel项目部署管理平台。当使用Forge的时候,你得在Forge后台将你服务器提供商的账号信息填上,然后呢交由Forge来具体管理。那么,这里假设呢我们有一个Model叫Provider,也就是对应着不同的主机提供商,比如国外的DigitalOcean、国内的阿里云等。


这里呢假设我们将所有处理外来API请求的class放在AppServices文件夹下,我们得对应每一个主机供应商都有一个“service”class,假设DigitalOcean这家供应商的service class是这样的:


接下来呢,我们得能够解析这个服务类,基于我们model里的type这一栏的信息,我们可以使用工厂(factory)模式来实现:


然后呢,我们就可以在需要的地方调用这个工厂,来相应地创建一个server 服务,比如假设在controller里调用:

factory = $factory;
    }
    public function store(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方法,然后就能获取到其背后对应的供应商,然后就能直接地createServer。这样来写呢,可能更像是我们日常中最直接的思考过程,虽然可能背后具体怎么实现你还没搞懂。那么怎么来实现呢?假设不借助facade,我们或许可以这样:

make($this->type);
    }
}

貌似可行。但是这样呢,因为这个factory类是直接在service方法内部实例化的,这是不好的,后期我们无法用它来mock测试。那么如果用realtime facade的方式会怎么样呢?

type);
    }
}

现在,不仅看起来更简洁优雅,而且也可以测试了,因为facade可以进行mock,比如说这样:

create([
            "id" => 1,
            "type" => "DigitalOcean",
        ]);
        $service = Mockery::mock(ServerProvider::class);
        ServerProviderFactory::shouldReceive("make")
                    ->with("DigitalOcean")
                    ->andReturn($service);
        $service->shouldReceive("createServer")
                    ->once()
                    ->with("web", "2GB")
                    ->andReturn("server-id");
        $response = $this->json("POST", "/api/providers/1/server", [
            "name" => "web",
            "size" => "2GB",
        ]);
        $response->assertStatus(201);
    }
}

你会发现real-time facade最有用的地方就是构建简洁、优雅的object APIs,同时呢又不会影响到代码的可测试性。希望这能给你的实际开发带来一定启发。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/28216.html

相关文章

  • PHP中的facade pattern(外观模式)

    摘要:本文来自原文链接欢迎作客我们的学习群该篇属于底层核心技术实战揭秘这一课程底层核心概念解析这一章的扩展阅读。考虑到学员们的基础差异,为了避免视频当中过于详细而连篇累牍,故将一些底层实现相关的知识点以文章形式呈现,供大家预习和随时查阅。 本文来自pilishen.com----原文链接; 欢迎作客我们的php&Laravel学习群:109256050该篇属于《Laravel底层核心技术实战...

    jaysun 评论0 收藏0
  • 外观设计模式

    摘要:外观设计模式的优点易于使用在实现形式上通常占用较小的内存。抽象的注意事项外观设计模式虽然少有劣势,但值得注意的一个问题是性能。 当我们竖起一个门面时,我们向外展示的只是一种外表,它可能隐藏着一个非同一般的事实。这也就是我们所要说的外观设计模式,这种模式为一大段的代码体提供了一个便捷的高级接口,隐藏了底层复杂的实现。这种设计模式简化代码的呈现形式,给开发人员一个API,同时也能提高代码的...

    zzbo 评论0 收藏0
  • 外观模式(Facade Pattern)

    摘要:深入剖析,第二章。如果给方法以默认访问权限,则只能在同一个包中访问,这个被认为是可以的,但是不最好,最优雅的方式是通过类。定义外观模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 《深入剖析Tomcat》(How Tomcat Works),第二章。 创建 Request 和 Response 分别实现 ServletRequ...

    LMou 评论0 收藏0
  • Lumen 初体验(二)

    摘要:的现状目前是版本,是基于开发。入口文件启动文件和配置文件框架的入口文件是。在路由中指定控制器类必须写全命名空间,不然会提示找不到类。目前支持四种数据库系统以及。使用时发生错误,因为在文件中,的默认驱动是。 最近使用 Lumen 做了 2 个业余项目,特此记录和分享一下。 Lumen 的介绍 在使用一项新的技术时,了解其应用场景是首要的事情。 Lumen 的口号:为速度而生的 La...

    Cheriselalala 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<