Php 是否应将一个用户类扩展为多个用户子类

Php 是否应将一个用户类扩展为多个用户子类,php,symfony,orm,doctrine-orm,Php,Symfony,Orm,Doctrine Orm,我使用symfony框架在PHP中开发,但是这个问题更广泛地适用于非symfony和非PHP开发人员。(对于symfony开发人员,我使用单表继承映射将子类映射到数据库,使用ORM,BasePerson扩展FOSUserBundle,然后再扩展两个子类。) “BasePerson”扩展了原始用户类,该类进一步扩展为两个独立的子类:摄影师、PhotoSubject 拥有子类是一个很好的逻辑分离,但是当我有一个摄影师也是一个摄影主体时,问题就出现了。他们将共享相同的电子邮件地址,但用户名不同(在用户

我使用symfony框架在PHP中开发,但是这个问题更广泛地适用于非symfony和非PHP开发人员。(对于symfony开发人员,我使用单表继承映射将子类映射到数据库,使用ORM,BasePerson扩展FOSUserBundle,然后再扩展两个子类。)

“BasePerson”扩展了原始用户类,该类进一步扩展为两个独立的子类:摄影师、PhotoSubject

拥有子类是一个很好的逻辑分离,但是当我有一个摄影师也是一个摄影主体时,问题就出现了。他们将共享相同的电子邮件地址,但用户名不同(在用户类中)

但是现在我有两个对象是给同一个人(同一个用户)的:一个照片主体和一个摄影师,两者都有不同的用户名和可能不同的密码等等,这在理论上显然是不可能的——它们需要存储为两个不同用户名的单独DB记录。对我来说,同一个用户有两个不同的登录似乎是一个设计问题


有人能为这个问题提出正确的设计方案吗?我是否应该根本不使用继承来避免这个问题,而是使用一个未扩展的单片“BasePerson”类。当用户登录时,我是否应该检查数据库中是否有其他具有相同电子邮件地址的“人”?或者这个问题还有其他解决方案吗?

我认为这里的问题是您混淆了与子类型的关系

摄影师可能是一种类型的人,只要它不会给你带来相互排斥的类似问题,但摄影主体不是一种类型的人


照片主体应该是照片和人之间的关系(1张照片->主题/人)

我认为你混淆了继承、行为和数据。在这种情况下,我宁愿用接口替换
摄影师
PhotoSubject

interface Photographer {
  /**
    * @param PhotoSubject[] $filter subjects to filter the photos
    *
    * @return Image[]
    */
  public function getPhotos(array $filter);

  public function addPhoto(Image $photo);

  /** @return Image */
  public function shot(PhotoSubject $subject);

  // any other methods
}

interface PhotoSubject {
   /**
     * @return Image[] the images of the subject
     */
   public function getSubjectShots();
}


class Person implements Photographer, PhotoSubject {
  /** @var Image[]|ArrayCollection */
  private $ownImages;
  /** @var Image[]|ArrayCollection */
  private $referencedShots =[];

  public function getPhotos(array $filter) { return $this->ownImages->filter(...)->toArray(); }
  public function addPhoto(Image $photo) { 
     $this->ownImages->add($photo); 
     $photo->setAuthor($this);
  }

  public function getSubjectShots() { return $this->referencedShots->toArray(); }

  public function shot(PhotoSubject $subject) {
     $image = new Image(); 
     $this->addPhoto($image);
     $image->addSubject($subject);

     return $image;
  }
}

您实际上不需要为世界上的每种类型的对象都拥有类。您只有一个对象—一个
,界面允许您从不同的角度显示
。在物理学中,它被称为“模型”——简单化的对象,描述当前需要的参数。这里也是一样,绑定到行为(接口),而不是实现。

7小时前提出了一个类似的问题,提供了一些有用的信息:您好,谢谢您的输入,但是我仍然需要一个子类BasePerson,它在照片中代表某人。然后,该类将以摄影师实现方法的方式为该“照片主题”实现诸如“getImages()”之类的方法。是的,但同样,这种类型的函数应该是发现人与照片之间的关系。换句话说,我会在摄影课上做一些类似的事情。Photo.findImages($person=null);关于条令,您将把执行工作的代码放入Photo类的自定义存储库类中。