array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 《软件架构模式》-第一章分层架构(上) - 爱码网

第一章

分层架构

最通常的架构模式就是分层架构模式,即所谓的N层架构。这种模式对大部分JAVAEE应用程序来说是标准模式,因此被大部分架构师、软件设计师、开发者广泛知晓。由于分层架构模式和公司里传统的IT沟通以及组织结构非常类似,使得它成为大多数商务应用开发最自然的选择。

模式描述

在分层架构模式中,它将应用分成多个水平层,每个水平层在应用中担任一个专门的角色(比如表现层或者业务逻辑)。尽管分层架构模型并没有指定必须的层次个数以及类型,但大部分这种模型都由4个标准层次构成:表现层、业务层、持久层、数据库(图1)。在一些情况下,业务层和持久层可以合为一个单一的业务层中,特别是当持久层的逻辑(比如SQL或者HSQL)内嵌于业务层中。因此小应用程序通常只有三个层‑次,至于更大或者更多的复杂商业应用可能会包含5个或者更多的层次。

在此架构中每层都有一个特定的角色和责任。比如,表现层负责处理所有用户交互和浏览器沟通的逻辑,业务层可能会负责执行和要求相关的特定业务。架构中每层都是每个特定的小作业的抽象,比如表现层必须要或者担忧怎样拿到顾客的数据。它只需要按特定格式显示信息在屏幕上。而同理业务层也不需要担忧如果格式化地显示客户的数据或者甚至不需要知道客户数据是从哪里来。它只需要从持久层得到数据,基于数据执行业务逻辑(比如计算数值)再把信息上传给表现层。

《软件架构模式》-第一章分层架构(上)

这种模型一个强大的特征是隔离开组件按照不同层次。每个层次中的组件只需要处理属于那个层次的功能逻辑即可。比如在展示层的组件只需要处理展示的逻辑,而业务层中的组件只需要处理业务逻辑。这样的组件分类方式便于建立高效的角色和责任制的模型,同时也会方便开发、测试、管理、维护应用,因为设计完善的组件接口以及限制的组件功能范围。

关键概念

注意在图1-2中,架构中的每个层次被标记为封闭状态。在该架构模式中,这是一个非常重要的概念。一个封闭的层次意味着当需要把消息从一层传递给另一层时,它必须先通过位于第一层正下方的那层,才能达到再下面的一层。例如,一个来自于表现层的要求,必须先通过业务层、持久层才最终到达数据库。

《软件架构模式》-第一章分层架构(上)

那么为什么不让表现层直接到达数据库呢?这样速度会更快。这里就牵涉到了一个关键概念叫层次分离。

层次分离意味着不同层次间互不影响,你在一个层次上的改动不会影响其他层次。如果你让表现层能直接访问持久层,会导致任何在持久层SQL上面的改动既会影响业务层也会影响表现层,这造成了应用中不同组件之间的强耦合影响,这样的应用架构也会变得难以修改。

层次分离也意味着不同层次间相对独立,因此不需要知道另一个层次的内部实现。理解这一点,考虑一个把表现层架构从JSP转换成JSF的大型重构项目,假设表现层和业务层间的协议不变,那么业务层不受重构的影响,不会受表现层架构改变的影响。

闭合的层次达成层次分离,会有助于不同层间互不影响,但是也有需要层次开放的时候。例如,假设在一个架构中,有一些需要被业务层次的通用服务组件,因此你想要加一个共享服务层。在种情况,创建一个服务层通常是一个好办法。因为架构上,它限制了访问这些共享服务层的必须是业务层而不是表现层。如果没有一个单独的服务层,在架构上就不会限制表现层对其的访问,这样也会造成管理访问权限变得困难。

在这个例子中,新服务层位于业务层下,意味着表现层不能直接访问该层。然后新的问题是,业务层需要穿越新服务层才能到达持久层,这不符合逻辑。实际上,这个问题可以通过设置开放层次解决。

在图1-3所示,服务层被标志成开放状态,意味着业务层允许跨越这层而直接访问持久层。这在逻辑上是相符的。

《软件架构模式》-第一章分层架构(上)

借助闭环或者开环层次的概念帮助我们定义架构中层次间的关系以及方向流,同时提供给设计者和开发师必要的信息去理解不同层次的访问限制。没有记录或者没能和层间合适地沟通通常会导致过紧的耦合以及脆弱的难以测试、维护、部署的架构。

转载自 并发编程网 - ifeve.com

相关文章: