一起谈.NET技术,Microsoft NLayerApp案例理论与实践 - 多层架构与应用系统设计原则

简介:   在对NLayerApp实际项目进行讨论之前,让我们首先学习一下(或者应该说重温一下)分层/多层架构与应用系统设计原则。很多朋友会认为这些都是老掉牙的内容,只要是软件从业人员,都会对这些内容非常熟悉。

  在对NLayerApp实际项目进行讨论之前,让我们首先学习一下(或者应该说重温一下)分层/多层架构与应用系统设计原则。很多朋友会认为这些都是老掉牙的内容,只要是软件从业人员,都会对这些内容非常熟悉。然而,果真如此吗?我在这里整理这部分内容,一方面是为介绍NLayerApp打下基础,而另一方面,则是希望借此机会将这些理论性的东西做个归纳,也希望读者朋友能够认真阅读,毕竟温故知新嘛。

  需要说明的是,从本章节开始,大多数理论性的东西都源自Microsoft Spain团队针对NLayerApp所编写的《Architecture Guide Book》,事实上这本Guideline的英文版至今也还没有完成,我会从中抽出部分章节做些翻译和归纳,有兴趣的朋友请直接上microsoftnalyerapp.codeplex.com站点上下载英文版阅读。

  Layers与Tiers

  对Layers与Tiers这两个单词进行区分是非常重要的。从中文翻译看,两者都是层的意思,因此我们往往会将这两个概念弄混。Layer一词更多的是表示对系统组件或功能的逻辑区分,它并没有包含将组件分布到不同的区域、不同的服务器上的意思。而Tier则是表示系统组件和功能在服务器、网络环境以及远程位置的物理部署。尽管这两个概念同时使用者非常相近的一些术语,比如展示、服务、业务和数据等,但我们必须了解它们之间的差别。下面这幅图表明了多层(N-Layer)逻辑架构与三层(3-Tier)物理结构之间的差异:

image

  需要注意的是,对于具有一定复杂度的应用程序而言,采用多层(N-Layer)逻辑架构的实现方式是非常必要的,这会降低系统的复杂度,并在设计、开发、测试、部署及维护等各个环节为应用系统带来高可用性、高延展性等正面效应。然而,并非所有的应用程序必须以三层(3-Tier)/多层(N-Tier)物理结构进行部署,我们可以将多个逻辑层部署在同一台机器上,也可以根据需求,将这些逻辑层部署在网络中的不同机器上。

  逻辑分层(Layer)的设计

  在讨论DDD的分层之前,先让我们看看传统的分层方式。就像上文所述,我们应该根据项目的实际需求,将组件/功能模块合理地划分到逻辑层中。同一层中的组件,应该是高内聚的,并具有相同的抽象层次。层与层之间应该低耦合。对于以分层设计的应用程序而言,最关键的问题就是如何处理层与层之间的依赖关系。考察传统的多层架构应用,处于某层的组件,只能对同层或下层的其它组件进行访问,这样做可以有效地降低层与层之间的依赖关系。通常会有两种分层设计:严格分层与灵活分层

  1. 严格分层迫使组件只能访问同层的其它组件,或者只能访问直接下层的其它组件,于是,第N层的组件只能访问第N或N-1层的组件,而第N-1层的组件只能访问第N-1或N-2层的组件,以此类推
  2. 灵活分层允许组件访问同层的其它组件,以及所有下层的其它组件,于是,第N层的组件可以访问第N或N-1、N-2…层的组件

  使用灵活分层的架构可以提高系统性能,因为这样的结构无需引入过多的请求/反馈的传递操作,因为一个层可以直接访问位于其下的任何层;而严格分层却降低了层与层之间的耦合性,对低层的修改不会对整个系统造成广泛的影响。根据Eric Evans在其《领域驱动设计-软件核心复杂性应对之道》一书中的描述,DDD的分层选用的是灵活分层模式。

  让我们再把讨论的粒度细化,来看看层中的组件与组件之间的关系。事实上,在很多复杂的应用中,位于同一层的组件与组件虽然具有相同的抽象层次,它们也不一定是高内聚的。因此,我们可以引入模块(Module)的概念,将同一层中高内聚的组件放在同一个模块中,于是,每个层又会由一个或多个高内聚的子系统(模块)所组成,如下UML组件图所示:

image

  使用分层架构,有如下几点好处:

  • 提高系统的可测试性
  • 对解决方案的维护和管理变得更加简单。层内高内聚、层间低耦合的结构,使得系统实现与分层组织方式变得非常灵活方便
  • 其它外部应用程序能够非常方便地使用不同的层所提供的特定功能
  • 当系统以层的方式进行组织时,分布式开发也变得非常简单易行
  • 在某些情况下,分层系统的物理部署方式能够给系统带来延展性,当然,应该有效地评估具体的实践方式,因为这种做法有可能损伤系统性能

  应用系统基本设计原则 - SOLID

  应用系统的设计应该遵循一些基本的设计原则,这能帮助你有效地创建一个低成本、高可用、高可扩展的应用程序。在这里,我们引入一个SOLID设计原则,SOLID由如下几点构成:

  • Single Responsibility Principle(单一职责原则)
  • Open Close Principle(开-闭原则)
  • Liskov Substitution Principle(里氏替换原则)
  • Interface Segregation Principle(接口分离原则)
  • Dependency Inversion Principle(依赖反转原则)

  下面简要介绍一下这几个原则。

  • 单一职责原则:每个类应该只有一个独一无二的职责,或者说每个类只能有一个主要功能,由此派生出一个结论:每个类应该尽可能少地依赖于其它类
  • 开-闭原则:每个类,应该对扩展进行开放,而对修改进行封闭,也就是支持扩展,而不是支持修改:类中的方法可以通过继承关系进行扩展,而不会改变类本身的代码
  • 里氏替换原则:子类可以被基类型(基类或者接口)替换。应用程序依赖抽象运行,其行为不会因为具体实现的改变而更改,应用程序应该依赖于抽象(基类或者接口),而不是具体实现。接下来将要讨论到的依赖注入(Dependency Injection)就与这条原则有关
  • 接口分离原则:接口的职责也应该是单一的,接口中应该包含哪些方法,需要进行严格的评估,如果其中某些方法的职责与接口的本身定义不相符合,则应该将其分离到其它接口中。类需要根据其调用者所需要的不同接口类型,来暴露不同的接口
  • 依赖反转原则:抽象不能依赖于具体,而具体则应该依赖于抽象。类之间的直接依赖应该用抽象来取代,这样做的一个优点是,我们可以实现自上而下的设计方式:在下层的具体实现还没有确定的情况下,只要能够在抽象层面将接口确定,就能够完成上层的设计与开发,这同样给可测试性带来便捷

  除了以上所述的SOLID原则之外,还有以下几个关键的设计原则可供参考:

  • 组件设计应该是高内聚的:相信大家都很熟悉这点了,就不多说了。例如:不要将数据访问逻辑写进领域模型的业务逻辑中,这与上述单一职责原则是密切相关的
  • 将Cross-Cutting的代码从特定于应用程序的逻辑中分离开来:Cross-Cutting的代码是一些面向横面的代码,比如安全、操作管理、日志以及测量/计量系统等。将这些代码与应用系统业务逻辑混在一起会增加系统的复杂性,给将来的扩展和维护造成很大的麻烦。这与面向方面编程(Aspect-Oriented Programming,AOP)有关
  • 关注点分离(Separation of Concerns,SoC):将应用系统分成多个子部分(子系统),各个部分之间的功能尽量不要重复,其目的就是为了减少交互点,以实现高内聚和低耦合
  • Don’t Repeat Yourself(DRY):一个特定的功能只能在某个特定的组件中实现一次,同样的功能不要在多个组件中重复多次
  • 避免YAGNI(You Ain’t Gonna Need It)效应:只考虑和设计必须的功能,避免过度设计

  好了,本讲就介绍到这里,估计对大多数接触过架构的软件朋友来说,本讲的部分内容都是废话。下一讲开始,我会花部分笔墨在DDD/DDDD的分层介绍上,虽然有可能还是废话,但这对我们理解NLayerApp的解决方案组织结构会有相当的帮助。

目录
相关文章
|
14天前
|
存储 运维 Serverless
千万级数据秒级响应!碧桂园基于 EMR Serverless StarRocks 升级存算分离架构实践
碧桂园服务通过引入 EMR Serverless StarRocks 存算分离架构,解决了海量数据处理中的资源利用率低、并发能力不足等问题,显著降低了硬件和运维成本。实时查询性能提升8倍,查询出错率减少30倍,集群数据 SLA 达99.99%。此次技术升级不仅优化了用户体验,还结合AI打造了“一看”和“—问”智能场景助力精准决策与风险预测。
146 69
|
1月前
|
弹性计算 负载均衡 网络协议
阿里云SLB深度解析:从流量分发到架构优化的技术实践
本文深入探讨了阿里云负载均衡服务(SLB)的核心技术与应用场景,从流量分配到架构创新全面解析其价值。SLB不仅是简单的流量分发工具,更是支撑高并发、保障系统稳定性的智能中枢。文章涵盖四层与七层负载均衡原理、弹性伸缩引擎、智能DNS解析等核心技术,并结合电商大促、微服务灰度发布等实战场景提供实施指南。同时,针对性能调优与安全防护,分享连接复用优化、DDoS防御及零信任架构集成的实践经验,助力企业构建面向未来的弹性架构。
180 76
|
28天前
|
人工智能 自然语言处理 API
MCP与A2A协议比较:人工智能系统互联与协作的技术基础架构
本文深入解析了人工智能领域的两项关键基础设施协议:模型上下文协议(MCP)与代理对代理协议(A2A)。MCP由Anthropic开发,专注于标准化AI模型与外部工具和数据源的连接,降低系统集成复杂度;A2A由Google发布,旨在实现不同AI代理间的跨平台协作。两者虽有相似之处,但在设计目标与应用场景上互为补充。文章通过具体示例分析了两种协议的技术差异及适用场景,并探讨了其在企业工作流自动化、医疗信息系统和软件工程中的应用。最后,文章强调了整合MCP与A2A构建协同AI系统架构的重要性,为未来AI技术生态系统的演进提供了方向。
435 62
|
18天前
|
存储 人工智能 开发框架
MCP 实践:基于 MCP 架构实现知识库答疑系统
文章探讨了AI Agent的发展趋势,并通过一个实际案例展示了如何基于MCP(Model Context Protocol)开发一个支持私有知识库的问答系统。
MCP 实践:基于 MCP 架构实现知识库答疑系统
|
22天前
|
存储 消息中间件 SQL
数据中台架构与技术体系
本文介绍了数据中台的整体架构设计,涵盖数据采集、存储、计算、服务及治理等多个层面。在数据采集层,通过实时与离线方式整合多类型数据源;存储层采用分层策略,包括原始层、清洗层、服务层和归档层,满足不同访问频率需求;计算层提供批处理、流处理、交互式分析和AI计算能力,支持多样化业务场景。数据服务层封装数据为标准化API,实现灵活调用,同时强调数据治理与安全,确保元数据管理、质量监控、权限控制及加密措施到位,助力企业构建高效、合规的数据管理体系。
|
17天前
|
存储 机器学习/深度学习 算法
阿里云X86/ARM/GPU/裸金属/超算等五大服务器架构技术特点、场景适配与选型策略
在我们选购阿里云服务器的时候,云服务器架构有X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器、高性能计算可选,有的用户并不清楚他们之间有何区别。本文将深入解析这些架构的特点、优势及适用场景,帮助用户更好地根据实际需求做出选择。
|
5月前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
123 5
|
8月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
131 7
|
8月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
154 0
|
12月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
293 0

热门文章

最新文章