类,闭包和Callables

时间:2018-04-29 14:58:55

标签: php

我编写了一个抽象类来处理持久化应用程序的模型。代码是通用的,可以与任何应用程序的模型一起使用。但是,某些模型需要一些特定处理,这超出了模型类的范围或抽象类的功能。 特定处理是扩展抽象类的类的责任。

因此,我需要抽象类能够调用扩展类中定义的函数,该函数将执行所需的特定处理。下面是一些有效的示例代码。但我不确定这是正确的方法(我尝试了很多不同的方法,但这是我唯一能够开展工作的方式)。

我的问题是:

  1. Closure方法的参数列表中使用persistModel()类型是否正确?
  2. Closure::fromCallable([$this, 'getPostFilename'])是将getPostFilename()方法传递到persistModel()方法的最佳(正确)方法吗?
  3. 我意识到这些问题都在征求意见,但我认为问题和答案可能会对那些与我一样挣扎的人有所帮助。

    工作示例代码:

    class Post
    {
    }
    
    abstract class FacadeAbstract
    {
        protected function persistModel(string $className, array $data, Closure $callabel = null)
        {
            $model = new $className();
    
            if (is_callable($callabel)) {
                echo $callabel($model);
            }
        }
    }
    
    class PostFacade extends FacadeAbstract
    {
        public function createPost(array $data)
        {
            $this->persistModel(Post::class, $data, Closure::fromCallable([$this, 'getPostFilename']));
        }
    
        public function deletePost(array $data)
        {
            $this->persistModel(Post::class, $data);
        }
    
        private function getPostFilename(Post $model): string
        {
            return "the_file_name.json\n";
        }
    }
    
    class Controller
    {
        public function actionGET(array $data)
        {
            $facade = new PostFacade();
            $facade->createPost($data);
        }
    }
    
    $controller = new Controller();
    echo $controller->actionGET(['slug' => 'context/title']);
    

1 个答案:

答案 0 :(得分:0)

回答你的问题:

在我看来,callable类型提示更灵活。当然,这需要使用call_user_func()而不是仅仅调用$callabel()

function persistModel(callable $callabel = null)
{
    if ($callabel !== null) {
        call_user_func($callabel, $model);
    }
}

使用callable时,您不再需要Closure::fromCallable(),只需拨打

即可
$this->persistModel([$this, 'getPostFilename']);

注1:当$callabel的来电确实是persistModel中的最后一次操作时,我只会返回$model变量并在getPostFilename内调用createPost }。但是大多数人都认为你的代码是极其简单的,并且还有更多。

注意2:看一下策略设计模式(Google将提供大量示例),也许这将导致更简洁的解决方案。