我想创建一个投票系统,可以对多个域对象进行投票:
所以我想我会为这些项创建一个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();
}
}
目前,存储库将是一个数据库。该数据库将包含每种投票类型的链接表:
因此,这实质上意味着每个域对象都需要另一个表来投票。这对工厂来说是个好人吗?在这种情况下是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 );
}
}
这有意义吗?
答案 0 :(得分:4)
是的,存储库和工厂都有意义。
关于工厂的一些评论:
我将删除switch ($type)
并为每种类型的Votable对象创建方法。所以而不是
VotingRepositoryFactory::createVotingRepository( 'comment' );
我更喜欢
VotingRepositoryFactory::createCommentVotingRepository();
原因是很容易忘记向交换机添加新案例,而(我不确定php,但是)编译语言会告诉你何时缺少被调用的方法。还记得你可以发送到工厂方法的字符串,因为$ type很难,而大多数智能IDE会告诉你类/对象上有什么方法。
另一个想法是添加一个可以像VotingRepositoryFactory::Instance->createCommentVotingRepository();
一样调用的单例。然后,“Instance”可以是DatabaseVotingRepositoryFactory或FakeVotingRepositoryFactory(用于单元测试)或VotingRepositoryFactory的任何其他实现。这样,如果要编写单元测试或切换到其他存储系统,就可以轻松替换VotingRepositoryFactory的实现。
只是一些想法..
答案 1 :(得分:2)
:
答案 2 :(得分:1)
哦,是的。 1