何时重新声明继承中的类属性以进行更严格的更明确的类型定义

时间:2013-11-07 15:48:06

标签: php oop

直截了当。

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那样解决它。

对于像这样的场景中最好做什么,是否有任何规则?

感谢。

1 个答案:

答案 0 :(得分: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“读取”它。

你的第二种方法也是正确的,但限制性较小。