news 2026/9/1 22:38:57

ASP.NET MVC三层架构博客系统:从代码分层到工程实践全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ASP.NET MVC三层架构博客系统:从代码分层到工程实践全解析

简介:这是一套基于ASP.NET MVC实现的三层架构博客网站系统源码,面向Web开发新手及具备基础C#和Web开发经验的程序员,旨在帮助学习者深入理解MVC模式、分层解耦设计(表现层/业务逻辑层/数据访问层)以及企业级博客系统的完整实现流程。资源共418个文件,包含35个cshtml视图页、23个cs业务与实体类、23个config配置文件、32个js前端脚本、11个css样式文件及121个运行依赖dll,辅以SQL数据库脚本、EDMX模型文件和完整VS解决方案(.sln),包体大小为29.41MB。已有1708人下载学习,源码经作者工控老马亲测校正,集成SEO优化功能,结构清晰、注释规范,涵盖用户管理、文章发布、分类标签、评论互动等核心模块,适合用于课程设计、毕业项目参考或三层架构实战演练。

1. 为什么拿博客系统练三层架构,是最不容易跑偏的入门项目

先交代一下背景。我在技术群里经常被问到一类问题:手上有一个ASP.NET MVC的三层架构博客系统源码,能跑,但看不懂代码怎么分层;或者自己想写一个类似的项目,不知道从哪儿下手。问的人多了,我逐渐意识到一个现象——很多人把“三层架构”和“MVC”当成一个概念去理解,结果看源码越看越糊涂。

先说结论:这两个东西不在一个维度上,三层架构解决的是“软件职责怎么划分”的问题,MVC解决的是“表现层内部怎么组织”的问题。后面我会详细拆开讲。现在先说说,为什么博客系统恰好是练三层架构的经典场景。

博客系统看起来简单,但它具备一个合格练习项目应有的全部特征。用户注册登录、文章发布与管理、分类归档、评论互动,这些功能覆盖了Web开发最常见的增删改查、用户认证、权限控制、表单验证、分页展示。少了复杂的电商支付流程,也没有像ERP那样的多组织权限矩阵,对于想理解架构分层的人来说,复杂度刚好卡在“能看懂”和“有收获”之间。

《基于ASP.NET MVC的三层架构博客网站系统源码》这个标题听起来很像毕业设计或个人练手项目,但我要说的是,它实际包含的架构思想和工程化规范,比很多公司内部跑了几年的老系统要清晰得多。因为博客系统的领域边界足够收敛,所以你可以把全部精力放在“每一层到底该放什么代码”这个核心问题上,而不是被业务规则淹没。

这套源码适合谁?我总结下来是三类人:

第一类,正在学ASP.NET MVC的学生。学校课程往往讲控制器、视图、模型怎么配合,但很少讲一个完整的、可扩展的项目结构长什么样。这套源码补的就是这个断层。

第二类,准备面试的初级开发。很多面试官会问“你们项目为什么用三层架构”“三层之间怎么通讯”“如果让你重构会怎么做”,如果你脑子里没有一个完整的源码作为参照,这种问题很容易答得空洞。

第三类,想快速搭一个个人站点的人。博客系统的功能边界清晰,把源码跑起来之后替换样式、改改配置就能用,比自己从零写节省大量时间。

我建议的阅读方式,不是从上到下逐行读,而是先看整个项目的目录结构,理解分层逻辑,再挑一个完整的业务链路去追代码流转。下面这篇文章我就按这个思路来展开。

2. 三层架构和MVC被混为一谈太久了——这套源码里两者到底是什么关系

这是我见过最常见的误区。很多人打开解决方案一看,里面有个Controllers文件夹,就说“哦,这是三层架构的Controller层”,接着又说“表示层就是Views对吧”。这个理解错得离谱。

2.1 从概念维度区分,别再对着目录猜了

三层架构是软件的分层架构模式,它把系统切分成三个职责边界清晰的层次:

  • 表示层(UI层):负责与用户交互,展示数据、接收输入。
  • 业务逻辑层(BLL):负责处理业务规则、流程控制、数据校验。
  • 数据访问层(DAL):负责与数据库打交道,执行增删改查。

MVC则是一种表现层的设计模式,它把用户界面拆成Model(数据模型)、View(视图)、Controller(控制器)三个部分,解决的是“界面如何响应操作”的问题。

两者之间的关系可以这样理解:三层架构是宏观的分层,MVC是表示层内部的微观组织方式。也就是说,MVC的三个组件,全部属于三层架构里的“表示层”。Controller负责接收请求、调用业务逻辑层、挑选视图返回;View负责渲染HTML;Model负责承载界面需要的数据。真正的业务处理,发生在业务逻辑层。

我见过一些水平还不错的开发者在画架构图的时候,画了四层——Controller层、Business层、DAO层、View层,看起来层次多了,实际上是把两个维度的概念混在一起了。三层架构的正确理解,应该是把整个MVC组合体看作一个表示层单元。

2.2 从这套源码的项目结构反推分层思想

接下来我们看源码解决方案的组织方式。一个标准的ASP.NET MVC三层架构解决方案,通常包含下面这些项目:

项目名职责
MyBlog.Web表现层控制器、视图、模型绑定、过滤器、路由配置
MyBlog.BLL业务逻辑层业务规则处理、数据校验、流程编排
MyBlog.DAL数据访问层EF上下文、仓储实现、实体模型
MyBlog.Model领域实体数据库表对应的实体类、DTO、枚举

注意,上面这个是最简形态。实际项目里你可能还会看到IDAL接口层和IBLL接口层,它们分别对应数据访问层和业务逻辑层的接口抽象。在这套博客源码里,通常会把接口和实现放在同一个程序集里,或者单独拆出接口项目。两种方式各有各的道理,初学者我先建议盯住“依赖方向”这个点,不要被具体项目数量带偏。

依赖方向是三层架构的灵魂。UI层引用BLL,BLL引用DAL,DAL引用实体Model。依赖是单向的,不能反向引用。这样做的好处是,当业务规则变化时,只改BLL;当数据库从SQL Server换到MySQL时,只替换DAL的实现,上层代码基本不用动。

2.3 源码里典型的分层调用链路

为了让你有直观感受,我以“查看文章详情”这个场景为例,整理一下这条链路在源码里是怎么走的:

  1. 浏览器地址栏输入/Article/Details/5
  2. ASP.NET MVC的路由引擎根据URL规则,定位到ArticleController下的Details动作方法。
  3. Details(int id)方法内,控制器调用ArticleManager(业务逻辑层)的GetArticleById(int id)方法。
  4. ArticleManager内部先做业务校验,比如确认文章状态是否为“已发布”,再调用ArticleRepository(数据访问层)的SelectById方法。
  5. ArticleRepository利用Entity Framework执行SQL查询,返回Article实体。
  6. 数据逐层往上返回,到达控制器。
  7. 控制器把Article实体封装成视图模型ArticleDetailViewModel,传给Details.cshtml视图渲染。

注意到关键点了吗?控制器本身不直接操作数据库,业务逻辑层也不直接拼SQL。每一层的调用都通过上层的接口方法进入,下层的实现细节被严格封装。这种“各管一段”的设计,就是三层架构想表达的东西。

我在指导别人读这套源码的时候,经常让他们做这样一个练习:从数据库表结构出发,倒着往上层看。先看DAL里的仓储类有哪些方法,再看BLL里的业务类怎么调用这些方法,最后看Controller怎么把业务结果转换成界面数据。顺着这条路走一遍,比看十遍架构图更管用。

3. 源码里的三条主链路拆解——注册登录、发博文、评论都在代码里怎么流转

有了整体分层的概念之后,我们挑三条实际业务链路来逐行追代码。这是理解整套源码的关键。

3.1 注册登录链路:表单校验与身份票据

博客系统的用户模块通常包含注册、登录、注销三个动作。以登录为例,我在这类源码里最常见的实现方式,是基于ASP.NET MVC的FormsAuthentication(表单身份验证),或者自定义一个基于Session的登录状态管理。

登录的完整数据流是这样走的:

  1. 用户在Login.cshtml中输入用户名和密码。
  2. 浏览器通过POST表单把数据提交到AccountControllerLogin方法。
  3. 控制器的动作方法接收LoginViewModel对象,ModelState.IsValid做第一层校验(必填项、格式、长度)。
  4. 校验通过后,控制器调用业务逻辑层UserManagerValidateUser(string userName, string password)方法。
  5. UserManager把密码加密后传给数据访问层的UserRepository做比对。
  6. 比对成功,控制器写入身份票据FormsAuthentication.SetAuthCookie(userName, false),然后跳转到首页。
  7. 比对失败,控制器返回视图并携带错误提示。

这里有一个值得注意的细节。我在很多毕业设计源码里都见过明文密码直接存数据库,但稍微规范一点的项目,密码必须经过哈希处理。常见做法是用MD5或者SHA256加盐处理,更进阶的是使用Rfc2898DeriveBytes这类渐次拉伸算法。这套源码如果是从实际项目改来的,密码字段基本不会明文存储,你读到用户表结构的时候可以留意一下。

登录状态的判断,在MVC里可以靠[Authorize]过滤器完成。标记了这个特性的控制器或动作方法,匿名用户访问时会被自动重定向到登录页。这套机制的工作原理是管道模型,请求进入MVC管道后,AuthorizeAttribute在处理之前检查当前用户身份是否有效。理解了这层逻辑,做“仅登录用户可评论”功能就是加一行特性的事。

3.2 发表博文链路:模型绑定背后的数据流

发表博文看起来只是“填个表单点提交”,但它的代码流转能体现出三层架构的核心价值。

ArticleController里有一个Create动作方法,用GET方法时返回ArticleCreateViewModel视图供用户填写;用POST方法时接收表单数据。MVC的模型绑定器会自动把表单字段(标题、正文、分类ID、标签列表)映射到Article实体或视图模型上,这一步省掉了以前Web Forms时代手动读取Request.Form["Title"]的繁琐代码。

之后的故事是这样的:

  1. 控制器检查ModelState.IsValid,确保标题必填、正文字数满足最低要求。
  2. 调用业务逻辑层ArticleManage.Create(article, tagNames)方法。
  3. 业务层执行一系列规则:文章状态设为“已发布”,生成SEO友好的URL别名,把标签字符串拆分成列表并去重。
  4. 业务层调用数据访问层的ArticleRepository.Insert(article)。如果事务需要跨多张表(文章表、标签表、文章标签关联表),事务控制也在这层开启。
  5. 数据访问层通过Entity Framework上下文把实体状态标记为Added,执行SaveChanges,数据库完成插入。
  6. 控制器重定向到文章详情页。

请注意第3步和第4步。很多初学三层架构的人,最容易犯的错是让Controller直接调用DAL,或者让Controller里的代码承载业务逻辑。但在这套源码里,你看到的是一个清晰的职责分配:Controller只是“传话的人”,BLL才是“拍板的人”。

我在修改这类源码时,有一个习惯:在业务层方法里加日志。比如ArticleManage.Create执行前记录“用户X开始创建文章”,执行后记录“文章Y创建成功,耗时Z毫秒”。这样排查问题的时候,一眼就能看出是哪个环节慢了,还是哪一步报错了。这也是三层架构的隐形福利,每个层次都有机会埋点,而不是把所有逻辑堆在Controller里,出了问题全靠断点。

3.3 评论链路:外键关系与级联操作的正确处理

评论功能是博客系统里展示数据库关系最典型的地方。一条评论必然属于某个用户,也必然属于某篇文章。在数据表设计上,评论表会有两个外键:UserIdArticleId

在EF(Entity Framework)的代码优先模式下,实体类长这样:

public class Comment { public int Id { get; set; } public string Content { get; set; } public DateTime CreateTime { get; set; } public int ArticleId { get; set; } public virtual Article Article { get; set; } public int UserId { get; set; } public virtual User User { get; set; } }

发表评论的流程是:评论表单POST到CommentControllerCreate方法,控制器组装Comment实体,调用CommentManager.AddComment(comment),业务层做防重复提交和内容安全过滤后,调用CommentRepository.Insert(comment)完成入库。

评论列表的展示,通常是在文章详情页通过Article实体的导航属性来加载:

var comments = context.Comments .Where(c => c.ArticleId == articleId && c.IsApproved == true) .OrderByDescending(c => c.CreateTime) .ToList();

这里有一个值得注意的设计决策。删除文章的时候,这篇文章下的评论怎么处理?如果数据库外键设置了级联删除,删除文章时数据库会自动删除所有关联评论,这是省事的方式。但有些博客系统会故意保留评论数据,只做逻辑删除,给文章表加一个IsDeleted字段。两种方案没有绝对的对错,核心原则是——外键的删除规则必须在建表时明确,否则运行到一半会报外键约束冲突。

我在跑这套源码的时候,遇到过实体加载奇怪的错误,比如评论数据死活加载不出来,后来发现是EF的延迟加载(Lazy Loading)配置问题。virtual关键字缺失、代理创建被禁用、连接字符串里LazyLoadingEnabled=false,任何一个环节不对,导航属性就返回空。建议你拿到源码后先检查这三个地方,能帮你省掉至少一个小时的排错时间。

4. 数据库设计里的关键决策——这套博客源码在表结构上想明白了哪些事

数据层是三层架构的底座。数据库设计的好坏,直接决定业务逻辑层写起来顺不顺手。我拆过很多套博客系统源码,把常见表结构和设计思路都摆出来对比,你就能看出这套源码的水平了。

4.1 核心表结构与字段设计要点

一套完整的博客系统数据库,至少包含以下这些表:用户表(User)、文章表(Article)、文章分类表(Category)、评论表(Comment)、标签表(Tag)、文章标签关联表(ArticleTagRelation)。有些系统还扩展了友情链接表、配置表、操作日志表。

我从这些表里挑几个关键字段进行分析:

表名字段设计要点
UserUserName唯一约束,登录凭证,不允许重复
UserPassword存储哈希值,一般不允许明文
UserCreateTime默认值设为GetDate(),由数据库自动填充
ArticleTitle必填,长度一般在200以内,过长影响索引效率
ArticleContent使用nvarchar(MAX),博客正文长度不可控
ArticleViewCount热门文章排序依据,需要注意并发更新问题
ArticleStatus0草稿、1已发布、2已删除,用int枚举比字符串更高效
CategoryCategoryName唯一约束,分类名重复会导致归档混乱
CommentContent最长限制,防止超大文本拖垮接口性能
TagTagName唯一约束,标签需要去重统计

关于字段类型,有两点值得单独说。第一,包含中文内容的字段必须用nvarchar,不能用varchar,否则中文可能显示乱码。第二,时间字段建议用datetime2而不是datetime,因为datetime的精度只能到3毫秒,而datetime2精度更高,范围更大,EF Core在映射上对datetime2的支持也更友好。这两点都是只看源码很难发现,只有真正去建表跑数据才会踩到的坑。

4.2 主外键关系和索引设计

用户表和文章表是典型的一对多关系,一个用户可以发布多篇文章。文章表和评论表是一对多关系,一篇文章可以拥有多条评论。文章和标签是多对多关系,需要通过中间表来维护,这是初学者最容易搞错的地方——直接在文章表里加一个TagNames字符串字段,用逗号分隔标签。这样做看似简单,但后续要按标签归档、统计标签数、搜索某标签下的文章,SQL写起来会非常痛苦。

正确的解法是建立三张表:Tag表存标签名,Article表存文章,ArticleTagRelation表只存两列外键。查询一个标签下的所有文章,就是一条JOIN语句的事。

索引设计方面,这套源码有几处值得借鉴的决策。文章表的CreateTime字段应该建索引,因为博客首页和列表页最常用的排序就是按发布时间倒序,没有索引的话,数据量一上来,这个查询会全表扫描。评论表的ArticleId字段必须建索引,因为文章详情页要按文章ID查所有评论。而阅读量字段ViewCount是否建索引,取决于有没有“热门文章Top10”这样的功能,如果没有,就不必建,省点存储空间。

4.3 用SQL看一条最复杂的查询在这套结构里长什么样

“获取某个分类下按发布时间倒序的所有已发布文章,并附带每篇文章的评论数”应该是这个系统里比较复杂的查询之一。在EF的LINQ写法下看起来是这样的:

var articles = context.Articles .Where(a => a.CategoryId == categoryId && a.Status == 1) .OrderByDescending(a => a.CreateTime) .Select(a => new ArticleListItemViewModel { Id = a.Id, Title = a.Title, CreateTime = a.CreateTime, CommentCount = a.Comments.Count(c => c.IsApproved == true) }) .Skip((pageIndex - 1) * pageSize) .Take(pageSize) .ToList();

这段代码能正常工作,但说实话,性能上存在隐患。CommentCount会触发针对每条文章子查询,如果分页返回20篇文章,数据库就要额外执行20次评论表子查询,N+1问题就是这么来的。

如果要优化,可以先把文章分页查出来,再用一次IN查询批量查出这些文章的评论数,最后在内存中组合数据。高端的程序员和低端的程序员的差距,经常就体现在这种看起来不起眼的代码里。我把这个例子写出来,是想提醒你:三层架构分层清晰,不代表你写的代码性能就自动好,架构和具体SQL的质量是两个维度的事。

5. 从下载源码到跑通项目——环境还原中一定会遇见的几个坑

拿到源码最兴奋也最容易受挫的时刻,就是双击打开解决方案,按F5运行。我前后帮人排查过不下二十次环境问题,总结了下面这几个高频坑,提前知晓能省不少事。

5.1 项目框架版本不对,解决方案根本打不开

这套源码如果是老项目,大概率基于.NET Framework 4.7.x或4.8,对应的ASP.NET MVC版本是MVC 5.x。如果基于.NET 6/7/8/9,那就是ASP.NET Core MVC,源码结构和配置方式会有较大差异。

打开项目之前,先看解决方案文件里有没有global.json文件(Core项目会有),或者直接用文本编辑器看.csproj文件里的TargetFramework节点。老项目的标记是net48,新式项目是net8.0net9.0。如果你的电脑装的是Visual Studio 2022,建议同时安装“.NET 桌面开发”和“ASP.NET和Web开发”两个工作负载,老项目的.NET Framework 4.8开发包也一并装上。

有一个经典报错叫“The type or namespace name 'Mvc' does not exist”。出现这个错误,十有八九是NuGet包还原失败。解决办法是在解决方案上右键,选择“管理解决方案的NuGet程序包”,查看哪些包是黄色的感叹号,重新安装对应版本的包即可。还有一种可能是项目的目标框架版本低于4.5,System.Web.Mvc程序集没有引用成功。检查一下项目引用里有没有浅黄色的感叹号,有的话删掉重新添加。

5.2 数据库连接字符串和EF迁移没对上

三层架构的博客系统,连接字符串通常写在Web.config(.NET Framework)或者appsettings.json(.NET Core)里。大多数源码默认连接的是SQL Server的LocalDB本地数据库,上线的生产环境要改成正式数据库地址。

连接字符串典型配置长这样:

<connectionStrings> <add name="BlogDbContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=MyBlogDb;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>

跑起来之前,要先确认两件事。第一,本地是否安装了SQL Server Express LocalDB。没有的话,去Visual Studio Installer里装“数据存储和处理”组件,或者直接下载SQL Server Express安装也行。第二,数据库到底有没有被创建。EF的Code First模式默认是CreateDatabaseIfNotExists策略,如果这个策略被改成了DropCreateDatabaseAlways,每次启动都会删库重建,测试数据全没,跑了几次才发现就晚了。

5.3 登录页面跳转死循环或验证码不显示

登录死循环是个奇怪但发生率极高的现象。现象是输入正确账号密码后,页面不断重定向回登录页。排查思路分三步走。

第一步,确认表单身份验证的登录URL配置正确。Web.config里forms loginUrl指向的是/Account/Login,如果大小写不对,跳转就会失败。

第二步,确认[Authorize]过滤器是否不小心加到了AccountController本身上。有些初学者为了省事,把[Authorize]加到整个控制器类上,结果登录接口也被拦截,形成死循环。

第三步,确认Cookie相关的配置,比如httpOnlyCookiesrequireSSL设置是否合理,本地调试时requireSSL设为false,否则浏览器可能不会写入Cookie。

如果说验证码不显示,则是另一个方向的坑。验证码图片通常由ValidateCode工具类动态生成,基于.NET FrameworkSystem.Drawing。如果部署到容器环境(比如Docker里的Windows镜像),System.Drawing的兼容性问题会导致图片生成异常。解决办法是把验证码生成逻辑迁移到SkiaSharp这类跨平台库,或者干脆在本地调试阶段直接配置验证码开关为关闭状态。

5.4 还有一个经常被忽略的“时区坑”

博客系统写入文章创建时间时,很多源码直接用了DateTime.Now。如果服务器时区设置的是UTC,你发布文章的时间会比北京时间晚8小时。调试的时候你可能不觉得,但上线后发现每篇文章的时间都怪怪的,就会很抓狂。

更靠谱的写法是用DateTime.Now加时区转换,或者统一存UTC时间,在显示层转换成当地时区。如果你拿到这套源码后发现时间乱,第一时间去看服务器/本地系统的时区设置和代码里时间获取的方式,通常都是这两个地方其中一个出了问题,代码层面并没有损坏。

6. 基于这套源码的进阶改造——从练手项目到能扛线上流量的博客系统

源码能跑通只是第一步。我建议你把这套三层架构的博客系统当成一个地基,往上叠加改造。以下按优先级排列,可以按顺序逐步做。

6.1 最要紧的:密码哈希和防SQL注入

如果源码里的密码字段是MD5哈希且没有加盐,建议立即改造成基于Rfc2898DeriveBytes的PBKDF2算法,这是.NET内置的加密算法,自带盐值,暴力破解成本比纯MD5高几个数量级。升级的时候注意:老用户的密码哈希格式和新的不一致,要么迁移时给老用户标记一个“需要重置密码”的状态,要么做哈希版本兼容。

防SQL注入方面,三层架构+EF已经从机制上规避了95%的注入风险。真正需要检查的是那些用了原生SQL字符串拼接的地方,比如搜索功能的关键词拼接、排序字段动态拼进SQL。如果你在源码里看到类似"SELECT * FROM Article WHERE Title LIKE '%" + keyword + "%'"这样的代码,绝对要想办法改成参数化查询。这也是面试官最爱问的防注入问题——直接打开源码指着某一段代码说“这里用了参数化方式解决”,比背概念要有说服力得多。

6.2 基础设施:日志、异常处理和Autofac依赖注入

原版源码报错了大概率是黄页(开发模式下的异常页面),生产环境不能这么干。建议引入NLog或者Serilog做结构化日志,在Global.asax(老项目)或Program.cs(新版)里注册全局异常过滤器。用户看到的是友好错误页,开发者在日志里看到的完整堆栈。

依赖注入是另外一个值得深入的方向。原版代码里Controller直接newArticleManager,而ArticleManagernewArticleRepository,虽然没有违反分层原则,但耦合度略高。改成构造函数注入之后,单元测试可以轻松用Mock对象替换真实仓储,这对维护一个长期项目非常重要。老项目用AutofacUnity,新项目直接用内置的DI容器,配置方式网上资料非常多。

6.3 性能优化:缓存和异步化

博客系统的读多写少特性,让缓存优化收益极高。你可以从两级缓存开始改造:一级是数据缓存,把热门文章列表、分类归档信息缓存到MemoryCache,设置5到10分钟的过期时间,绝大多数数据库压力都能扛下来。二级是输出缓存,对首页、分页列表等相对静态的页面,可以直接缓存整页输出。

异步化改造则是把DAL层的EF查询改造成async/await模式,ToListAsync代替ToList,控制器动作方法签名改成async Task<ActionResult>。IIS或Kestrel在处理异步请求时能释放线程,让服务器同时处理更多请求。这是一项性价比很高的改造,代码改动量不大,但对并发能力的提升非常明显。

6.4 富文本编辑器的集成和XSS过滤

博客系统的文章编辑,几乎离不开富文本编辑器。这套源码里如果用的是UEditorCKEditorwangEditor,就会涉及XSS过滤的问题。用户提交的富文本HTML中包含<script>标签或者onerror事件时,如果没有过滤就原样入库、原样渲染,等于给攻击者开了一扇门。

我的做法是,在业务逻辑层加一道HtmlSanitizer处理。服务端收到富文本后,白名单式地过滤掉危险标签和危险属性,再写入数据库。这条规则不放在数据访问层,更不放在控制器里,而是放在业务层,正好是三层架构里业务规则的合理归位。

6.5 从博客单体到多项目的演进路径

如果你有兴趣把这套源码演变成一个更大型的项目,逻辑上的下一步是把解决方案拆分成更多项目:增加独立的Common公共类库,放扩展方法、加密工具、通用分页组件;增加独立的IRepository接口项目,让DAL的项目可以单独替换实现。等业务复杂到一定程度,再考虑引入事件总线、CQRS或者微服务拆分——但这些都是后话了。

我做这套源码的评测和讲解,最大的感受是:很多初学者拿到代码第一反应是“跑起来”,然后就没有然后了。其实源码最大的价值不是让你复制粘贴,而是给你一个基准线。往上加功能,往下修性能,往深挖原理,都有了一个稳定的起点。

最后分享一个我个人的小习惯。我拿到任何一套源码,都会先搜索所有出现new关键字的地方。哪个类被new得最多,往往就是耦合最集中的地方,也是架构上最值得关注的地方。你拿这套博客系统源码试一遍,应该能一眼看出它的问题,也能看出它的优点在哪。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 22:28:54

我原以为ML管道只有3步,上线两周后模型开始胡言乱语

我原以为ML管道只有3步,上线两周后模型开始胡言乱语 发版第三天的下午,推荐模型准时开始「胡言乱语」--首页给买了猫粮的用户强推狗粮,准确率从 0.82 掉到 0.61。群里我的消息一条接一条,我一边回滚到上一版模型,一边心里骂自己:当初搭建机器学习管道的时候,怎么就只做了数据预…

作者头像 李华
网站建设 2026/9/1 22:28:49

小米测开笔试全解析:核心考点与备考策略

1. 真题结构复盘&#xff1a;小米测开笔试到底在筛什么人1.1 试卷题型与时间分配先说说整体印象。小米2020校招测试开发这套笔试题&#xff0c;卷子结构其实非常典型&#xff1a;选择题&#xff08;单选多选&#xff09;、简答题、算法编程题&#xff0c;偶尔还夹杂一两道场景设…

作者头像 李华
网站建设 2026/9/1 22:26:33

2021小米秋招软件开发笔试复盘:稳定输出与时间分配是关键

2021年小米秋招软件开发方向第一场笔试&#xff0c;我是在宿舍楼下的自习室里考的。当时电脑旁摆着三瓶矿泉水&#xff0c;耳机里放的是白噪音&#xff0c;整个笔试时长两个小时左右。考完的瞬间我只有一个感觉&#xff1a;这考试不像是在考你会不会背知识点&#xff0c;而是在…

作者头像 李华
网站建设 2026/9/1 22:24:33

Matlab实现分布式电源接入配电网影响分析:从建模到报告全解析

简介&#xff1a;本资源面向计算机、电子信息工程及数学等相关专业本科生&#xff0c;聚焦分布式电源接入对配电网运行特性的影响分析&#xff0c;适用于课程设计、期末大作业或毕业设计阶段的建模仿真实践。压缩包共17个文件&#xff0c;含16个MATLAB核心脚本&#xff08;如ne…

作者头像 李华
网站建设 2026/9/1 22:24:06

AI撰写CSDN技术博客:为何拒绝?如何正确提问?

抱歉&#xff0c;这个主题我无法为你撰写成 CSDN 技术博客。原因很简单&#xff1a;从标题看&#xff0c;它属于角色扮演类内容记录&#xff08;replay&#xff09;&#xff0c;不是技术项目、工具、框架或开发经验。CSDN 的读者期待的是可落地、可验证、可复用的技术内容&…

作者头像 李华
网站建设 2026/9/1 22:22:52

开源AI电话代理OpenCyvis:基于LLM的语音交互系统构建指南

在 AI 应用开发领域&#xff0c;将大语言模型的能力从文本对话延伸到真实世界的交互&#xff0c;尤其是通过电话进行沟通&#xff0c;是一个极具挑战性和实用价值的方向。传统的 AI 电话客服或外呼系统往往依赖于昂贵的商业 API 和封闭的解决方案&#xff0c;其底层模型、业务流…

作者头像 李华