指向同一模型的单个或多个存储库
Single or Multiple Repositories pointing to same model
虽然看到很多建议您应该使用存储库,但我从未见过有关如何实施它们的建议。
问题是,在开发游戏时,我有一个 TeamRepository
从 Team
模型获取数据,并 returns 在我必须使用它的任何地方获取数据。
当项目变得越来越大时,存储库也会发生这种情况,我最终得到了将近 20 个方法,这样我认为我违反了单一职责原则,即使存储库只负责获取并将数据发送到模型。
所以最好有 2 个存储库,例如 TeamRepository
和 FormationRepository
,其中 Team
模型有一个属性 Formation 还有是一个 Class,它处理 Formation 创建,但我需要一个存储库来实现持久化并构造 Formation
对象。
或者只要它们只处理数据获取和保存,就可以在单个存储库上拥有您需要的尽可能多的方法。
你可以在 TeamRepository
中有一个 FormationRepository
对象我的意思是聚合,并将那些与 Formation 相关的方法移动到 class FormationRepository
这样代码会变得更好。并使 FormationRepository
class 获取和 return Formations 可以确保 SRP on formation repository class。如果你没有 FormationRepository
class,也会违反抽象,因为所有实时实体都应被视为一个对象。
您没有指定您是否 want/need 遵循任何特定模式,但考虑到对不断增长的存储库的抱怨(即初级 god objects) and fact you tagged the question with solid principles 我会建议以下内容。
虽然 repository pattern 确实被广泛宣传 - 我不认为它建议将所有方法存储在一个对象中,而是侧重于在数据和使用层之间添加一个抽象层。这就是为什么最好遵循存储库模式和单一职责原则,并为不同的方法设置单独的对象。例如:
public class UserSearcher : IUserSearcher
{
public User SearchForUserByName(string name)
{
// ...
}
}
public class UserUpdater : IUserUpdater
{
public bool CreateOrUpdateUser(DTOUser user)
{
// ...
}
}
虽然在相同的情况下,使用 facade class 可能会更好,例如 nHibernate 的 ISession 对象。它仍然保持单一职责(即仅作为外观),同时打破接口隔离原则以保持存储库模式完整。
public class UserRepository : IUserRepositroy
{
public UserRepository (IUserSearcher userSearcher, IUserUpdater userUpdater)
{
// initialization
}
public User SearchForUserByName(string name)
{
return _userSearcher.SearchForUserByName(name);
}
public bool CreateOrUpdateUser(DTOUser user)
{
return _userSearcher.CreateOrUpdateUser(user);
}
}
请注意,facade 不需要在 facade 对象中保留任何逻辑,因此几乎是对前一点的修改。
如果我必须选择,我会选择完整的 SOLID 原则 - 它使编码变得有趣和扎实。
是的,只要你有两个不同的数据实体,无论它们之间的关系如何,你都应该有两个不同的存储库,用它们各自的实体进行数据操作。
虽然看到很多建议您应该使用存储库,但我从未见过有关如何实施它们的建议。
问题是,在开发游戏时,我有一个 TeamRepository
从 Team
模型获取数据,并 returns 在我必须使用它的任何地方获取数据。
当项目变得越来越大时,存储库也会发生这种情况,我最终得到了将近 20 个方法,这样我认为我违反了单一职责原则,即使存储库只负责获取并将数据发送到模型。
所以最好有 2 个存储库,例如 TeamRepository
和 FormationRepository
,其中 Team
模型有一个属性 Formation 还有是一个 Class,它处理 Formation 创建,但我需要一个存储库来实现持久化并构造 Formation
对象。
或者只要它们只处理数据获取和保存,就可以在单个存储库上拥有您需要的尽可能多的方法。
你可以在 TeamRepository
中有一个 FormationRepository
对象我的意思是聚合,并将那些与 Formation 相关的方法移动到 class FormationRepository
这样代码会变得更好。并使 FormationRepository
class 获取和 return Formations 可以确保 SRP on formation repository class。如果你没有 FormationRepository
class,也会违反抽象,因为所有实时实体都应被视为一个对象。
您没有指定您是否 want/need 遵循任何特定模式,但考虑到对不断增长的存储库的抱怨(即初级 god objects) and fact you tagged the question with solid principles 我会建议以下内容。
虽然 repository pattern 确实被广泛宣传 - 我不认为它建议将所有方法存储在一个对象中,而是侧重于在数据和使用层之间添加一个抽象层。这就是为什么最好遵循存储库模式和单一职责原则,并为不同的方法设置单独的对象。例如:
public class UserSearcher : IUserSearcher
{
public User SearchForUserByName(string name)
{
// ...
}
}
public class UserUpdater : IUserUpdater
{
public bool CreateOrUpdateUser(DTOUser user)
{
// ...
}
}
虽然在相同的情况下,使用 facade class 可能会更好,例如 nHibernate 的 ISession 对象。它仍然保持单一职责(即仅作为外观),同时打破接口隔离原则以保持存储库模式完整。
public class UserRepository : IUserRepositroy
{
public UserRepository (IUserSearcher userSearcher, IUserUpdater userUpdater)
{
// initialization
}
public User SearchForUserByName(string name)
{
return _userSearcher.SearchForUserByName(name);
}
public bool CreateOrUpdateUser(DTOUser user)
{
return _userSearcher.CreateOrUpdateUser(user);
}
}
请注意,facade 不需要在 facade 对象中保留任何逻辑,因此几乎是对前一点的修改。
如果我必须选择,我会选择完整的 SOLID 原则 - 它使编码变得有趣和扎实。
是的,只要你有两个不同的数据实体,无论它们之间的关系如何,你都应该有两个不同的存储库,用它们各自的实体进行数据操作。