开发者

Is this a good candidate for a factory?

I want to create a voting system, where multiple domain objects can be voted on:

  • a calendar event
  • a comment
  • a user

So I figured I would create a Voteable interface for these items:

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

I thought this vote method would proxy a repository method, something like:

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

    }
}

For now, the repository will be a database. This database will have linking tables for each type of vote:

  • eventVote
  • commentVote
  • userVote

So, t开发者_如何学运维his essentially means that each domain object needs another table to cast the votes to. Would this be a good candidate for a 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, tying it all together, from within the domain objects (comment in this case for example), 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 );
    }
}

Does this make sense?


yes both the repository and the factory make sense.

a few comments about the factory:

i'd remove the switch ($type) and create methods for each type of Votable object. so instead of

VotingRepositoryFactory::createVotingRepository( 'comment' );

i'd prefer

VotingRepositoryFactory::createCommentVotingRepository();

the reason being that it's 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 a called method is missing. also remembering what strings you can send into the factory method as $type is hard, while most intelligent IDEs will tell you what methods exist on a class/object.

another idea would be to add a singleton that could be called like VotingRepositoryFactory::Instance->createCommentVotingRepository();. the "Instance" could then be a DatabaseVotingRepositoryFactory or a FakeVotingRepositoryFactory (for unit testing) or any other implementation of a VotingRepositoryFactory. that way you could easily replace the implementation of the VotingRepositoryFactory if you want to write unit tests or switch to some other storage system.

just a few ideas..


Yep, it does.

:]


Oh Yes it makes. +1

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜