Is this a good candidate for a factory?

I want to create a voting system for which several domain objects can be voted on:

  • calendar event
  • a comment
  • user

So, I decided to create a Voteable interface for these elements:

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

I thought this vote method would proxy the repository method, for example:

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

At the moment, the repository will be a database. This database will contain binding tables for each type of voting:

  • eventVote
  • commentVote
  • userVote

Thus, this essentially means that each table of the domain requires a different table for the transfer of votes. Will this be a good candidate for the factory? A VotingRepositoryFactory in this case? In other words, something like:

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

Then, linking all this together, from inside the domain objects (for example, a comment in this case), I would look something like this:

 class Comment implements Voteable { public function construct() { $this->_repository = VotingRepositoryFactory::createVotingRepository( 'comment' ); } public function vote( User $user, $value ) { $this->_repository->castVote( $this, $user, $value ); } } 

It makes sense?

+7
php design-patterns factory
source share
3 answers

Yes, both the repository and the factory make sense.

some comments about factory:

I remove switch ($type) and create methods for each type of Votable object. therefore instead

VotingRepositoryFactory::createVotingRepository( 'comment' );

I would prefer

VotingRepositoryFactory::createCommentVotingRepository();

the reason is that it is easy to forget to add a new case to the switch, while (I'm not sure about php, but) compiled languages ​​will tell you when there is no call method. also remembering which lines you can send to the factory method of type $ type, and most smart IDEs will tell you what methods exist in the class / object.

Another idea is to add a singleton, which can be called as VotingRepositoryFactory::Instance->createCommentVotingRepository(); . An "instance" can then be DatabaseVotingRepositoryFactory or FakeVotingRepositoryFactory (for unit testing) or any other implementation of VotingRepositoryFactory. thus, you can easily replace the VotingRepositoryFactory implementation if you want to write unit tests or switch to another storage system.

just a few ideas ..

+4
source share

Yes it is.

:]

+2
source share

Oh yes it is. +1

+1
source share

All Articles