brightnucleus / static-facade
静态外观类,用于封装共享对象实例,方便访问。
Requires
- brightnucleus/exceptions: >=0.2
Requires (Dev)
- phpunit/phpunit: ~5
This package is auto-updated.
Last update: 2024-09-16 06:53:10 UTC
README
静态外观类,用于封装共享对象实例,方便访问。
目录
安装
使用此包的最佳方式是通过 Composer
composer require brightnucleus/static-facade
基本用法
要创建静态外观,您可以选择扩展 StaticFacade
类或使用 StaticFacadeTrait
,具体取决于您是否需要扩展现有类。
然后,此类静态外观将将其收到的任何静态方法调用作为动态方法调用转发到它封装的对象实例。
例如,假设您有一个从数据库获取用户的 UserRepository
类。如果您不能通过构造函数(这会避免静态耦合)注入该共享实例,您通常会通过静态调用(UserRepository::getInstance()
)或使用服务定位器(Services::get('UserRepository')
)来获取共享实例。这会产生繁琐的代码,因为与此类类的每次交互都包含两个独立的步骤。
为了使这更加方便,您可以提供一个静态外观,它抽象出共享实例的获取。
示例
// Without a static Facade. $userRepository = Services::get( 'UserRepository' ); $user = $userRepository->find( $userID ); // With a static Facade. $user = UserRepository::find( $userID );
注意:这将在消费代码中创建与静态外观本身的紧密耦合。这对于绕过遗留代码的限制非常出色,并且比将代码耦合到实际使用的类更可取,因为您还有一个抽象层,可以按需修改/替换实际类。然而,您应该 始终优先考虑在运行时注入依赖关系,而不是创建这种紧密的耦合。
扩展 StaticFacade 类
如果您的外观不需要扩展另一个现有类,通常您会扩展 StaticFacade
类。
示例
<?php declare(strict_types = 1); namespace Example\Project; use BrightNucleus\StaticFacade\StaticFacade; class UserRepository extends StaticFacade { protected static function getFacadeInstance() { // Return the shared instance of the object you are wrapping here. } }
使用 StaticFacadeTrait 特性
如果您的外观已经扩展了另一个类,您不能使用 StaticFacade
类,因为 PHP 不允许多重继承。在这种情况下,您可以使用提供相同功能的 StaticFacadeTrait
。
示例
<?php declare(strict_types = 1); namespace Example\Project; use BrightNucleus\StaticFacade\StaticFacadeTrait; class UserRepository extends AbstractRepository { use StaticFacadeTrait; protected static function getFacadeInstance() { // Return the shared instance of the object you are wrapping here. } }
在缺少方法时抛出异常
默认情况下,当通过外观调用未知方法时,会抛出一个带有详细消息的 BrightNucleus\Exception\BadMethodCallException
。
要提供自定义异常,您可以重写 getFacadeException
方法,该方法具有以下签名
protected static function getFacadeException(string $method, array $arguments) : Exception
直接向外观添加方法
默认情况下,静态外观现在将正常工作,并将任何方法调用动态地转发到其封装的对象。
但是,您始终可以直接向外观添加存根。如果您大量使用外观,这可能会很有意义,因为自动转发调用调用的方法比直接调用慢,而且它还缺少 IDE 生成任何有意义提示所需的基本提示。
要使用直接调用,只需添加匹配的静态方法,并将参数转发到对象的实例的动态方法,如下例所示
public static function find(int $userID) { return Services::get('UserRepository') ->find($userID); }
贡献
欢迎所有反馈/错误报告/拉取请求。
许可证
版权所有 (c) 2016 Alain Schlesser, Bright Nucleus
此代码根据 MIT 许可证 授权。