Это хороший кандидат на завод? - PullRequest
7 голосов
/ 25 февраля 2010

Я хочу создать систему голосования, в которой можно голосовать за несколько объектов домена:

  • событие календаря
  • комментарий
  • пользователь

Итак, я решил создать интерфейс Voteable для этих элементов:

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

    }
}

На данный момент хранилище будет базой данных. Эта база данных будет иметь таблицы ссылок для каждого типа голосования:

  • eventVote
  • commentVote
  • userVote

Итак, это, по сути, означает, что каждому объекту домена нужна другая таблица, чтобы отдать голоса. Будет ли это хорошим кандидатом на завод? А 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 );
    }
}

Имеет ли это смысл?

Ответы [ 3 ]

4 голосов
/ 26 февраля 2010

да, и хранилище, и фабрика имеют смысл.

несколько комментариев о фабрике:

Я бы удалил switch ($type) и создал методы для каждого типа объекта Votable. так вместо

VotingRepositoryFactory::createVotingRepository( 'comment' );

я бы предпочел

VotingRepositoryFactory::createCommentVotingRepository();

причина в том, что легко забыть добавить новый регистр к коммутатору, в то время как (я не уверен насчет php, но) скомпилированные языки сообщат вам, когда отсутствует вызываемый метод. Также трудно запомнить, какие строки вы можете отправить в метод фабрики как $ type, в то время как большинство интеллектуальных IDE сообщат вам, какие методы существуют в классе / объекте.

другой идеей было бы добавить синглтон, который можно было бы назвать как VotingRepositoryFactory::Instance->createCommentVotingRepository();. «Экземпляр» может быть затем DatabaseVotingRepositoryFactory или FakeVotingRepositoryFactory (для модульного тестирования) или любой другой реализацией VotingRepositoryFactory. таким образом, вы можете легко заменить реализацию VotingRepositoryFactory, если хотите написать модульные тесты или переключиться на другую систему хранения.

всего несколько идей ..

2 голосов
/ 25 февраля 2010

Да, это так.

:]

1 голос
/ 25 февраля 2010

О, да, это делает. + 1

...