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

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

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

问题

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

底层类

namespace Me\Package;

class PHPFile
{
    public function set($key, $value) {
        $this->$key = $value;
        return $this;
    }

    public function get($key) {
        return isset($this->$key) ? $this->$key : 'NO_SUCH_KEY';
    }

    public function sum()
    {
        // 一个“结束”方法的示例
    }
}

门面

namespace Me\Package\Facades;

use Illuminate\Support\Facades\Facade;

class PHPFile extends Facade {
   protected static function getFacadeAccessor() { return 'PHPFile'; }
}

服务提供者

use Me\Package\PHPFile;

public function register()
{
    App::bind('PHPFile',function() {
        return new PHPFile;
    });
}

测试

print PHPFile::set('first', 10)->set('second', 20)->sum();
// 30
print PHPFile::get('first');
// 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

<?php

namespace Me\Package;

class PHPFile
{
    public function set($key, $value) {
        $this->$key = $value;
        return $this;
    }

    public function get($key) {
        return isset($this->$key) ? $this->key : 'NO_SUCH_KEY';
    }

    public function sum()
    {
        // example of an "ending" method
    }
}

The facade

<?php

namespace Me\Package\Facades;

use Illuminate\Support\Facades\Facade;

class PHPFile extends Facade {
   protected static function getFacadeAccessor() { return 'PHPFile'; }
}

Serviceprovider

use Me\Package\PHPFile;

public function register()
{
    App::bind('PHPFile',function() {
        return new PHPFile;
    });
}

Test

print PHPFile::set('first', 10)->set('second', 20)->sum();
// 30
print PHPFile::get('first');
// 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(我的生成器类)


namespace Me\Package\Factories;

use Me\Package\PHPFile;

class PHPFileFactory
{
    public function __call($method, $args)
    {
        return (new PHPFile)->$method(...$args);
    }    
}

在服务提供者中绑定工厂

App::bind('PHPFile', function() {
    return new PHPFileFactory;
});

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

英文:

Add a factory

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

<?php

namespace Me\Package\Factories;

use Me\Package\PHPFile;

class PHPFileFactory
{
    public function __call($method, $args)
    {
        return (new PHPFile)->$method(...$args);
    }    
}

Bind the factory in the serviceprovider

App::bind('PHPFile',function() {
    return new PHPFileFactory;
});

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:

确定