首页 > 编程知识 正文

分层体系结构例子,sdn dc分层架构

时间:2023-05-06 04:23:14 阅读:172694 作者:3817

简介迷路的便当。 曾就职于中兴通讯、GDCC、中软国际、ThoughtWorks等大型中外企业,担任高级软件工程师、架构师、技术总监、首席顾问。 GitChat畅销书的作者。

熟悉Java、Scala、Python、C#、JavaScript、Ruby等多种语言,面向对象思想、测试驱动开发与重构、域驱动设计、函数式编程、体系结构、大数据分析、大数据分析致力于大型软件企业面向服务的系统架构设计、大数据平台架构设计、互联网Web系统架构设计

该翻译包括《软件设计精要与模式》、《Java 设计模式》、《恰如其分的软件架构》、《WCF 服务编程》、《人件》、《重构——改善既有代码设计》和《架构之美(Beatiful Architecture)》注释版以及《领域驱动设计模式、原理与实践》注释版。

版权声明

正文及正文相关课程均由GitChat平台独家发布,未经许可不得转载。

识别层次结构层次结构是应用最广泛的结构模型,大多数软件系统通过分层隔离不同的兴趣点来适应不同需求的变化,并对其变化保持独立此外,分层体系结构模型也是分离业务复杂性和技术复杂性的工具。 《领域驱动设计》写道。

为了使代码库成为BBoM以削弱域模型的完整性,最终不降低可用性,系统体系结构必须支持技术复杂性和域复杂性的分离。 技术实现变化的原因和领域逻辑变化的原因明显不同,基础设施和领域逻辑问题会以不同速率发生变化。

本文所用的“以不同速度变化”实际上是指引起变化的原因各不相同,这正好是单一责任原则(Single-Responsibility Principle,SRP )的体现。 Robert Martin认为单一责任原则是“一个类应该只有一个原因引起它的变化”。 换句话说,如果有两个原因引起类的变化,就需要分离。 单一职责原则可以理解为框架原则,它考虑的不是类别,而是层次。 为什么要把商业和基础设施分开呢? 因为引起那些变化的原因不同。

经典的分层体系结构分层体系结构由来已久,分层一个软件系统似乎已经成为每个开发者的固有意识,不用想就能自然而然地得到。 其中最典型的是三层结构和区域驱动设计提出的四层结构。

经典三层架构

在软件体系结构中,经典的三层体系结构自顶向下由用户接口层、业务逻辑层和数据访问层组成。 这个阶层结构之所以能流行,是有历史原因的。 在提出该层次结构的时代,许多企业系统都比较简单,本质上都是单体结构(Monolithic Architecture )的数据库管理系统。 该分层架构已经是客户端-服务器架构的演进,可以有效地分离业务逻辑和数据访问逻辑,使这两种不同的兴趣点相对自由独立地演进。 典型的三层体系结构如下。

领域驱动设计的经典分层架构

领域驱动设计在经典的三层结构的基础上做了进一步的改进,在用户接口层和业务逻辑层之间引入了一个新的层,即APP应用层。 同时,几个层面的命名也发生了变化。 将业务逻辑层更名为域层是理所当然的,而将数据访问层更名为基础设施层,突破了数据库管理系统一直以来的限制,扩大了基础层封装技术复杂性的内涵下图显示了Eric Evans经典著作《面向模式的软件架构》的层次结构。

追寻层次结构的本源

当分层结构越来越普及时,我们的设计反而僵化了。 一些软件设计师不理解层次结构的本质,只知道画葫芦把层次应用于系统。 要么采用经典的三层体系结构,要么遵循由域驱动的经过设计和改进的四层体系结构,这样的分层是否有hsdgtx,我没有思考就询问了一下。 这是阶层结构被滥用的根源。

因为层(Layer )是固有的体系结构模型,所以其乱舞必须是Frank Buschmann等人所著的《模式系统》第一卷《模式系统》。 该模型参考了ISO相对于TCP/IP协议的分层。 0103010层次结构说明:

分层体系结构模型有助于构建一个APP,其中每个子任务组可以分解为特定抽象级别的xldfj任务组。

显然,这里所说的“分层”首先是逻辑分层,分解子任务组需要考虑抽象层次、层次的抽象层次。 既然是水平层次,就一定存在层次的高低; 抽象级别的差异决定了层次的数量。 因此,分层体系结构需要解决以下问题:

分层的依据和原则是什么? 图层和图层是如何合作的?分层的依据与原则

我们之所以将整个系统水平分层,是因为我们有意识地决定了认知规则。机器为本,用户至上机器是运行系统的基础,而我们制作的系统是为用户提供服务的。 层次结构的层次越上

,其抽象层次就越面向业务,面向用户;分层架构中的层次越往下,其抽象层次就变得越通用,面向设备。为什么经典分层架构为三层架构?正是源于这样的认知规则:其上,面向用户的体验与交互;其中,面向应用与业务逻辑;其下,面对各种外部资源与设备。在进行分层架构设计时,我们完全可以基于这个经典的三层架构,沿着水平方向进一步切分属于不同抽象层次的关注点。因此,分层的第一个依据是基于关注点为不同的调用目的划分层次。以领域驱动设计的四层架构为例,之所以引入应用层(Application Layer),就是为了给调用者提供完整的业务用例。

分层的第二个依据是面对变化。分层时应针对不同的变化原因确定层次的边界,严禁层次之间互相干扰,或者至少将变化对各层带来的影响降到最低。例如数据库结构的修改自然会影响到基础设施层的数据模型以及领域层的领域模型,但当我们仅需要修改基础设施层中数据库访问的实现逻辑时,就不应该影响到领域层了。层与层之间的关系应该是正交的。所谓“正交”,并非二者之间没有关系,而是垂直相交的两条直线。唯一相关的依赖点是这两条直线的相交点,即两层之间的协作点。正交的两条直线,无论哪条直线进行延伸,都不会对另一条直线产生任何影响(指直线的投影)。如果非正交,即“斜交”,当一条直线延伸时,它总是会投影到另一条直线,这就意味着另一条直线会受到它变化的影响。

在进行分层时,我们还应该保证同一层的组件处于同一个抽象层次。这是分层架构的设计原则,它借鉴了 Kent Beck 在 Smalltalk Best Practice Patterns 一书提出的“组合方法”模式。该模式要求一个方法中的所有操作处于相同的抽象层,这就是所谓的“单一抽象层次原则(SLAP)”。这一原则可以运用到分层架构中。例如在一个基于元数据的多租户报表系统中,我们特别定义了一个引擎层(engine layer),这是一个隐喻,相当于为报表系统提供报表、实体与数据的驱动引擎。引擎层之下,是基础设施层,提供了多租户、数据库访问与元数据解析与管理等功能。在引擎层之上是一个控制层,通过该控制层的组件可以将引擎层的各个组件组合起来。分层架构的顶端是面向用户的用户展现层。如下图所示:

层之间的协作

在我们固有的认识中,分层架构的依赖都是自顶向下传递的,这也符合大多数人对分层的认知模型。从抽象层次看,层次越处于下端,就会变得越通用越公共,与具体的业务隔离得越远。出于重用的考虑,这些通用和公共的功能往往会被单独剥离出来形成平台或框架,在系统边界内的低层,除了面向高层提供足够的实现外,就都成了平台或框架的调用者。换言之,越是通用的层,越有可能与外部平台或框架形成强依赖。若依赖的传递方向仍然采用自顶向下,就会导致系统的业务对象也随之依赖于外部平台或框架。

依赖倒置原则(Dependency Inversion Principle,DIP)提出了对这种自顶向下依赖的挑战,它要求“高层模块不应该依赖于低层模块,二者都应该依赖于抽象。”这个原则正本清源,给了我们当头棒喝——谁规定在分层架构中,依赖就一定要沿着自顶向下的方向传递?我们常常理解依赖,是因为被依赖方需要为依赖方(调用方)提供功能支撑,这是从功能重用的角度来考虑的。但我们不能忽略变化对系统产生的影响!与建造房屋一样,我们自然希望分层的模块“构建”在稳定的模块之上。谁更稳定?抽象更稳定。因此,依赖倒置原则隐含的本质是:我们要依赖不变或稳定的元素(类、模块或层)。也就是该原则的第二句话:抽象不应该依赖于细节,细节应该依赖于抽象。

这一原则实际是“面向接口设计”原则的体现,即“针对接口编程,而不是针对实现编程”。高层模块对低层模块的实现是一无所知的,带来的好处是:

低层模块的细节实现可以独立变化,避免变化对高层模块产生污染在编译时,高层模块可以独立于低层模块单独存在对于高层模块而言,低层模块的实现是可替换的

倘若高层依赖于低层的抽象,必然会面对一个问题:如何将具体的实现传递给高层的类?由于在高层通过接口隔离了对具体实现的依赖,就意味着这个具体依赖被转移到了外部,究竟使用哪一种具体实现,由外部的调用者来决定。只有在运行调用者代码时,才将外面的依赖传递给高层的类。Martin Fowler 形象地将这种机制称为“依赖注入(dependency injection)”。

为了更好地解除高层对低层的依赖,我们往往需要将依赖倒置原则与依赖注入结合起来。

层之间的协作并不一定是自顶向下的传递通信,也有可能是自底向上通信,例如在 CIMS(计算机集成制造系统)中,往往会由低层的设备监测系统监测(侦听)设备状态的变化。当状态发生变化时,需要将变化的状态通知到上层的业务系统。如果说自顶向下的消息传递往往被描述为“请求(或调用)”,则自底向上的消息传递则往往被形象地称之为“通知”。倘若我们颠倒一下方向,自然也可以视为这是上层对下层的观察,故而可以运用观察者模式(Observer Pattern),在上层定义 Observer 接口,并提供 update() 方法供下层在感知状态发生变更时调用。或者,我们也可以认为这是一种回调机制。虽然本质上这并非回调,但设计原理是一样的。

如果采用了观察者模式,则与前面讲述的依赖倒置原则有差相仿佛之意,因为下层为了通知上层,需要调用上层提供的 Observer 接口。如此看来,无论是上层对下层的“请求(或调用)”,抑或下层对上层的“通知”,都颠覆了我们固有思维中那种高层依赖低层的理解。

现在,我们对分层架构有了更清醒的认识。我们必须要打破那种谈分层架构必为经典三层架构又或领域驱动设计推荐的四层架构这种固有思维,而是将分层视为关注点分离的水平抽象层次的体现。既然如此,架构的抽象层数就不是固定的,甚至每一层的名称也未必遵循固有(经典)的分层架构要求。设计系统的层需得结合该系统的具体业务场景而定。当然,我们也要认识到层次多少的利弊:过多的层会引入太多的间接而增加不必要的开支,层太少又可能导致关注点不够分离,导致系统的结构不合理。

我们还需要正视架构中各层之间的协作关系,打破高层依赖低层的固有思维,从解除耦合(或降低耦合)的角度探索层之间可能的协作关系。另外,我们还需要确定分层的架构原则(或约束),例如是否允许跨层调用,即每一层都可以使用比它低的所有层的服务,而不仅仅是相邻低层。这就是所谓的“松散分层系统(Relaxed Layered System)”。

该怎么演进领域驱动架构?

我们在上文中回顾了经典三层架构与领域驱动设计四层架构,然而任何技术结论都并非句点,而仅仅代表了满足当时技术背景的一种判断,技术总是在演进,领域驱动架构亦是如此。与其关心结果,不如将眼睛投往这个演进的过程,或许风景会更加动人。

根据“依赖倒置原则”与 Robert Martin 提出的“整洁架构”思想,我们推翻了Eric Evans 在《领域驱动设计》书中提出的分层架构。Vaughn Vernon 在《实现领域驱动设计》一书中给出了改良版的分层架构,他将基础设施层奇怪地放在了整个架构的最上面:

整个架构模型清晰地表达了领域层别无依赖的特质,但整个架构却容易给人以一种错乱感。单以这个分层模型来看,虽则没有让高层依赖低层,却又反过来让低层依赖了高层,这仍然是不合理的。当然你可以说此时的基础设施层已经变成了高层,然而从之前分析的南向网关与北向网关来说,基础设施层存在被“肢解”的可能。坦白讲,这个架构模型仍然没有解决人们对分层架构的认知错误,例如它并没有很好地表达依赖倒置原则与依赖注入。还需要注意的是,这个架构模型将基础设施层放在了整个分层架构的最顶端,导致它依赖了用户界面层,这似乎并不能自圆其说。我们需要重新梳理领域驱动架构,展示它的演进过程。

那么到底该怎么演进领域驱动架构?感兴趣的同学可以在我的达人课《领域驱动战略设计实践》里了解更系统的架构知识内容。这是专门为了想提高软件架构设计能力的软件架构师量身定制的系统课程,也是是国内第一个全面讲解 DDD 的原创课程。

本课程限时特价 39 元,共计 34 篇,形式为“图文+音频”;特价截止日期: 7月30日 。

扫码试读或点此试读购买

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。