【问题标题】:When to redeclare class property in inheritance for stricter more explicit type defining [closed]何时在继承中重新声明类属性以获得更严格更明确的类型定义 [关闭]
【发布时间】:2013-11-07 15:48:05
【问题描述】:

直截了当。

abstract class AbstractRepository {

    private $mapper;

    public function __construct(AbstractMapper $mapper) {
        $this->mapper = $mapper;
    }

    public function save(AbstractEntity $entity) {
        return $this->mapper->save($entity);
    }

    public function delete(AbstractEntity $entity) {
        return $this->mapper->delete($entity);
    }

}

class UserRepository extends AbstractRepository {

    private $userMapper;

    public function __construct(UserMapper $userMapper) {
        parent::__construct($userMapper);
        $this->userMapper = $userMapper;
    }

    public function fetchByUsername($username) {
        return $this->userMapper->fetch( array('username' => $username) );

}

VS

abstract class AbstractRepository {

    // Different visibility
    protected $mapper;

    public function __construct(AbstractMapper $mapper) {
        $this->mapper = $mapper;
    }

    public function save(AbstractEntity $entity) {
        return $this->mapper->save($entity);
    }

    public function delete(AbstractEntity $entity) {
        return $this->mapper->delete($entity);
    }

}

class UserRepository extends AbstractRepository {

    // $userMapper property gone

    public function __construct(UserMapper $userMapper) {
        parent::__construct($userMapper);
    }

    public function fetchByUsername($username) {
        return $this->mapper->fetch( array('username' => $username) );

}

我喜欢第一种方式,因为UserRepository 包含UserMapper 的实例更加明确和具体。

第二种方式更好,因为代码少但走线

return $this->mapper->fetch( array('username' => $username) );

没有那么清楚

return $this->userMapper->fetch( array('username' => $username) );

当我在用户存储库中时,我知道$this->mapperUserMapper 的一个实例,但我更喜欢像$this->userMapper 一样称呼它。

对于在这种情况下最好做什么有什么规定吗?

谢谢。

【问题讨论】:

  • 这两种方式都行不通。见stackoverflow.com/a/19131270/476
  • 你是什么意思不起作用?因为它是错误的?两种方式都能完美运行。我想知道哪种方法是正确的。
  • 请参阅stackoverflow.com/questions/19429089/… 以获得解释。
  • @deceze 我以前读过。那不是我的问题。我的代码两种方式都能 100% 工作,但我只想知道哪种方式更好。
  • 不确定您要达到的目标。您可以为每个继承类编写 setter/getter ala getUserMapper() 以阐明您正在使用的映射器。

标签: php oop


【解决方案1】:

您的第一种方法没有意义...您正在复制代码。

您必须了解的是,UserRepository 仍然具有 $mapper 属性。它只是不能直接访问,因为它是private。您需要访问器方法来执行此操作:

abstract class AbstractRepository {

    // Different visibility
    private $mapper;

    public function __construct(AbstractMapper $mapper) {
        $this->mapper = $mapper;
    }

    protected function getMapper() {
        return $this->mapper;
    }

    public function save(AbstractEntity $entity) {
        return $this->mapper->save($entity);
    }

    public function delete(AbstractEntity $entity) {
        return $this->mapper->delete($entity);
    }

}

class UserRepository extends AbstractRepository {

    // $userMapper property gone

    public function __construct(UserMapper $userMapper) {
        parent::__construct($userMapper);
    }

    public function fetchByUsername($username) {
        return $this->getMapper()->fetch( array('username' => $username) );

}

通过这种方式,您可以确保任何*Repository 子类都可以使用$mapper 做任何奇怪的事情,但您仍然可以使用getMapper“阅读”它。

您的第二种方法也是正确的,但限制较少。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    相关资源
    最近更新 更多