访问对象的创建者

时间:2011-02-21 17:16:39

标签: php oop

假设我正在使用与另一个对象具有Has-A关系的对象 - 游戏中有一个与之关联的玩家列表。玩家需要不时更新他在名册数据库中的信息 - 其名称是游戏的属性。允许玩家在游戏数据库中更新自己的记录的最佳方法是什么?

我想我可以让游戏为播放器做更新,但我认为最好让玩家尽可能地做自己的工作,这是他在数据库中需要更新的记录。此外,我仍然需要一种方法让任何一个玩家知道它是哪个游戏的一部分。每个玩家是否应该将游戏指示器作为属性嵌入其中?

如果有帮助,请参阅相关代码:

class HvZPlayer extends User{
private $bitten;
private $died;
private $hvz_status;
private $lastFed;
private $parent;

public function __construct($data){
    parent::__construct($data);
}

public function set_Human(){
    $this->hvz_status   = "Human";
    $this->bitten       = NULL;
    $this->died         = NULL;
    $this->lastFed      = NULL;
    $this->parent       = NULL;

    $conn = new WritePDO();
    $sql = "UPDATE "; //This is where I'm stuck.
}

}

2 个答案:

答案 0 :(得分:3)

首先尊重single responsibility principle。这是OOP最重要的规则之一。

根据这个简单的原则,代表单个玩家的玩家对象不应该处理诸如将数据保存到数据库之类的事情。但是发送简单的消息,比如嘿,我的状态已经改变了。也许你想和我做点什么?似乎完全没问题。其他想要侦听Player对象的对象可能会执行某些操作。这是observer pattern进来的地方。你可以尝试EventDispatcher from Symfony - 这种模式的一个非常好的实现。

伪码:

$database = ...;
$eventDispatcher = new EventDispatcher();

$eventDispatcher->connect('player.status_changed', function(Event $event) use ($database) {
    $pid    = $event->getSubject()->getId();
    $status = $event->getSubject()->getStatus();

    $database->query('UPDATE player SET status = :stats WHERE id = :id;', array(
        'id'     => $pid,
        'status' => $status
    ));
});

$player = new Player($eventDispatcher);

---------

class Player {
    $eventDispatcher;

    public function __construct(EventDispatcher $eventDispatcher) {
        $this->...;
    }

    public function setStatus($status) {
        $this->status = $status;

        $this->eventDispatcher->notify(new Event($this, 'user.status_changed'));
    }
}

答案 1 :(得分:0)

我现在正在做的方法是使用Game类中的静态方法生成一个包含数据的实例:

static function currentGame(){
    $conn = new ReadPDO();
    $sql = "SELECT *
            FROM games
            WHERE id={$_GET['id']}";

    $result = $conn->query($sql);
    $rowCount = $conn->query("SELECT FOUND_ROWS()")->fetchColumn();

    if($rowCount == 1){
        $game = new HvzGame($result->fetch());
        return $game;
    }else{
        return FALSE;
    }
}

然而,这似乎有点尴尬,因为它将返回当前观看的游戏,而不是给定玩家所属的游戏。在绝大多数情况下,这些将是相同的,但不一定。我觉得那里必须有更好的解决方案。