wal*_*her 5 c# architecture modularity decoupling
我正在开发一个系统,我希望尽可能地将我的图层分离,你知道,某种模块化的应用程序可以在不对系统其他部分进行严格修改的情况下切换数据库和内容.
所以,我一直在关注x-Robert C. Martin关于良好实践,清洁代码,解耦架构等的谈话,以获得一些灵感.我觉得有点奇怪的是他对系统的描述Fitnesse以及他们为WikiPages 实现存储/加载方法的方式.我也在关联视频:Robert C. Martin - 清洁建筑与设计
他描述的内容(至少从我的理解中)是实体知道如何从某个持久层存储和加载自身的机制.当他想将WikiPages存储在内存中时,他只是覆盖了WikiPage并创建了一个新的InMemoryWikiPage.当他想将它们存储在数据库中时,他做了同样的事情......
所以,我的一个问题是 - 这种方法叫做什么?我一直在学习关于存储库模式和内容的所有时间,为什么应该像这样的持久性无知的类,但我似乎无法在他做的这件事上找到任何材料.因为我的应用程序将由模块组成,我认为这可能有助于解决我的问题而无需为我的实体创建一些集中存储......每个模块都会自行处理,包括其实体的持久性.
我认为代码看起来像是这样的:
public class Person : IEntity
{
public int ID { get;set; }
public string Name { get;set; }
public void Save()
{
..
}
public void Update()
{
}
public void Delete()
{
}
...
}
Run Code Online (Sandbox Code Playgroud)
看起来有点奇怪,但......或许我误解了他在视频中所说的话?
我的第二个问题是,如果你不同意这种方法,你会在这种模块化应用程序中采取什么样的路径?
如果可能,请提供一些示例并提供一些解释.
您发布的模式是Active Record。
Repository 和 Active Record 模式的区别在于,在 Active Record 模式中,数据查询和持久化以及域对象位于一个类中,而在 Repository 中,数据持久化和查询与域对象本身解耦。
您可能想要研究的另一种模式是查询对象,与存储库模式不同,存储库模式的方法数量会在每个可能的查询(过滤、排序、分组等)中增加,查询对象可以使用流畅的接口来表达[1 ]或专用的,您可以在其中传递参数[2]
最后,您可以查看命令查询职责分离架构以获取想法。我个人松散地遵循了它,只是找到了对我有帮助的想法。
希望这可以帮助。
根据评论更新
存储库模式的一种变体是这样的
UserRepository
{
IEnumerable<User> GetAllUsers()
IEnumerable<User> GetAllByStatus(Status status)
User GetUserById(int id)
...
}
Run Code Online (Sandbox Code Playgroud)
由于存储库已针对请求的其他查询进行了更新,因此该版本无法扩展
另一种变体是将查询对象作为参数传递给数据查询
UserRepository
{
IEnumerable<User> GetAll(QueryObject)
User GetUserById(int id)
...
}
var query = new UserQueryObject(status: Status.Single)
var singleUsers = userRepo.GetAll(query)
Run Code Online (Sandbox Code Playgroud)
在.Net世界中,一些传递的是Linq表达式而不是QueryObject
var singleUsers = userRepo.GetAll(user => user.Status == Status.Single)
Run Code Online (Sandbox Code Playgroud)
另一种变体是专用存储库通过其唯一标识符对一个实体进行检索并保存它,而查询对象用于提交数据检索,就像在 CQRS 中一样。
更新2
我建议您熟悉SOLID 原则。这些原则对于指导您创建松散耦合、高内聚的架构非常有帮助。
Los Techies 关于 SOLID 原则的汇编包含关于 SOLID 原则的优秀介绍性文章。