它是一个游戏网站,我们存储分数:
class Game
{
public function addScore($player, $score)
{
INSERT INTO game .........
}
}
管理员可能会删除分数,因此我们也要添加删除方法:
public function delete($id)
{
DELETE FROM game .........
}
现在的问题是,删除被记录,所以我们必须包装这段代码:
控制器:
$log->addLog('user deletetion');
$game->delete($id);
因此,当我们在控制器中删除此游戏时,也会发生日志记录。现在出现了问题:在代码中,没有什么可以阻止只调用$game->delete();
方法!这很糟糕,因为如果有任何菜鸟开始使用这个代码,他就不知道删除必须带有日志记录。这是某事的标志,还是?? ??
答案 0 :(得分:2)
如果您总是希望在删除之前编写日志,那么只需将日志记录添加到delete()方法中就像RiggsFolly建议的那样,因为这是一个“原子”操作。
如果例如除了记录+删除之外,您将违反SRP,则会以相同的方法弹出对话框。正如您在同一方法中混合数据处理和UI一样。这是两个单独的责任。
答案 1 :(得分:1)
这可以使用Facade模式解决。你需要这样的东西
class GameFacade{
public function __constructor(Game $game, Logger $logger){
$this-game = $game;
$this-logger = $logger;
}
public function delete($id) {
$this->game->delete($id);
$this->logger->log("Game deleted");
}
}
所以,现在我们必须只使用这个Facade来处理Game
实体。显然,你不能阻止新来者直接使用Game
删除方法,但至少你可以使某种约定只使用实体外观。
您可以选择的另一种方法是使用结构模式生成实体。请阅读有关模式的更多信息,但您也应该仔细使用它们。
答案 2 :(得分:1)
您可以使用Decorator pattern来装饰您的Game
课程。这样,每当有人调用delete方法并将其保留在Game
类之外时,您就会记录。
以下是有关如何在Symfony框架中执行此操作的指南,以便您了解:https://symfony.com/doc/current/service_container/service_decoration.html