这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
- 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
- 📢本文作者:由webmote 原创
- 📢作者格言: 生活在于折腾,当你不折腾生活时,生活就开始折腾你,让我们一起加油!💪💪💪
🎏 序言
大家都知道,ORM(实体关系映射模型)能帮助我们快速构建应用程序,而在使用.net 技术栈工作时,一定会首选Microsoft的数据库访问框架Entity Framework Core(EF Core)来构建应用程序,这里我们就谈谈你们中许多人都熟悉的软件原理和模式。
🎏 1.六个原理模式:
- 关注点分离–构建正确的体系结构;
- 服务层–将数据操作与表示操作分开;
- 仓储–选择正确的数据库访问模式;
- 依赖注入–将您的数据库代码转换为服务;
- 建立业务逻辑–将领域驱动设计与EF结合使用;
- 性能调优–如果有需要,让它更快的工作。
关于软件原理和模式,每个人都有自己的看法。
虽然整个软件世界在日新月异的发生变化,但值得庆幸的是,总有一些东西没有变,一些非常聪明的人一直在思考编程科学,而他们总是在向我们推荐模式,我认为这是掌握软件开发的精粹和捷径。
从大佬那里直接学习的想法很棒,然而枯燥的理论需要落地才能成佛,因此本文将一些软件思想与我多年的学习结合在一起,希望能从中体会到大佬的要义。
注意:我假设您已经了解实体框架,如果不是,建议您学习下Microsoft的EF Core文档,其中包括许多示例应用程序。
🎏 2.关注点分离
什么是关注点分离(SoC)?字都认识,组合起来好难理解。
关注点:字面意思是你关注的地方。可以是类库、包、类、甚至函数。分离:分开,纵向划分或者横向划分,可以按照功能职责划分,也可以按照业务语义划分。
该原则要求您:具有相似或相关功能的代码应组合在一起,可以理解为放置在单独的项目中。这称为凝聚力。使每个小组/项目尽可能独立,每段代码都应该有一个清晰的界面和工作范围,由其他调用者更改其工作方式,而不太可能更改代码,这也被称为低耦合。
网络上大多数EF代码示例都倾向于直接从其使用的任何应用程序类型调用。这并不遵循SoC,也不能真正代表实际应用程序的编写方式,真正符合SOC原则的设计分层如下:
分层方法对于中小型应用程序非常有效,也非常适合云平台开发,在云平台中可以在负载很大的情况下启动Web应用程序的更多实例负载,在设计上这称为横向扩展或自动扩展。
下图显示了如何将SoC应用于数据库访问代码,所有EF数据库访问代码都以气泡突出显示,气泡的大小与您在每一层中找到的EF代码的数量有关,请注意,ASP.NET Core项目和纯业务逻辑(BizLogic)项目中根本没有EF Core查询/更新代码。
🎏 3.服务层
《Microsoft .NET:企业的架构应用程序》,这本书向我介绍了服务层的使用,有兴趣可以去参考下。
服务层的原则就是边界问题。服务层“在两个接口层之间设置了边界”,但这对我的应用程序有什么帮助?我的理解是服务层作为适配器。
在分层体系结构中,数据库/业务逻辑与表示层之间经常存在数据不匹配的情况。DDD中有类似的观点,数据库和业务逻辑应专注于业务规则,而表示层则是为用户提供良好的用户体验,或者提供标准且简单的API服务。
因此,服务层成为至关重要的层,因为它可以是了解双方并可以在两个世界之间转换数据的层。这样可以使业务逻辑和数据库不受表示需求的干扰。
看看下图
EF提供了一种构建查询的方法,称为select loading,它可以从每个表中“挑选”相关的列,并将它们组合成一个完全适合用户视图的DTO / ViewModel类。我将这种转换与其他排序,过滤和分页功能一起应用于服务层。代码如下:
public static IQueryable<BookListDto>
MapBookToDto(this IQueryable<Book> books)
{
return books.Select(p => new BookListDto
{
BookId = p.BookId,
Title = p.Title,
Price = p.Price,
PublishedOn = p.PublishedOn,
ActualPrice = p.Promotion == null
? p.Price : p.Promotion.NewPrice,
PromotionPromotionalText =
p.Promotion == null
? null : p.Promotion.PromotionalText,
AuthorsOrdered = string.Join(", ",
p.AuthorsLink
.OrderBy(q => q.Order)
.Select(q => q.Author.Name)),
ReviewsCount = p.Reviews.Count,
ReviewsAverageVotes = p.Reviews.Select(y =>
(double?)y.NumStars).Average()
});
}
是的,这段代码很复杂,我们需要从许多不同的地方提取数据并同时进行一些计算,当然你可以构建自己的GenericServices库来减少操作的复杂度。
🎏 4. 小结
本篇还没有结束,明天继续。 例行小结,理性看待。
👓都看到这了,还在乎点个赞吗?
👓都点赞了,还在乎一个收藏吗?
👓都收藏了,还在乎一个评论吗?