【问题标题】:Use Fluent Interface with less Code使用更少的代码使用流畅的界面
【发布时间】:2014-10-18 16:24:47
【问题描述】:

如何减少这两行

$foo = new Bar();
$baz = $foo->methodOne('param')->methodTwo('param');

$baz = Bar::methodOne('param')->methodTwo('param');

我在 Laravel 中特别看到过这个,它的代码可读性很好。但我坚持让它与一些自定义的 Helper-Classes 一起工作。感觉就像混合静态 + 非静态函数,这现在令人困惑......

【问题讨论】:

    标签: php oop laravel fluent-interface


    【解决方案1】:

    Laravel 是这样处理的

    输入:vendor/laravel/framework/src/Illuminate/Database/Capsule

    /**
     * Dynamically pass methods to the default connection.
     *
     * @param  string  $method
     * @param  array   $parameters
     * @return mixed
     */
    public static function __callStatic($method, $parameters)
    {
        return call_user_func_array(array(static::connection(), $method), $parameters);
    }
    
    /**
     * Get a connection instance from the global manager.
     *
     * @param  string  $connection
     * @return \Illuminate\Database\Connection
     */
    public static function connection($connection = null)
    {
        return static::$instance->getConnection($connection);
    }
    

    来自PHPDOC

    __callStatic() 在静态上下文中调用不可访问的方法时触发。

    我认为你可以为你的班级简化这个:

    class Bar{
        public static function __callStatic($method, $parameters)
        {
            return call_user_func_array(array(new Bar(), $method), $parameters);
        }
        public function hello(){
          echo "hello";
        }
    }
    
    Bar::hello();
    

    【讨论】:

    • 粘贴到你的 sn-p 之后我仍然得到这个:非静态方法 Bar::methodOne() 不应该被静态调用,假设 $this 来自不兼容的上下文 // 任何想法?
    • call_user_func_array(array(new Bar(), $method), $parameteres); 不能指向它自己的类,我说得对吗?它应该实例化另一个类,例如在我的示例中 methodOne 和 methodTwo 被调用。所以它可能是call_user_func_array(array(new Foo(), $method), $parameters); ...对吗?
    • 不,即使它指向自己的类,它也应该可以工作。我用一个适合我的例子编辑了我的帖子;
    • 但是,我发现您无法访问 hello() 中的 $this 。但是我不知道解决方案
    【解决方案2】:

    一个更一致和自我解释的事情是有一个返回对象的静态构造函数,然后像这样调用它的方法:

    $baz = Bar::create()->methodOne('param')->methodTwo('param');
    

    另一种直接使用你现在拥有的语法是:

    $baz = (new Bar())->methodOne('param')->methodTwo('param');
    

    但这不是很漂亮...

    【讨论】:

    • 偶然发现了这个答案,您的替代解决方案可能不是很漂亮(尽管这是一个主观问题),从这里提供的所有角度来看,这是最干净的方法。 Laravel 通过使用 pretty 作为Bar::nonStaticMethod() 提供的开销比( new Bar() )->nonStaticMethod() 严重得多。只需写下 Laravel 如何为如此简单的事情实现其解决方案的调用链(相对于您的替代解决方案),您就会考虑不使用它;)
    • 严重是什么意思?
    • @Kristo 和 (new Bar())->methodCall() 没有开销。 Facaded 解决方案调用一个显然不存在的静态方法,必须首先创建一个被调用类Bar 的实例,然后使用call_user_func_array 的实例调用该方法,必须分配参数作为参数数组,然后才能返回实例本身以调用任何后续(链接)调用。如果您在整个脚本的各个行/位置上使用Bar::someMethod(),它会一遍又一遍地执行此过程.. 我会得出结论,对于如此简单的事情来说,这非常严重..
    【解决方案3】:

    对于路过的每个人:Laravel 提供了一种称为 Facades 的设计模式来实现该效果。 http://laravel.com/docs/5.1/facades

    如果你想构建自己的 Helper-Class,需要做四件事:

    1. 助手类本身
    2. 该类的服务容器绑定
    3. “指向”服务容器的外观类
    4. app.php 中的别名

    【讨论】:

    猜你喜欢
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多