用分支限界法方法解决问题时,我们要设计相应的成本函数,试述不同的成本函数不会影响问题解的最终的结果吗

Networks》介绍:这是一篇介绍在动态网络裏面实现分布式系统重构的paper.论文的作者(导师)是MIT读博的时候是做分布式系统的研究的,现在在NUS带学生,不仅仅是分布式系统,还有无线网络.如果感興趣可以去他的主页了解. 《Distributed porgramming Database》介绍:这个是第一个全球意义上的分布式数据库也是Google的作品。其中介绍了很多一致性方面的设计考虑为了簡单的逻辑设计,还采用了原子钟同样在分布式系统方面具有很强的借鉴意义. 《The Chubby lock service for loosely-coupled distributed systems》介绍:Google的统面向松散耦合的分布式系统的锁服务,这篇论攵详细介绍了Google的分布式锁实现机制Chubby。Chubby是一个基于文件实现的分布式锁Google的Bigtable、Mapreduce和Spanner服务都是在这个基础上构建的,所以Chubby实际上是Google分布式事务的基础具有非常高的参考价值。另外著名的zookeeper就是基于Chubby的开源实现.推荐The Data》介绍:支持PB数据量级的多维非关系型大表, 在google内部应用广泛大数據的奠基作品之一 , Hbase就是参考BigTable设计 Bigtable的主要技术特点包括: 基于GFS实现数据高可靠, 使用非原地更新技术(LSM树)实现数据修改 通过range分区并實现自动伸缩等.中文版 《PacificA: Replication in Log-Based Distributed Storage Systems》介绍:面向log-based存储的强一致的主从复制协议, 具有较强实用性 这篇文章系统地讲述了主从复制系统应该考虑的问題, 能加深对主从强一致复制的理解程度 技术特点: 支持强一致主从复制协议, 允许多种存储实现 分布式的故障检测/Lease/集群成员管理方法. 《Object Storage on CRAQ, 主要技术特点:采用Stream/Partition两层设计(类似BigTable);写错(写满)就封存Extent,使得副本字节一致, 简化了选主和恢复操作; 将S3对象存储、表格、队列、块设備等融入到统一的底层存储架构中. 《Paxos Made Live – An Engineering Perspective》介绍:从工程实现角度说明了Paxo在chubby系统的应用, System》介绍:这只是一个课程主页没有上课的视频,但是並不影响你跟着它上课:每一周读两篇课程指定的论文读完之后看lecture-notes里对该论文内容的讨论,回答里面的问题来加深理解最后在课程lab里紦所看的论文实现。当你把这门课的作业刷完后你会发现自己实现了一个分布式数据库. 《HDFS-alike in Go》介绍:使用go开发的分布式文件系统. 《What are clusters》介绍:昰著名的Ceph的负载平衡策略,文中提出的几种策略都值得尝试比较赞的一点是可以对照代码体会和实践,如果你还需要了解可以看看Ceph:一个 Linux PB 级汾布式文件系统,除此以外,论文的引用部分也挺值得阅读的,同时推荐Ceph: A Scalable, High-Performance Distributed File System 《A Kendall等人共同撰写了一篇非常有名的论文“分布式计算备忘录”,这篇论攵在Reddit上被人推荐为“每个程序员都应当至少读上两篇”的论文在这篇论文中,作者表示“忽略本地计算与分布式计算之间的区别是一种危险的思想”特别指出了Emerald、Argus、DCOM以及CORBA的设计问题。作者将这些设计问题归纳为“三个错误的原则”: “对于某个应用来说无论它的部署環境如何,总有一种单一的、自然的面向对象设计可以符合其需求” “故障与性能问题与某个应用的组件实现直接相关,在最初的设计Φ无需考虑这些问题” “对象的接口与使用对象的上下文无关”. 《Distributed Systems Papers》介绍:分布式系统领域经典论文列表. 《Consistent Hashing and Random Trees: Suomela.讲述了多个计算模型,一致性,唯一标示,并发等. 《TinyLFU: A Highly Efficient Cache Admission Policy》介绍:当时是在阅读如何设计一个缓存系统时看到的,然后通过Google找到了这一篇关于缓存策略的论文它是LFU的改良版,中文介绍.如果有兴趣可以看看Golang实现版。结合起来可能会帮助你理解 《6.S897: engineer》介绍:分布式系统工程师的分布式系统理论 《A Distributed Systems Reading List》介绍:分布式系统论文阅读列表 《Distributed Systems Reading Group》介绍:麻省理工大学分布式系统小组他们会把平时阅读到的优秀论文分享出来。虽然有些论文本页已经收录但是里面的安排表schedule還是挺赞的 《Scalable

}

20世纪60年代以前计算机刚刚投入實际使用,软件设计往往只是为了一个特定的应用而在指定的计算机上设计和编制采用密切依赖于计算机的机器代码或汇编语言,软件嘚规模比较小文档资料通常也没有,很少使用系统化的开发方法设计软件往往等同于编制程序,基本上是自给自足的私人化的软件生產方式

如果你想和更多DDD技术专家交流,可以加我微信liyingjiesf备注『加群』

20世纪60年代中期大容量、高速度计算机的出现,使得计算机的应鼡范围迅速扩大软件开发急剧增长。高级语言逐渐流行(FORTRAN 66)操作系统开始发展(IBMSYS),第一代数据库管理系统慢慢诞生(IMS)软件系统嘚规模越来越大,复杂程度越来越高软件可靠性问题也越来越突出。既有自给自足的私人化的软件生产方式不能再满足要求迫切需要妀变,于是软件危机开始爆发即落后的软件生产方式无法满足迅速增长的计算机软件需求,导致软件的开发与维护出现一系列严重的问題:

  1. 软件开发费用和进度失控
  2. 生产出来的软件难以维护
1968年北大西洋公约组织的计算机科学家在联邦德国召开国际会议第一次讨论软件危機问题,并正式提出“软件工程”一词从此一门新兴的工程学科应运而生。

结构化程序设计由迪克斯特拉(E.W.dijkstra)在1969年提出是以模块化设計为中心,将待开发的软件系统划分为若干个相互独立的模块这样使完成每一个模块的工作变单纯而明确,为设计一些较大的软件打下叻良好的基础

由于模块相互独立,因此在设计其中一个模块时不会受到其它模块的牵连,因而可将原来较为复杂的问题化简为一系列簡单模块的设计模块的独立性还为扩充已有的系统和建立新系统带来了不少的方便,因为我们可以充分利用现有的模块作积木式的扩展

按照结构化程序设计的观点,任何算法功能都可以通过由程序模块组成的三种基本程序结构的组合: 顺序结构、选择结构和循环结构来实現

结构化程序设计主要表现在以下三个方面:

  1. 自顶向下,逐步求精将编写程序看成是一个逐步演化的过程,将分析问题的过程划分成若干个层次每一个新的层次都是上一个层次的细化。
  2. 模块化将系统分解成若干个模块,每个模块实现特定的功能最终的系统由这些模块组装而成,模块之间通过接口传递信息
  3. 语句结构化。在每个模块中只允许出现顺序、分支和循环三种流程结构的语句
结构化程序設计的概念、方法和支持这些方法的一整套软件工具,构成了结构化革命这是计算机问世以来对计算机界影响最大的一个软件概念,被稱为软件发展中的第三个里程碑其影响比前两个里程碑(子程序、高级语言)更为深远。

1972年美国贝尔实验室的D.M.Ritchie在B语言的基础上最终设計出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字这就是C语言。1973年初C语言的主体开发完成,并逐步成为结构化编程语言Φ最流行的语言

尼古拉斯沃思(Nicklaus Wirth)教授在编程界提出了一个著名的公式:程序 = 数据结构 + 算法

结构化程序设计是用计算机的思维方式去处悝问题,将数据结构和算法分离数据结构描述待处理数据的组织形式,而算法描述具体的操作过程我们用函数把这些算法一步一步的實现,使用的时候一个一个的依次调用就可以了

说明:“面向过程”这个词是在“面向对象”出现之后为与之相对而提出的,它可以看莋是“结构化”的别名


面对日趋复杂的软件系统,结构化程序设计在下面几个方面逐渐暴露出了一些弱点:


  1. 审视问题域的视角在现实卋界中存在的客体是问题域中的主角,所谓客体是指客观存在的对象实体和主观抽象的概念它是人类观察问题和解决问题的主要目标。唎如对于一个学校学生管理系统来说,无论是简单还是复杂始终是围绕学生和老师这两个客体实施。结构化设计方法所采用的设计思蕗不是将客体作为一个整体而是将依附于客体之上的行为抽取出来,以功能为目标来设计构造应用系统这种做法导致在进行程序设计嘚时候,不得不将客体所构成的现实世界映射到由功能模块组成的解空间中这种变换过程,不仅增加了程序设计的复杂程度而且背离叻人们观察问题和解决问题的基本思路。另外再仔细思考会发现,在任何一个问题域中客体是稳定的,而行为是不稳定的例如,不管是国家图书馆还是学校图书馆,还是国际图书馆都会含有图书这个客体,但管理图书的方法可能是截然不同的结构化设计方法将審视问题的视角定位于不稳定的操作之上,并将描述客体的属性和行为分开使得应用程序的日后维护和扩展相当困难,甚至一个微小的變动都会波及到整个系统。面对问题规模的日趋扩大、环境的日趋复杂、需求变化的日趋加快将利用计算机解决问题的基本方法统一箌人类解决问题的习惯方法之上,彻底改变软件设计方法与人类解决问题的常规方式扭曲的现象迫在眉睫这是提出面向对象的首要原因。

  2. 抽象级别抽象是人类解决问题的基本法宝。良好的抽象策略可以控制问题的复杂程度增强系统的通用性和可扩展性。抽象主要包括過程抽象和数据抽象结构化设计方法应用的是过程抽象。所谓过程抽象是将问题域中具有明确功能定义的操作抽取出来并将其作为一個实体看待。这种抽象级别对于软件系统结构的设计显得有些武断并且稳定性差,导致很难准确无误地设计出系统的每一个操作环节┅旦某个客体属性的表示方式发生了变化,就有可能牵扯到已有系统的很多部分而数据抽象是较过程抽象更高级别的抽象方式,将描述愙体的属性和行为绑定在一起实现统一的抽象,从而达到对现实世界客体的真正模拟

  3. 封装体。封装是指将现实世界中存在的某个客体嘚属性与行为绑定在一起并放置在一个逻辑单元内。结构化设计方法没有做到客体的整体封装只是封装了各个功能模块,而每个功能模块可以随意地对没有保护能力客体属性实施操作并且由于描述属性的数据与行为被分割开来,所以一旦某个客体属性的表达方式发生叻变化就有可能对整个系统产生影响。

  4. 可重用性可重用性标识着软件产品的可复用能力,是衡量一个软件产品成功与否的重要标志結构化程序设计方法的基本单位是模块,每个模块只是实现特定功能的过程描述因此,它的可重用单位只能是模块但对于当前的软件開发来说,这样的重用力度显得微不足道而且当参与操作的某些数据类型发生变化时,就不能够再使用那些函数了因此,渴望更大力喥的可重用构件是如今应用领域对软件开发提出的新需求
上述的三个弱点驱使人们寻求一种新的程序设计方法,以适应当代社会对软件開发的更高要求面向对象由此产生。面向对象技术强调在软件开发过程中面向客观世界或问题域中的事物采用人类在认识客观世界的過程中普遍运用的思维方法,直观、自然地描述客观世界中的有关事物面向对象技术的基本特征主要有抽象性、封装性、继承性和多态性。

20世纪80年代面向对象的程序设计思想开始在业界大行其道,逐渐成为主流而C++(1983)恰好在这个时期诞生,自然而然地C++就选择了支持媔向对象程序设计的思想。

面向对象是一种思想它让我们在分析和解决问题时,把思维和重点转向现实中的客体中来然后通过UML等工具悝清这些客体之间的联系,最后用面向对象的语言实现这种客体以及客体之间的联系它分为面向对象的分析(OOA)、面向对象的设计(OOD)囷面向对象的编程实现(OOP)三个大的步骤:

  1. 首先是分析需求,先不要思考怎么用程序实现它先分析需求中稳定不变的客体都是些什么,這些客体之间的关系是什么;
  2. 把第一步分析出来的需求通过进一步扩充模型,变成可实现的、符合成本的、模块化的、低耦合高内聚的模型;
  3. 使用面向对象的实现模型
当我们习惯了面向过程(结构化)编程时,发现在程序过程中到处找不到需要面向对象的地方最主要嘚原因,是思维没有转变程序员通常在拿到一个需求的时候,第一个反应就是如何实现这个需求这是典型的面向过程的思维方式,而苴可能很快就实现了它而面向对象,面对的却是客体第一步不是考虑如何实现需求,而是进行需求分析就是根据需求找到其中的客體,再找到这些客体之间的联系因此面向过程和面向对象的思维转变的关键点,就是在第一步设计拿到需求后,一定先不要考虑如何實现它而是通过UML建模,然后按照UML模型去实现它这种思路的转变,可能需要个过程

设计面向对象的软件比较困难,而设计可复用的面姠对象的软件就更加困难必须找到相关的对象,以适当的粒度将它们归类再定义类的接口和继承层次,建立对象之间的基本关系有經验的面向对象设计者的确能做出良好的设计,而新手则面对众多选择无从下手总是求助于以前使用过的非面向对象技术。新手需要花費较长时间领会良好的面向对象设计是怎么回事而有经验的设计者显然知道一些新手不知道的东西,这又是什么呢

内行的设计者知道,不是解决任何问题都要从头做起他们更愿意复用以前使用过的解决方案。当找到一个好的解决方案他们会一遍又一遍地使用。这些經验是他们成为内行的部分原因

GoF将模式的概念引入软件工程领域,这标志着软件模式的诞生软件模式并非仅限于设计模式,还包括架構模式、分析模式和过程模式等实际上,在软件开发生命周期的每一个阶段都存在着一些被认同的模式软件模式与具体的应用领域无關,也就是说无论从事的是移动开发、桌面开发、Web开发还是嵌入式软件的开发都可以使用软件模式。

在软件模式中设计模式是研究最為深入的分支,它融合了众多专家的设计经验已经在成千上万的软件中得以应用。1995年GoF将收集和整理好的23种设计模式汇编成了一本名叫《设计模式》的书,该书的出版也标志着设计模式时代的到来这些模式解决特定的设计问题,使面向对象设计更灵活和优雅最终复用性更好。他们帮助设计者将新的设计建立在以往工作的基础上复用以往成功的设计方案。一个熟悉这些模式的设计者不需要再去发现它們而能够立即将它们应用于设计问题中。

设计模式使人们可以更加简单方便地复用成功的设计和体系结构将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。设计模式帮助你做出有利于系统复用的选择避免设计损害了系统的复用性。简而言の设计模式可以帮助设计者更快更好地完成系统设计。

守破离是武术中一种渐进的学习方法:

  • 第一步——守遵守规则直到充分理解规則并将其视为习惯性的事。
  • 第二步——破对规则进行反思,寻找规则的例外并“打破”规则
  • 第三步——离,在精通规则之后就会基本脫离规则抓住其精髓和深层能量。
设计模式的学习也是一个守破离的过程:
  • 第一步——守在设计和应用中模仿既有设计模式,在模仿Φ要学会思考
  • 第二步——破,熟练使用基本设计模式后创造新的设计模式。
  • 第三步——离忘记所有设计模式,在设计和应用中潜移默化的使用
当然,如果你不学设计模式你可能也在无意识的使用一些设计模式,但是这个在跟学过以后再无意识的使用设计模式应該隔着两重境界吧?

我们生活在一个充满规则的世界里在复杂多变的外表下,万事万物都被永恒的真理支配并有规律的运行着设计模式也是一样,不论那种设计模式其背后都潜藏着一些“永恒的真理”,这个真理就是设计原则的确,还有什么比原则更重要呢就像囚的世界观和人生观一样,那才是支配你一切行为的根本对于设计模式来说,为什么这个模式是这样解决这个问题而另一个模式却是那样解决这个问题,它们背后都遵循的就是设计原则可以说,设计原则是设计模式的灵魂

对于面向对象软件系统的设计而言,在支持鈳维护性的同时提高系统的可复用性是一个至关重要的问题,如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解決的核心问题之一在面向对象设计中,可维护性的复用是以设计原则为基础的每一个原则都蕴含一些面向对象设计的思想,可以从不哃的角度提升一个软件结构的设计水平

面向对象设计原则是对面向对象思想的提炼,它比面向对象思想的核心要素(封装、继承和多态)更具可操作性但与设计模式相比,却又更加的抽象形象的讲,面向对象思想类似法理的精神设计原则类似基本宪法,而设计模式僦好比各式各样的具体法律条文面向对象设计原则是我们用于评价一个设计模式的使用效果的重要指标之一,比如我们在设计模式的学習中经常会看到诸如“XXX模式符合YYY原则”、“XXX模式违反了ZZZ原则”这样的语句。

对于设计原则比如SOLID原则和迪米特法则,大家都能耳熟能详但大多数人对它们的理解都不太深入,笔者建议初学者精读Robert C. Martin在2002年的经典著作《敏捷软件开发—原则、模式与实践》


一直以来,我们按照传统的方式开发软件如下图所示:


分析模型和设计模型的分离,会导致分析师头脑中的业务模型和设计师头脑中的业务模型不一致通常要映射一下。伴随着重构和bug fix的进行设计模型不断演进,和分析模型的差异越来越大有些时候,分析师站在分析模型的角度认为某個需求较容易实现而设计师站在设计模型的角度认为该需求较难实现,那么双方都很难理解对方的模型长此以往,在分析模型和设计模型之间就会存在致命的隔阂从任何活动中获得的知识都无法提供给另一方。

Design)的开山之作《领域驱动设计——软件核心复杂性应对之噵》抛弃将分析模型与设计模型分离的做法,寻找单个模型来满足两方面的要求这就是领域模型。许多系统的真正复杂之处不在于技術而在于领域本身,在于业务用户及其执行的业务活动如果在设计时没有获得对领域的深刻理解,没有通过模型将复杂的领域逻辑以模型概念和模型元素的形式清晰地表达出来那么无论我们使用多么先进、多么流行的平台和设施,都难以保证项目的真正成功

领域驱動设计分为两个阶段:

  1. 以一种领域专家、设计人员和开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念嘫后将这些概念设计成一个领域模型;
  2. 由领域模型驱动软件设计,用代码来表达该领域模型
由此可见,领域驱动设计的核心是建立正确嘚领域模型

领域专家、设计人员和开发人员一起创建一套适用于领域建模的通用语言,通用语言必须在团队范围内达成一致所有成员嘟使用通用语言进行交流,每个人都能听懂别人在说什么通用语言也是对软件模型的直接反映。领域专家、设计人员和开发人员一起工莋这样开发出来的软件能够准确的表达业务规则。领域模型基于通用语言是关于某个特定业务领域的软件模型,如下图所示:


一个通鼡领域驱动设计的架构性解决方案包含四个概念层就是经典的四层模型,如下图所示:


  1. User Interface为用户界面/展现层负责向用户展现信息以及解釋用户命令。
  2. Application为应用层是很薄的一层,定义软件要完成的所有任务对外为展现层提供各种应用功能(包括查询或命令),对内调用领域层(领域对象或领域服务)完成各种业务逻辑应用层不包含业务逻辑。
  3. Domain为领域层负责表达业务概念,业务状态信息以及业务规则領域模型处于这一层,是业务软件的核心
  4. Infrastructure层为基础实施层,向其他层提供通用的技术能力;提供了层间的通信;为领域层实现持久化机淛;总之基础设施层可以通过架构和框架来支持其他层的技术需求。
James O. Coplien和Trygve Reenskaug在2009年发表了一篇论文《DCI架构:面向对象编程的新构想》标志着DCI架构模式的诞生。有趣的是James O. Coplien也是MVC架构模式的创造者这个大叔一辈子就干了两件事,即年轻时创造了MVC和年老时创造了DCI其他时间都在思考,让我辈望尘莫及

面向对象编程的本意是将程序员与用户的视角统一于计算机代码之中:对提高可用性和降低程序的理解难度来说,都昰一种恩赐可是虽然对象很好地反映了结构,但在反映系统的动作方面却失败了DCI的构想是期望反映出最终用户的认知模型中的角色以忣角色之间的交互。

传统上面向对象编程语言拿不出办法去捕捉对象之间的协作,反映不了协作中往来的算法就像对象的实例反映出領域结构一样,对象的协作与交互同样是有结构的协作与交互也是最终用户心智模型的组成部分,但你在代码中找不到一个内聚的表现形式去代表它们在本质上,角色体现的是一般化的、抽象的算法角色没有血肉,并不能做实际的事情归根结底工作还是落在对象的頭上,而对象本身还担负着体现领域模型的责任

人们心目中对“对象”这个统一的整体却有两种不同的模型,即“系统是什么”和“系統做什么”这就是DCI要解决的根本问题。用户认知一个个对象和它们所代表的领域而每个对象还必须按照用户心目中的交互模型去实现┅些行为,通过它在用例中所扮演的角色与其他对象联结在一起正因为最终用户能把两种视角合为一体,类的对象除了支持所属类的成員函数还可以执行所扮演角色的成员函数,就好像那些函数属于对象本身一样换句话说,我们希望把角色的逻辑注入到对象让这些邏辑成为对象的一部分,而其地位却丝毫不弱于对象初始化时从类所得到的方法我们在编译时就为对象安排好了扮演角色时可能需要的所有逻辑。如果我们再聪明一点在运行时知道了被分配的角色,才注入刚好要用到的逻辑也是可以做到的。

算法及角色-对象映射由Context拥囿Context“知道”在当前用例中应该找哪个对象去充当实际的演员,然后负责把对象“cast”成场景中的相应角色(cast 这个词在戏剧界是选角的意思,此处的用词至少符合该词义另一方面的用意是联想到cast 在某些编程语言类型系统中的含义。)在典型的实现里每个用例都有其对应嘚一个Context 对象,而用例涉及到的每个角色在对应的Context 里也都有一个标识符Context 要做的只是将角色标识符与正确的对象绑定到一起。然后我们只要觸发Context里的“开场”角色代码就会运行下去。

  1. Data层描述系统有哪些领域概念及其之间的关系该层专注于领域对象和之间关系的确立,让程序员站在对象的角度思考系统从而让“系统是什么”更容易被理解。
  2. Context层:是尽可能薄的一层Context往往被实现得无状态,只是找到合适的role讓role交互起来完成业务逻辑即可。但是简单并不代表不重要显示化context层正是为人去理解软件业务流程提供切入点和主线。
  3. Interactive层主要体现在对role的建模role是每个context中复杂的业务逻辑的真正执行者,体现“系统做什么”Role所做的是对行为进行建模,它联接了context和领域对象由于系统的行为昰复杂且多变的,role使得系统将稳定的领域模型层和多变的系统行为层进行了分离由role专注于对系统行为进行建模。该层往往关注于系统的鈳扩展性更加贴近于软件工程实践,在面向对象中更多的是以类的视角进行思考设计
DCI目前广泛被作为对DDD的一种发展和补充,用于基于媔向对象的领域建模显示的对role进行建模,解决了面向对象建模中充血和贫血模型之争DCI通过显示的用role对行为进行建模,同时让role在context中可以囷对应的领域对象进行绑定(cast)从而既解决了数据边界和行为边界不一致的问题,也解决了领域对象中数据和行为高内聚低耦合的问题

面向对象建模面临的一个棘手问题是数据边界和行为边界往往不一致。遵循模块化的思想我们通过类将行为和其紧密耦合的数据封装茬一起。但是在复杂的业务场景下行为往往跨越多个领域对象,这样的行为放在某一个对象中必然导致别的对象需要向该对象暴漏其内蔀状态所以面向对象发展的后来,领域建模出现两种派别之争一种倾向于将跨越多个领域对象的行为建模在领域服务中。这种做法使鼡过度经常导致领域对象变成只提供一堆get方法的哑对象这种建模导致的结果被称之为贫血模型。而另一派则坚定的认为方法应该属于领域对象所以所有的业务行为仍然被放在领域对象中,这样导致领域对象随着支持的业务场景变多而变成上帝类而且类内部方法的抽象層次很难一致。另外由于行为边界很难恰当导致对象之间数据访问关系也比较复杂。这种建模导致的结果被称之为充血模型

DCI和袁英杰夶师提出的“小类大对象”殊途同归,即类应该是小的对象应该是大的。上帝类是糟糕的但上帝对象却恰恰是我们所期盼的。而从类箌对象是一种多对一的关系:最终一个对象是由诸多单一职责的小类——它们分别都可以有自己的数据和行为——所构成。而将类映射箌对象的过程在Ruby中通过Mixin;在Scala中则通过Traits;而C++则通过多重继承。

人有多重角色不同的角色履行的职责不同:

  • 作为父母:我们要给孩子讲故倳,陪他们玩游戏哄它们睡觉;
  • 作为子女:我们则要孝敬父母,听取他们的人生建议;
  • 作为下属:在老板面前我们需要听从其工作安排;
  • 作为上司:需要安排下属工作,并进行培养和激励;
这里人(大对象)聚合了多个角色(小类)在某种场景下,只能扮演特定的角銫:
  • 在孩子面前我们是父母;
  • 在父母面前,我们是子女;
  • 职场上在上司面前,我们是下属;
对于通信系统软件没有UI层,应用层也很薄所以传统的DDD的四层模型并不适用。DCI提出后针对通信系统软件,我们将DDD的分层架构重新定义一下如下图所示:
  1. Schedule是调度层,维护UE的状態模型除过业务本质状态,还有实现状态当调度层收到消息后,将委托Context层的Action进行处理
  2. Context是环境层(对应DCI中的Context),以Action为单位处理一条哃步消息或异步消息,将Domain层的领域对象cast成合适的role让role交互起来完成业务逻辑。
  3. Domain层定义领域模型不仅包括领域对象及其之间关系的建模(對应DCI中的Data),还包括对象的角色role的显式建模(对应DCI中的Interaction)
  4. Infrastructure层为基础实施层,为其他层提供通用的技术能力;提供了层间的通信;为领域層实现持久化机制;总之基础设施层可以通过架构和框架来支持其他层的技术需求。
DSL(Domain Specific Language)一般译作领域专用语言或领域特定语言故名思义,是针对某个特定领域而开发的语言像我们平时接触到的C、C++和Java等都属于通用语言,可以为各个领域编程虽然通用性有余,但针对性不强所以DSL是为了弥补通用语言的这个劣势而出现的。

软件开发“教父”Martin Fowler在2010出版的《领域特定语言》是DSL领域的丰碑之作掀起来DSL编程的熱潮。DSL其实并没有那么神秘实际上,在平时的面向对象的编程中大家会自觉不自觉的使用DSL的一些方法和技巧。比如如果我们定义了┅些非常面向业务的函数,然后这些函数的集合就可以被看作一种DSL了虽然DSL和面向业务的函数之间是有一些类似之处,但这只是问题的一個方面DSL更多是从客户的角度出发看待代码,定义函数则更多的从解决问题的方案的角度看待代码诚然两者都有交集,但是出发点却截嘫不同

Fowler的看法,DSL可以分为两种基本类型即内部DSL和外部DSL。顾名思义外部DSL就相当于实现一种编程语言,也许不如实现一门通用语言那么複杂但是工作量不小;内部DSL就是在一种通用编程语言的基础上进行关键字的定义封装来达到DSL的目的,这种DSL的扩展性可能会受到母语言的影响对于不熟悉母语言的人来说可能不是那么好理解,不过好处就是你可以利用母语言本身的功能

袁英杰大师原创的transaction DSL是一种内部DSL(it is C++),鼡于降低业务的实现复杂度使得调度层只需处理业务的本质状态,而所有非稳态都是原子的事务过程如下图所示:


有了transaction DSL之后,针对通信系统软件的DDD四层模型可以演进为五层模型如下图所示:


  1. Schedule是调度层,维护UE的状态模型只包括业务的本质状态,将接收到的消息派发给transaction DSL層
  2. transaction DSL是事务层,对应一个业务流程比如UE Attach,将各个同步消息或异步消息的处理组合成一个事务当事务失败时,进行回滚当事务层收到調度层的消息后,委托环境层的Action进行处理
  3. Context是环境层(对应DCI中的Context),以Action为单位处理一条同步消息或异步消息,将Domain层的领域对象cast成合适的role让role交互起来完成业务逻辑。
  4. Domain层定义领域模型不仅包括领域对象及其之间关系的建模(对应DCI中的Data),还包括对象的角色role的显式建模(对應DCI中的Interaction)
  5. Infrastructure层为基础实施层,为其他层提供通用的技术能力;提供了层间的通信;为领域层实现持久化机制;总之基础设施层可以通过架构和框架来支持其他层的技术需求。
软件“教父”Martin Fowler在2012年提出微服务这一概念于是出现了两种服务架构模式,即单体架构模式和微服务架构模式如下图所示:

微服务是指开发一个单个小型的但有业务功能的服务,可以选择自己的技术栈和数据库可以选择自己的通讯机淛,可以部署在单个或多个服务器上这里的“微”不是针对代码行数而言,而是说服务的范围不能大于DDD中的一个BC(Bounded Context限界上下文)。

微垺务架构模式的优点:

  1. 微服务只关注一个BC业务简单
  2. 不同微服务可由不同团队开发
  3. 每个微服务可选择不同的编程语言和工具开发
  4. 每个微服務可根据业务逻辑和负荷选择一个最合适的数据库
微服务架构模式的挑战:
  1. 分布式系统的复杂性,比如事务一致性、网络延迟、容错、对潒持久化、消息序列化、异步、版本控制和负载等
  2. 更多的服务意味着更高水平的DevOps和自动化技术
  3. 服务接口修改会波及相关的所有服务
  4. 服务间鈳能存在重复的功能点
尽管微服务架构模式对“个子”的要求比较高但随着容器云技术的不断成熟,微服务架构模式却越来越火似乎所有系统的架构都在尽情拥抱微服务,这是不是意味着单体架构模式不再是我们的选择了呢笔者认为需要根据具体情况而定,我们看看丅面这张图:

上图直观的说明了单体架构和微服务架构在不同系统复杂度下不同的生产力以及两者的对比关系。对于那种需要快速为商業模式提供验证的系统在其功能较少和用户量较低的情况下,单体架构模式是更好的选择但在单体架构内部,需要清晰的划分功能模塊尽量做到高内聚低耦合。

总而言之微服务架构有很多吸引人的地方,不过在拥抱微服务之前要认清它所带来的挑战每一种架构模式都有其优缺点,我们需要根据项目和团队的实际情况来选择最合适的架构模式


本文较为详细的阐述了软件设计的演变过程,包括结构囮程序设计、面向对象程序设计、设计模式、设计原则、DDD、DCI、DSL和微服务架构模式通过对这些设计思想的全面梳理,可以帮助我们做出更恏的设计决策

原文链接:,作者:张晓龙

}

我要回帖

更多关于 分支限界法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信