2010-02-25 8 views
7

Ich möchte ein Voting-System zu schaffen, in denen mehrere Domänenobjekte, über die abgestimmt werden können:Ist das ein guter Kandidat für eine Fabrik?

  • ein Kalenderereignis
  • Kommentar
  • ein Benutzer

So würde ich dachte, ich erstellen eine Voteable Schnittstelle für diese Artikel:

interface Voteable 
{ 
    public function vote(User $user, $value); 
} 

Ich dachte, die vote Methode würde Proxy eine Repository-Methode, so etwas wie:

class VotingRepository 
{ 
    public function castVote(Voteable $item, User $user, $value) 
    { 
     // save the these values, along with the value 
     $itemId = $item->getId(); 
     $userId = $user->getId(); 

    } 
} 

Vorerst wird das Repository eine Datenbank sein. Diese Datenbank wird Tabellen für jede Art von Stimme verbindet:

  • eventVote
  • commentVote
  • userVote

Also, das bedeutet im Wesentlichen, dass jede Domain-Objekt eine andere Tabelle, die die Stimmabgabe muss . Wäre das ein guter Kandidat für eine Fabrik? A VotingRepositoryFactory in diesem Fall? Mit anderen Worten so etwas wie:

class VotingRepositoryFactory 
{ 
    createVotingRepository($type) 
    { 
     switch($type) 
     { 
      case 'event': 
       // create a voting repository with EventVote table 
       return new VotingRepository(new EventVoteTable()); 
      case 'comment': 
       // create a voting repository with CommentVote table 
       return new VotingRepository(new CommentVoteTable()); 
      case 'user': 
       // create a voting repository with UserVote table 
       return new VotingRepository(new UserVoteTable()); 
     } 
    } 
} 

Dann alles zusammen zu binden, von innerhalb der Domain-Objekte (Kommentar in diesem Fall zum Beispiel), würde ich so etwas wie folgt aussehen:

class Comment implements Voteable 
{ 
    public function construct() 
    { 
     $this->_repository = VotingRepositoryFactory::createVotingRepository('comment'); 
    } 

    public function vote(User $user, $value) 
    { 
     $this->_repository->castVote($this, $user, $value); 
    } 
} 

Ist diese Sinn ergeben?

+0

Denken Sie daran, sich nicht zu sehr mit den Designmustern zu beschäftigen. Entwurfsmuster erzeugen eleganten und leicht zu wartenden Code, wenn sie effektiv und vernünftig verwendet werden. Sie möchten jedoch auch die Gefahr vermeiden, 10 Fuß Gerüste zu bauen, nur um Ihre Uhr an die Wand zu hängen. Das heißt, ich mag es, auf der Seite von zu viel Gerüst zu irren. ;-) –

+0

@Jeff: Ich höre was du sagst. Die Website wird jedoch (zumindest für mich) ein ziemlich ehrgeiziges Projekt sein. Also wollte ich, dass es so gut wie möglich vom Gitarristen geht. –

Antwort

4

ja sowohl das Repository und die Fabrik sinnvoll.

ein paar Kommentare über das Werk:

ich die switch ($type) entfernen würde und für jede Art von Votable Objektmethoden erstellen. so statt

VotingRepositoryFactory::createVotingRepository('comment');

ich würde es vorziehen,

VotingRepositoryFactory::createCommentVotingRepository();

der Grund dafür ist, dass es einfach zu vergessen, einen neuen Fall an den Schalter hinzuzufügen, während (Ich bin nicht sicher über php, aber) kompilierte Sprachen sagen Ihnen, wenn eine aufgerufene Methode fehlt. Denken Sie auch daran, welche Zeichenfolgen Sie an die Factory-Methode senden können, da $ type schwer ist, während die meisten intelligenten IDEs Ihnen sagen, welche Methoden für eine Klasse/ein Objekt existieren.

eine andere Idee wäre, ein Singleton hinzuzufügen, das wie VotingRepositoryFactory::Instance->createCommentVotingRepository(); aufgerufen werden könnte.Die "Instanz" könnte dann eine DatabaseVotingRepositoryFactory oder eine FakeVotingRepositoryFactory (für Komponententests) oder eine beliebige andere Implementierung einer VotingRepositoryFactory sein. Auf diese Weise können Sie die Implementierung der VotingRepositoryFactory problemlos ersetzen, wenn Sie Komponententests schreiben oder zu einem anderen Speichersystem wechseln möchten.

nur ein paar Ideen ..

+0

+1 Das sind einige großartige zusätzliche Informationen. Vielen Dank. Also, lass mich sehen, ob ich das richtig verstehe: Mit anderen Worten, du sagst, dass die 'getInstance()' auch irgendwie wie eine Fabrik sein würde? Das bringt eine andere Fabrik zurück, die auf etwas config zum Beispiel basiert? Ist das zufällig eine abstrakte Fabrik? –

+0

Ja, das von getInstance() zurückgegebene Objekt wäre eine abstrakte Fabrik. Sie können eine Art Konfigurationsdatei verwenden, um anzugeben, welche Art von Factory erstellt werden soll. manchmal habe ich es sogar nur hart programmiert (_instance = new ...). Es macht es immer noch sehr einfach zu ersetzen, sobald Sie müssen (eine Zeile Code). In Ihrer Anwendung tauchen immer mehr Singletons auf, vielleicht möchten Sie sich auch das "ServiceLocator" -Muster oder eine Art IoC-Container ansehen. So können Sie all Ihre Singletons (und vieles mehr) konfigurieren ein zentraler Ort. – stmax

2

Ja, tut es.

:]

+0

Was ?! Nein, wenn's ist und und oder aber ... ??? Fange ich wirklich an, den Dreh raus zu kriegen? Woohoo! :-D –

+0

Hmm .. Sorry, aber Sie haben Ihre Frage mit einer perfekten Antwort beantwortet – streetparade

+0

Nun, dann zu euch beiden: Danke euch beiden für die Zusicherung. –

Verwandte Themen