我编写了一个抽象类来处理持久化应用程序的模型。代码是通用的,可以与任何应用程序的模型一起使用。但是,某些模型需要一些特定处理,这超出了模型类的范围或抽象类的功能。 特定处理是扩展抽象类的类的责任。
因此,我需要抽象类能够调用扩展类中定义的函数,该函数将执行所需的特定处理。下面是一些有效的示例代码。但我不确定这是正确的方法(我尝试了很多不同的方法,但这是我唯一能够开展工作的方式)。
我的问题是:
Closure
方法的参数列表中使用persistModel()
类型是否正确?Closure::fromCallable([$this, 'getPostFilename'])
是将getPostFilename()
方法传递到persistModel()
方法的最佳(正确)方法吗?我意识到这些问题都在征求意见,但我认为问题和答案可能会对那些与我一样挣扎的人有所帮助。
工作示例代码:
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']);
答案 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将提供大量示例),也许这将导致更简洁的解决方案。