如何在使用构建器模式时允许唯一的Laravel Facade实例?

huangapple go评论91阅读模式
英文:

How to allow unique Laravel Facade instances when using Builder pattern?

问题

我正在使用建造者模式,但在调用之间出现数据混淆。我希望每次静态调用我的门面时都能获得一个新的实例。示例:

底层类

  1. namespace Me\Package;
  2. class PHPFile
  3. {
  4. public function set($key, $value) {
  5. $this->$key = $value;
  6. return $this;
  7. }
  8. public function get($key) {
  9. return isset($this->$key) ? $this->$key : 'NO_SUCH_KEY';
  10. }
  11. public function sum()
  12. {
  13. // 一个“结束”方法的示例
  14. }
  15. }

门面

  1. namespace Me\Package\Facades;
  2. use Illuminate\Support\Facades\Facade;
  3. class PHPFile extends Facade {
  4. protected static function getFacadeAccessor() { return 'PHPFile'; }
  5. }

服务提供者

  1. use Me\Package\PHPFile;
  2. public function register()
  3. {
  4. App::bind('PHPFile',function() {
  5. return new PHPFile;
  6. });
  7. }

测试

  1. print PHPFile::set('first', 10)->set('second', 20)->sum();
  2. // 30
  3. print PHPFile::get('first');
  4. // 10 !!!

由于门面保持相同的实例,第二个测试行将打印 10。我希望在这里得到 'NO_SUCH_KEY' - 每次静态调用后都获得一个新实例。我该如何做到这一点?我尝试让门面返回一个最小的“工厂”,简单地返回一个新的 PHPFile 实例的构造函数,但没有成功。我还阅读到应该在“结束”方法(sum/get)中调用 new static,但不确定如何做到这一点并保留累积的数据。

英文:

Im using the Builder pattern but get data mixup between calls. I want a fresh instance on each static call to my facade. Example:

Underlying class

  1. <?php
  2. namespace Me\Package;
  3. class PHPFile
  4. {
  5. public function set($key, $value) {
  6. $this->$key = $value;
  7. return $this;
  8. }
  9. public function get($key) {
  10. return isset($this->$key) ? $this->key : 'NO_SUCH_KEY';
  11. }
  12. public function sum()
  13. {
  14. // example of an "ending" method
  15. }
  16. }

The facade

  1. <?php
  2. namespace Me\Package\Facades;
  3. use Illuminate\Support\Facades\Facade;
  4. class PHPFile extends Facade {
  5. protected static function getFacadeAccessor() { return 'PHPFile'; }
  6. }

Serviceprovider

  1. use Me\Package\PHPFile;
  2. public function register()
  3. {
  4. App::bind('PHPFile',function() {
  5. return new PHPFile;
  6. });
  7. }

Test

  1. print PHPFile::set('first', 10)->set('second', 20)->sum();
  2. // 30
  3. print PHPFile::get('first');
  4. // 10 !!!

Since facades keep the same instance the second test row will print 10. I want 'NO_SUCH_KEY' here - a new instance after each static call. How can I do that? I tried making the facade return a minimal "factory", simply a constructor returning a new PHPFile instance but did not succeed that way. I also read I should call a new static in the "ending"-methods (sum/get) but not sure how to do that and keep the accumulated data.

答案1

得分: 1

添加一个工厂

这个工厂会拦截任何带有魔术__call方法的调用,然后将其分派给一个新的PHPFile(我的生成器类)

  1. namespace Me\Package\Factories;
  2. use Me\Package\PHPFile;
  3. class PHPFileFactory
  4. {
  5. public function __call($method, $args)
  6. {
  7. return (new PHPFile)->$method(...$args);
  8. }
  9. }

在服务提供者中绑定工厂

  1. App::bind('PHPFile', function() {
  2. return new PHPFileFactory;
  3. });

感谢 @apokryfos 指出我需要返回其他内容 - 不是生成器本身,而是另一个类。

英文:

Add a factory

This factory will intercept any call with magic __call method, then dispatch it to a fresh PHPFile (My Builder class)

  1. <?php
  2. namespace Me\Package\Factories;
  3. use Me\Package\PHPFile;
  4. class PHPFileFactory
  5. {
  6. public function __call($method, $args)
  7. {
  8. return (new PHPFile)->$method(...$args);
  9. }
  10. }

Bind the factory in the serviceprovider

  1. App::bind('PHPFile',function() {
  2. return new PHPFileFactory;
  3. });

Thanks to @apokryfos who pointed out I needed to return something else - not the Builder itself but another class.

huangapple
  • 本文由 发表于 2020年1月4日 00:40:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/59582173.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定