2016-05-19 56 views
0

我正在使用symfony框架在PHP中開發,但是這個問題更廣泛地適用於非symfony和非PHP開發人員。 (對於symfony開發人員,我使用單表繼承映射使用Doctrine ORM將子類映射到數據庫,BasePerson擴展了FOSUserBundle,然後進一步擴展了兩個子類。)應該將用戶類擴展爲多個用戶子類

「BasePerson」擴展了原始用戶類進一步擴展爲兩個獨立的子類:攝影師,PhotoSubject。

擁有子類是一個很好的邏輯分離,但是當我有一個也是PhotoSubject的攝影師時,問題就出現了。他們將共享相同的電子郵件地址,但使用不同的用戶名(在用戶類中)。

但是現在我有兩個對象爲同一個人(同一個用戶):一個PhotoSubject和一個攝影師,都有不同的用戶名和可能不同的密碼等等,這在Doctrine中顯然是不可能的 - 他們需要被存儲爲有不同用戶名的兩個單獨的數據庫記錄。對同一個用戶有兩個不同的登錄名對我來說似乎是一個設計問題。

任何人都可以提出這個問題的正確設計?我應該不使用繼承來避免這個問題,而是有一個沒有擴展的單體「BasePerson」類。我應該在用戶登錄時以某種方式檢查數據庫中是否有相同電子郵件地址的另一個「人員」?或者有另一種解決這個問題的方法嗎?

+0

7小時前提出了一個類似的問題,它提供了一些有用的信息: http://stackoverflow.com/questions/37306930/doctrine-inheritance-strategy-when-two-different-subclasses-extend-the-same -enti –

回答

0

我認爲這裏的問題是你已經混淆了與子類型的關係。

攝影師可能是一種類型的人,只要它不會在相互排斥的道路上導致類似的問題,但照片主題不是一種人。

一個Photosubject應該是一張照片和一個人之間的關係(1張照片 - >主題/人)

+0

嗨gview,感謝您的輸入,但是我仍然需要一個BasePerson的子類來代表照片中的某個人。然後這個類將以攝影師實現方法的方式實現諸如「攝影主題」的「getImages()」方法。 –

+0

是的,但同樣,這種類型的功能應該是發現人與人之間的關係。換句話說,我會製作類似Photo類的那部分內容。 Photo.findImages($ =人NULL);關於Doctrine,您將把用於Photo類的自定義存儲庫類的代碼放入該存儲庫。 – gview

0

我想你混淆了繼承,行爲和數據。在這種特殊情況下,我寧願用接口

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; 
    } 
} 

你並不真的需要有類世界每種類型的對象替換PhotographerPhotoSubject類。您有一個對象 - 一個Person和接口允許您從不同的角度顯示Person。在物理學中,它被稱爲「模型」 - 簡化的對象,描述當前所需的參數。同樣在這裏,綁定到行爲(接口),而不是實現。