VotingRepositoryFactory

VotingRepositoryFactory

我想创建一个投票系统,可以在其中对多个域对象进行投票:

  • 日历事件
  • 评论
  • 用户

  • 所以我想为这些项目创建一个Voteable接口(interface):
    interface Voteable
    {
        public function vote( User $user, $value );
    }
    

    我认为这个vote方法将代理存储库方法,例如:
    class VotingRepository
    {
        public function castVote( Voteable $item, User $user, $value )
        {
            // save the these values, along with the value
            $itemId = $item->getId();
            $userId = $user->getId();
    
        }
    }
    

    目前,该存储库将是一个数据库。该数据库将具有每种投票类型的链接表:
  • 事件投票
  • 评论投票
  • 用户投票

  • 因此,从本质上讲,这意味着每个域对象都需要另一个表来进行投票。这会是一家工厂的好人选吗?在这种情况下是VotingRepositoryFactory?换句话说:
    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() );
            }
        }
    }
    

    然后,将它们从域对象(例如,在本例中为注释)中绑在一起,看起来像这样:
    class Comment implements Voteable
    {
        public function construct()
        {
            $this->_repository = VotingRepositoryFactory::createVotingRepository( 'comment' );
        }
    
        public function vote( User $user, $value )
        {
            $this->_repository->castVote( $this, $user, $value );
        }
    }
    

    这有意义吗?

    最佳答案

    是的,仓库和工厂都有意义。

    关于工厂的一些评论:

    我将删除switch ($type)并为每种类型的Votable对象创建方法。所以代替
    VotingRepositoryFactory::createVotingRepository( 'comment' );
    我更喜欢
    VotingRepositoryFactory::createCommentVotingRepository();
    原因是很容易忘记在开关中添加新的大小写,而(我不确定php,但是)编译语言会在缺少被调用方法时告诉您。还记得使用$ type很难将哪些字符串发送到工厂方法中,而大多数智能IDE会告诉您类/对象上存在哪些方法。

    另一个想法是添加一个可以称为VotingRepositoryFactory::Instance->createCommentVotingRepository();的单例。那么“实例”可以是DatabaseVotingRepositoryFactory或FakeVotingRepositoryFactory(用于单元测试)或VotingRepositoryFactory的任何其他实现。这样,如果您要编写单元测试或切换到其他存储系统,则可以轻松替换VotingRepositoryFactory的实现。

    只是一些想法。

    关于php - 这是工厂的好人选吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2337279/

    10-11 03:09