精华内容
下载资源
问答
  • 复杂适应系统和swarm简介

    千次阅读 2004-09-16 21:20:00
    第一部分: 关于swarm.Swarm软件用来给复杂性过个体行为建模, 用于对经济行为的复杂性研究仿真. 他在美国新墨西哥州的 Santa fe 研究所得到开发的。Santa fe 研究所和一些个人及政府为Swarm的发展提供了资助,它的...

    第一部分: 关于swarm.

    Swarm软件用来给复杂性过个体行为建模, 用于对经济行为的复杂性研究仿真. 他美国新墨西哥州的 Santa fe 研究所得到开发的。Santa fe 研究所和一些个人及政府为Swarm的发展提供了资助,它的发行得到了GNU库的公认证和许可。文档和例程,以及软件和开发工具的 Alla 部件,作为可执行部件和源代码,可从网上免费自由得到。

    Swarm 是使用 Objective C语言开发的在早期的版本中编写Swarm的应用程序也使Objective CSwarm 2.0版开始提供了对Java语言的支持,将来可能支持JavaScriptC++pythonPerl等语言Swarm的最新版本 Swarm 2.1.1可以在不同版本的UnixLinuxWindows95Windows98WindowsNTWindows2000环境下运行

    社会经济系统的仿真,是建立在复杂适应系统(Complex Adaptive System 简称CAS)理论研究基础上的。通过“相对简单的微观个体活动可以突现出宏观层面的复杂行为”,给社会科学的研究与实践乘上当代新技术的航班打开了通路。

    第二部分: 关于复杂性研究.

    什么叫简单系统,什么叫复杂系统?一个完全无序、处于热平衡状态的系统无疑是简单的系统,比如说一个很完美的晶体,一个金刚钻也是一个很简单的系统。一般讲,描述简单系统需要的信息量是少的,描述复杂系统状态的信息量多。所以,复杂系统的状态,一般讲是处在完全有序和完全无序的中间,并不是在两头。

    -- 周光召(以下转载来自周光召的观点)

    在探讨复杂系统的结构和演化的时候,有几个基本规律起基本的作用。它们的内涵不仅有大量实验事实的验证,而且成为我们研究复杂系统的基本出发点,我们把它叫做原理或者论。有三个比较重要的,一个是守恒原理,一个是开放论,一个是进化论

      守恒定理说的是事物都在不断发展变化,不管怎么发展变化,总有一些量是不变的。像物理系统里的能量、电荷,化学系统里有多少碳元素,经济系统里的资金、货物,这些都是从一个手转到另外一个手,但是量不会凭空多出来或者少了,这些量不会无中生有,也不会无端消失。在整个运动变化期间,总和是收支平衡的,这种量就是守恒量,会随时随地满足守恒的方程。

      在能量过程中,能量守恒,有一种能量叫做热能,和所有的能量不一样,它是物质利用分子和原子做无规则运动的能量。有序就是要有规则,无序就是没有规则。所以热能在一定程度上是一种无序的能量。温度高的热能比温度低的热能,序还是高一点。无规则运动的能量不是很容易转化成规则运动的能量。热力学第二定律,说的是由于存在摩擦、电阻等等,叫耗散因素,和外界没有物质和能量交换的封闭系统。有序的运动,最后就会通过摩擦、电阻等等耗散,转变成无序的能量运动。热量只能从高温流向低温,最后趋势热平衡,而不能相反。或者封闭系统内的过程都是不可逆过程。如果想要将热量从低温提到高温,就要有电冰箱,要消耗电。

      热力学第二定律,是宏观物理学的基本定律。我们生活的世界上,由大量原子核分子组成的物理、化学、生物的以及更高层次的社会的物质结构都要遵守,对封闭系统运动的无序度就会不断增大。而且封闭系统进行的过程是不可逆的。其中有序状态会逐渐消失,转为无序的热平衡状态。人封闭起来,不吃不喝,这个人很快就死了,然后就腐烂了,和外边的环境变成一样的,变成无序的热平衡状态。

      有序的结合或有序的运动,不能在封闭系统里产生的,这是热力学第二定律重要的结论,也是我们为什么要开放的一个重要原因。

      封闭使系统状态走向无序,但是自然界中不断从无序状态中生成有序组织的物质,像晶体、生物、社会组织等等。它们并不违反热力学第二定律,因为他们不是从处于热平衡的封闭系统中产生的,而是从远离热平衡中的开放系统产生的,这就是开放论最重要的出发点。

      一个开放的系统,不断和外边交换物质、能量和信息,像资金、人才、知识、装备、货物等等,就显得生机勃勃。从清代开始的闭关锁国,造成了中国的长期落后,而改革开放,促进了中国的迅速发展,充分证明了这个真理。

      这个系统常常受到一些偶然因素的影响,就会偏离平衡的状态。如果作用力的总和使得系统偏离了以后,原来的两个作用力就不平衡了。结果使它恢复平衡状态,这种系统就会叫做稳定的状态。否则就要处于一个不稳定的状态。比如我们把一个球放在一个碗里,一定停在碗底,如果拉起来一点就滚几下,还要停在碗底,碗底是一个稳定的平衡状态。如果要把它放一个球在这儿,再把一个小球放在这个球的顶上,放得好可以待一会儿,稍微碰一下就会滚下去了,这种就是不平衡的状态,作用力稍微偏离一点,状态就偏离了。在不稳定状态的系统,在外界偶然的干扰下,就会偏离原有的轨道,而且发生大的甚至是灾害性的变化。

     

    第三部分: 有序向无序转化,走向混沌

    从牛顿力学的观点来看,相互作用力和状态的初始条件或者边界条件完全给定以后,系统的运动轨迹就完全给定了。原来我们讨论地球的运动,今天地球怎么运动,就知道一年以后它怎么运动。钟摆以每秒为周期的摆动,这也是一个周期运动。在一般的情况下,周期运动的运动轨迹是按照力学运动的规律完全决定的,地球轨道也是一个周期运动,一年一个周期。

      在这种观点的影响下,人们曾经认为,一切现象都是按必然的规律产生的。以后的研究发现,在一定条件下,必然性就会转化为偶然性。即使牛顿力学这种确定论的力学,也会产生一种混沌的现象。

      在非线性相互作用力的周期运动的情况就不一样了。外部的边界参数或者初始参数改变的时候,改变到一个程度,就会突然出现周期加倍的分差的现象,绕着它,转一圈就回到原来的地方,原来是绕两圈,周期加速了一倍。如果再改变,周期还会再加倍,原来要转两圈,现在转四圈才会到原来的地方。到了某个极限,运动突然变成混沌。混沌在相图上可以绕一个有限的区域,每一天都能够跑到,不是只是在一个圈上。这种周期加倍的现象,在日常生活中也会有。假如在农村待过,去种果树,就会发现如果营养给得好,果树每年结的果子都很好。如果某些条件给差了,就要出现大年、小年,一年结大果,再一年甚至不结果,第三年再结果,周期就分杈了。再把这个条件改变,也许要四年才能结一次果,这都是周期分杈的现象。

      周期运动通过周期加倍而出现混沌,是一个很普遍的现象。像果树、人口,很多方面,包括心脏的跳动,心脏是有周期的,如果哪一天你发现心脏第一个周期和第二个周期不一样大,一个跳的强一点,一个跳的弱一点,这就麻烦了,产生二联律,经过两个周期才恢复到原来的样子,再发展期间就变成三联律。

      1985年的时候物理学家做的实验,看到参数在变化的时候,在不断分叉,到最后形成混沌。在混沌的状态底下,只要比较两条初始条件处于细微差别,处于混沌的运动轨迹,开始的时候彼此靠近,随着时间的推移,距离越来越大,但是整个轨道都在一个有限的空间里。比如说有一个双胞胎,生下来的时候是完全一样的,基因都一样,但是他们也许上学的时候,有一个人突然得了感冒,结果考试没考好,有一个进了名牌大学,一个进了普通大学,以后两个人,尽管给他们的条件基本一样,一个偶然的事件就使以后变得越来越不一样。

      蝴蝶效应,影响运动的条件,一旦处于导致混沌的区域,运动对外界的干扰就非常敏感,偶然性就会起到重要作用。其实混沌现象,最早是大气科学家发现的。因为大气运动应该服从牛顿的运动学规律。但是大气的相互作用,和大气、海洋、生物的运动都是非线性的。

      因此在某些条件下,大气运动就会出现混沌现象。在这种时候,他们就发现,在上海有个蝴蝶……,一个礼拜以后在北京就下暴雨,叫做蝴蝶效应。现在大家有时对气象预报的同志有点埋怨,有时说天晴,怎么突然下雨,这是正常现象,近期的预言可以,但是长期预言很困难,这叫蝴蝶效应。

      人口的例子,有一个很简单的方程,XN+1的人口,首先是正比于DN代的人口,人口也不能无限制的增长,由于地球有限,食物有限,有一个限制,成了一个1-XN,1是象征的,也许是一百亿,把它规范化了。实际上所有的人口方程大体上多是这样的。最后人口就趋于一个稳定的状态,到3.3的时候,人口就会一会儿多,一会儿少。到了再大的时候,人忽然多,忽然少,对人来讲,现在还没有观察到后边的现象,因为人口生殖率还没有那么高。不过对昆虫的已经观察到了,专门做实验了。

      由于有可能出现混沌,要保持系统的稳定,不要陷入混沌状态,复杂系统状态的及时反馈、调控和自适应机制是不可缺少的。一般生命系统都有这种机制,如果没有这种机制就麻烦了。比如感染细菌,细菌有自我繁殖,而且有某种正反馈的现象,越来越多,几代以后,细菌多的不得了。如果自己没有杀死细菌的调控机制,根本就活不下去。任何一个系统要保持稳定,必须要有及时反馈、调控和自适应的系统。生物是这样的,一个社会组织也是一样的。

     

    第四部分: 怎样从无序中形成有序的结构

     在远离热平衡的开放系统中,通过和外界不断交换物质,吸收有序的能量和信息,排除经耗散而变得没有用的能量和信息,逐步发展确定结构和运动行为的有序状态,并且进一步由简单的结构向复杂结构进化。这种结构在科学上称之为耗散结构,生物系统也可以认为是一种耗散结构。一旦新陈代谢停止了、封闭了,不去交换物质能量和信息,生命活动就结束了。

      其中某一种模式的涨落,如果能通过非线性作用反馈加以放大,就逐渐会形成其主导模式的统治模式,会抑制其它模式的作用,迫使内部的子系统臣服,按照统治模式的格式进行相似的自我复制,并按照统一步调行动,形成具有特定时间和空间结构的整体。比如所有的政府机构一旦形成以后,开始由于某种革命或者某种选举,是一种涨落的行为形成以后,就成了一个统治的模式,就会从省政府,县政府,上面有什么机构下面就会有什么机构,基本按照这种模式复制过来,某种程度相似的结构,特别是你不自觉的话,肯定是上面一个什么机构,下面一个什么机构,很多机关也是这样的。

      很多系统的有序结构,都发生在系统的临界状态附近。什么叫临界状态?比如水结冰的时候,零度的时候就是临界状态,由液体变成固体。100度的时候,由水变成了气,那也是临界状态。有一种状态由另外一种状态转变的时候,临界的那个地方相互作用,就变成长程的,影响很远。现在信息的作用总是长程的,因为信息传播的越来越快,在世界上任何一个地方发生一件事情,美国“9.11”事件一发生,一会儿全世界就都知道了。所以,信息的作用非常大,才能用反恐把全世界都臣服在它底下,使得别人都无法反抗,作用是长期的。内部子系统之间常常相关,使得产生的有序态自相似形,特别是自然的系统,社会系统比较复杂,将系统的任意局部加以放大,结构和原来的系统是相同的。用简单的规则就可以产生复杂的空间结构叫做分形。最简单的是雪花,在刚好零度附近产生的,而且雪花不管是在东北是在华南,只要到了那个温度,就会突然自动形成,而且形成出来漂亮结构的,有序的状态。

     

    第五部分: 复杂适应系统

      有很多复杂系统,在特定的外部条件底下,可以通过自组织形成特定时空结构的有序状态,在环境的影响下能够自组织、自学习、自适应,不断演化形态而生存、繁衍和发展。如果适应能力赶不上环境的变化,就会衰亡下去。我们称这种复杂系统是复杂适应系统,生命毫无疑意是一种复杂的适应系统。

      复杂适应系统有以下特征:

      第一、由子系统构成,但它的结构、运动模式和性质具有整体的特点。不是子系统简单叠加之和,甚至部分子系统的变化,对整体特点都不产生大的影响。包括一个人有部分的地方损坏了,也不会影响这个人作为一个整体而存在。

      第二、处于远离热平衡的开放系统。

      第三、内部子系统相互之间是分线性的。

      第四、在一定环境条件范围内,具有自组织、自学习、自适应和进化的功能,自动形成有序的状态,适应环境的变迁而演化繁殖,内部结构的衰老和外部环境的恶化,也会造成解体。

      第五、历史的偶然因素,会对演化过程产生重要的影响。假如一个胎儿在母亲怀孕的时候,突然受到外力,或者母亲吃了什么药,对胎儿就要产生致残或者很严重的后果。

      《复杂》一书里有句名言,要在混沌的边缘上,才会有新的思想或者新的结构产生。

      混沌状态或者复杂适应系统的有序状态,只有在必须的条件具备的时候才能发生。常常反映这些条件的参数也非常敏感,少许的改变可能突然改变它的状态。如果对产生的条件有正确的认识,就会给调控这些状态提供可能性。

      心脏跳动本来是有序的状态,但是如果出现二联律,心率变动,到混沌区去了。过去是用高电压猛击一下,再拉回来,把这个参数变回来,现在就知道了只要对敏感区,用一个几十伏的电压击下去就会恢复过来。参数很敏感,问题是能不能找到区域,有很大的危险。

      进化论的问题。按照达尔文学说,地球上现在生存的物种都是由共同的祖先长期进化而来的产物,而进化是基因变异、遗传繁殖和自然选择三种因素组合作用的历史过程,但其中自然选择是进化的主要因素。即使同一种族的个体之间,由于多种原因基因也不完全相同。

      个体的形状和体能会有差异。在相同环境下,有的个体在相互竞争中体能强,有的也会采取更好的策略,伪装或者共生,适应当时的环境,这些个体就能够繁殖更多的后代,它们的体能和智力就会遗传,并且繁殖下去,在种群中取得优势。

      什么叫有益?没有绝对标准,是对当时的环境而言的。一旦环境改变,原来适应的可能不再适应,数量就会减少,原来不适应的可能更为有益,数量增加,生物的种群发布就会重新发生变化。现在到底是进化还是不是进化很难说,生物界有的人提倡把这个叫做演化,总之对当时是有益的。

      在生物进化学说被广泛接受以后,进化的概念向两个方向扩展。一个是把生物进化的一般结论应用于人类,另一方面将其推广到无机自然界,将生物进化印象导致人类起源和社会进步的观念,人类学已经基本上科学地阐明了从猿到人的进化轮廓,社会学也大体论述了从原始社会到共产主义社会的社会进步图式。开放系统是进化的必要条件,非平衡态是有序之源。进化学说还在不断发展中,在科学界还有不同的声音。

      复杂适应系统的举例,生物进化。地球上天天都有各种各样具有耗散结构的复杂系统产生、发展和消亡。在发展过程中,不断适应环境的变化,不断积累信息,使得自身的复杂程度越来越高,以自学习和自组织的方式自发地形成由简单到复杂,由低级到高级组织形式的演化过程,这种过程是典范的地球上生物的进化过程和这一过程对地球环境和气侯变迁产生的影响。

      一个例子是讲恐龙绝灭。在地球生存史上,曾经周期性的出现过冰期,遭受过空间小行星的撞击,有过大量的地震、火山爆发、洪水泛滥等自然灾害,有些灾害如此严重以至于当时的生物品种大部分都遭到绝灭。5亿4千万年出现过五次大的生物绝灭的灾害,最厉害的是一次发生在2亿1千万年以前,当时火山爆发、地震,生物在短短的时间内都死掉了。

      恐龙是在2亿1千万年灾害过后以后才大量发展的。地球的气侯回到非常温暖的时期,为恐龙的繁殖创造良好的环境。哺乳动物的祖先竞争不过恐龙,当时的哺乳动物没有发展大型的、智能较高的动物,只有一些小型的生活在地下的哺乳动物,比如鼠类在当时得以生存下来。从一个更远的意义上讲,人类跟老鼠也有共同的祖先。

      恐龙统治了很长时间,到后期,大概1亿2千6百万年,地球气侯发生了变化,几百万年里温度在下降,很多热带生物相继绝种,陆地变得干燥,内陆形成酷暑和寒冬,植物生长不好,恐龙数量开始减少。恐龙生长环境恶化的时候,大约是6千5百万年前,就发生了外来小行星的碰撞,这次碰撞造成了尘埃、温度下降、全球黑暗,使得恐龙灭绝,陆上物种减少了88%,海上的物种减少了50%。这次灾害终止了恐龙的统治,爬行动物的统治,这样使得当时藏在地下的老鼠,靠吃腐烂生物受的影响小,所以存活下来,在这儿之后得到了比较大的发展机会。今天生物界的基因都在恶劣环境下,经过千锤百炼得以生存下来,同时历史的偶然性作为机遇起了重要的作用,如果没有这些因素,今天人类有没有还不太清楚。一个复杂适应系统的进化,可能由于强大外力的干预而停止。小行星碰撞作为环境的恶化,促使恐龙绝灭。

      自然生态系统是在进化过程中不断发展的复杂适应系统,在生态系统物流和能流的每一个环节,每个生态位上都生存着许多物种,在保证生态环境中物流和能流守恒的条件下,充分利用系统的各种资源进行繁衍。

      生态系统中,可能通过基因变异或者物种迁移,产生新的物种,与原有的物种竞争生存的资源和空间。现在我们国家对外来引进物种特别注意,现在外来引进的已经造成了很严重的我们国家的生态问题,原来以为是好的一些东西,从外国引进来,结果大量的繁殖,无法控制。

      距今400到500万年前,在非洲南部已经出现了直立行走的南方古猿。可能在700到80万年前,由于非洲东部地区持续干旱,森林破坏,非洲猴开始沿三路进行演化,第一支抱住树木不放,后来成了大猩猩。第二支开始向森林边沿转移,不脱离森林,在草原上寻找食物,演化成黑猩猩。第三支是弱者,没办法跟其他两支竞争,只好走出森林,寻求新的出路,被迫用双足走路,开发出杂食的习惯,不要爬树了,同时因为环境很严酷,懂得相互合作、分享食物,最后实现向人类祖先古猿的转变。现在有些条件很好的人很危险,不一定最后发展的很好,有些弱势的将来就有可能发展起来。

      最近的研究表明,今天的人类和他们血缘最近的祖先黑猩猩的基因密码排列秩序,只有1.23%的差别。由基因突变和自然选择在几百万年中形成的一小点差别,就形成了我们和远祖之间的鸿沟。为生存竞争所迫的猴子,离开果实累累的森林,到平原上寻求发展,无疑在开始阶段经历了艰苦的考验,艰难的时势造就了万物之灵的人类。

      人类在发展进化过程中,不断以其独有的智慧和勤劳,认识世界,改造世界,在文化和知识开始发展后的短短一万年内,人类把整个地球变得面目全非。现在有些人老是觉得环境不好,做科学研究,一定要到最好的学校,最多的钱支持,我一直认为,拿钱少的在艰苦环境奋斗的科学家,有些人成为大家了。

      和自然生态系统一样,高技术和产业也是一个不断进化的复杂适应系统。在开放条件下,通过复制就是技术扩散,变异就是技术和产品的创新,通过竞争或者共生,像参股的共生,经过市场的选择和适应,在价值链的每个环节就会形成新的相关的产业,包括为产业服务的金融、运输、电信、保险、销售、维修等等服务业,他们共同形成了既分工又协同的产业生态系统,通过自学习、自组织、自适应不断实现进化。产业聚群是产业生态系统的一种表现形式,电子产业已经形成了工业系统,最适宜相关产业的发展。

      有一个有名的经济学家说了一段话,技术创新和竞争性市场空间的相互作用,是资本主义工业过程中的基本驱动力,技术创新就是基因的变异,竞争和适应是复杂适应系统基本的要点。在竞争市场上,一个正常、健康的经济并不处于平衡的状态,而是经常被技术革新所破坏。企业家在观察市场经济的时候,总是注意资本主义如何管理现存的结构,更聪明的办法是去了解这些结构是如何被创造出来,并且如何摧毁它们。在经济的系统中也是在不断发展,不断变化,不断创新,不断调整的结构。

      高技术和高新技术产业发展的规律,从复杂系统的概念出发,首先是国家目标,特别是国防的需求,是高技术及其产业的催生婆,在发展的初期有不可替代的作用。它们的出生还是要靠外力,但是高技术产业及其产业的发展壮大,却是一个复杂适应系统,通过自组织、自学习、自适应不断演化壮大的过程。

      高技术的创新,就是基因的变异,决定于技术人员活跃的思想和高超的技术水平。有一个新思想带来的技术革新,可能创造一个新的高新技术企业。技术的复制、创新、变异不断进行。新公司和新产品每天都在出现,市场竞争激烈反应迅速,性能、质量合速度成为市场选择的关键,这些都促使高新技术产业加快演化。不同的高新技术产业之间,能产生正反馈的作用,微电子芯片的进步提高电脑的功能和速度,扩大电脑的市场和应用面。反过来,电脑的发展增加了芯片的需求量,采用计算机辅助设计加快了芯片的研究和开发工作的进度。这种高技术之间的正反馈作用,带动了高新技术产业高速扩张。

      在价值链上,不同高新技术产业联盟,快速推动高新技术产业的发展,因特尔和微软,这种兼容大大加速了微电子芯片和电脑的发展。垄断在一个短的时期,能给垄断企业带来高额利润,但是会使整个系统的进化停滞了,对整个社会是不力的,因此在发达国家都制定了反垄断法,我们国家也很快有反垄断法。高技术替代方案很快产生,高技术企业不能靠垄断技术而获得持续发展,依靠垄断技术最后都遭到失败。苹果公司当年是最有名的电脑公司,不愿意把电脑设计公开,使得其它厂商不能生产兼容的产品,尽管它的技术很优异,早占领市场,最后还是败给了IBM的PC。这些都说明高新技术企业在开放的条件下,才能迅速发展。高技术企业依靠杰出的人才,是企业管理的中心环节。但是在开放的条件下,必然形成人员的流动和随着人员流动带来的技术转移,当某个环节出现了技术革新思想,就像在生态系统出现新的生态位一样,会有技术人员脱离,去创办相关的产业,占领新的生态位,用原有的企业形成新的,常常是效率更高的分工,在整个高新技术产业里协同发展。

      人员流动有个人的原因,但更多的是企业管理模式存在问题,或者不支持创新,或者决策错误,市场前景不好,或者待遇过低,和市场价值偏离。过分频繁的人才流动,不利于一个高新技术企业的发展,人才竞争会迫使企业更加注重企业文化的塑造,知识产权的保护和对有创造力职工的激励。从整个社会来看,适度规范的人员流动能加快技术的转移,能够繁殖。加快淘汰落后的技术和企业,创造更健康的竞争环境和新的就业途径,提高市场运行的效率,从社会、政府的角度,不应该行政的阻止这些人员的流动,应该加以适当的规范,在一定条件下,要给予必要的支持。

      作为生产力的高技术快速发展要求,生产关系迅速调整,高技术企业的技术构成、产业结构、管理模式、运行机制和市场战略,都要随着技术的变迁,而不断革新。不停顿的创新和变革,是高技术企业发展的常规。凡是跟不上的企业不是被兼并,就是经历大的起伏和波折,能获得持续发展的高新技术企业只是其中的少数。

      在相同的外界条件下,系统发展的速度和动力是由系统的开放程度和内因起决定作用的。内因中人才群体的整体素质,招募和使用人才的政策起主要作用。而领导层的素质,反映在对发展目标和市场战略的选择,对资源的发掘和集中使用,对人才的识别、培训、激励和量才使用,对研发和质量的重视,对市场开拓的策划,提高为顾客服务的效率,对工作的协调和组织能力等方面,又在起关键的作用。

      高技术企业要形成一个良好的生态系统,竞争力和持续的创新力是高技术企业赖以生存的基础。知识、人才、资金、信息和市场是支持高技术企业,提高其竞争力的主要因素。要形成良好的高技术生态系统,其周围必须有提供知识和人才的大学和科研机构,有风险资金的投入,有良好的信息基础设施,有市场的强大需求,还要有为市场服务的完整体系。核心是要提高竞争力和创新力,要有人才、知识、市场和基础设施,在社会上要具备好的条件。

      中国科学的繁荣,必须让科技界形成复杂的适应系统,在急剧的变动环境下,通过自组织、自学习、自适应不断向高级阶段进化。

      首先要有开放的环境,要有知识创新,相当于基因突变,还要传播,相当于繁殖。传播不仅是知识传播,将来还要吸引更多的人才,也是我们的一种繁殖。要加强学术交流,竞争和协作,同时要有好的应用和评价系统,就是怎么进行学术选择和市场选择。每一个环节,政策都要正确,措施都要得当。如果政策正确措施得当,这些条件都具备了,就能够形成复杂适应系统,就能够自组织、自学习、自适应,不断发展,不断进化,那时的科学繁荣就会指日可待。而现在我们老是拔苗助长、急于求成,不是创造好这些政策和环境的条件,让他自身在这个条件里很好的成长,这里确实存在很多问题。比如开放的环境,一直到现在,中国各个机构之中,学校、研究所之间的交流比国外还是要差。我们的知识创新,基因突变不够,我们的传播,尤其是各个学科之间的交叉和传播现在不够。对科学人才的吸引,现在有的学科也比较危险,学生不学了。当然,学术交流、争论,特别是学术争论现在很不发达,没有形成真正竞争的公平的环境。我们的选择,单纯凭一种指标选择,比如说SCI的论证也是不够的。这些措施都需要研究,怎样能够形成一个自我发展的,当然要在社会的支持下,因为是开放系统,总要跟外界有物质能量、信息的交流,如果自己发展起来了,有更多的成果输送出去,就会有更多的资源进来,就能够形成良性循环不断发展,如果这些条件不具备,就是再急于求成,再拔苗助长,恐怕只能作出更多的弄虚作假、浮夸这些情况出来。

      当人类社会的进化由基因突变转向智能创新,自然界物种由天择转向人择,当人类活动造成的非线性相互作用,引起在气侯、生态、经济、政治等领域,可能发生危机和灾变,导向混沌的历史时刻,人类对其历史和后代,对宇宙万物的生息担负了空前的责任。

      自私和愚昧,掠夺和霸权是进化过程遗留给人类的兽性。人要超越生物就必须战胜自私和愚昧,必须反对掠夺和霸权。当人类战胜自身的弱点,在公平竞争积极进取的同时始终和大自然及其同类和谐共处、协同进化,人类就会进入到持续发展的新阶段,就会有光辉灿烂的前景。

     

    补充: 非线形系统

    什么叫非线性?就是作用和作用的效果,日常生活中非线性很多,去买一件衣服是这么多钱,买十件衣服一定给你打折扣,八折,就表示他不是按照比例来增长的。这就是一种非线性的作用。当然,日常生活中可以找出很多都是非线性作用的。有了非线性作用力的话,就会出现一些新的情况,就是某些反映系统性质的参量,就会呈指数上涨,可能会越来越多,比如散布一个谣言,一个传两个,两个传四个,最后就会指数上升,越传越多。

      非线性相互作用,会产生一种正反馈,原来是多少,再反馈回来变得更大。比如喇叭正反馈,声音发出去再反馈回来,回到我这儿使它更放大,这个喇叭就要尖叫,这就是正反馈。这样就会造成系统不稳定,喇叭一尖叫,大家就不能工作了。在某些条件下,由于正反馈,就会使系统的长期行为作用的参数和系统的初始状态或者编辑条件非常敏感。就像成语所说的差之毫厘,失之千里。在另外的条件下,又可能在混乱中产生秩序,突发形成一些有序状态。

      非线性相互作用,还会引起运动过程中的突变,比如冲击波、雪崩、地震、股市崩溃等等,突然发生的,都是因为非线性作用有一个正反馈的效应,一个很小的影响,慢慢越来越大,大到一个程度突然爆发了。

    展开全文
  • 架构设计 例子和实践 系统设计说明书(架构、概要、详细)目录结构演进架构中的领域驱动设计Web架构设计经验分享软件架构设计从MVC框架看MVC架构的设计领域驱动设计(Domain Driven Design)参考架构详解关于垂直切分...

    架构设计 例子和实践 系统设计说明书(架构、概要、详细)目录结构演进架构中的领域驱动设计Web架构设计经验分享软件架构设计从MVC框架看MVC架构的设计领域驱动设计(Domain Driven Design)参考架构详解关于垂直切分Vertical Sharding的粒度企业应用集成与开源ESB产品ServiceMix和Mule介绍论基于数据访问的集合类(Data Access Based Collection)和领域事件(Domain Event)模式关于系统异常设计的再思考前车之覆,后车之鉴——开源项目经验谈软件的架构与设计模式之什么是架构OO系统设计师之路–设计模型系列(1)–软件架构和软件框架

    系统设计说明书(架构、概要、详细)目录结构

    虽然这些文档一般来说公司都是有模板的,但我写这些文档以来基本上是每写一次就把目录结构给改一次,应该说这是因为自己对这些文档的理解开始加深,慢慢的越来越明白这些文档的作用和其中需要阐述的东西,觉得这三份文档主要阐述了一个系统的设计和实现过程,从系统分解为层次、层次内的模块以及相互的接口、模块分解为对象以及对象的接口、实现这些对象接口的方法。这次又整了一份,^_^,欢迎大家指正。

    XXX架构设计说明书

    (架构设计重点在于将系统分层并产生层次内的模块、阐明模块之间的关系)

    一.  概述

    描述本文的参考依据、资料以及大概内容。

    二.  目的

    描述本文编写的目的。

    三.  架构设计

    阐明进行架构设计的总体原则,如对问题域的分析方法。

    3.1.       架构分析

    对场景以及问题域进行分析,构成系统的架构级设计,阐明对于系统的分层思想。

    3.2.       设计思想

    阐明进行架构设计的思想,可参考一些架构设计的模式,需结合当前系统的实际情况而定。

    3.3.       架构体系

    根据架构分析和设计思想产生系统的架构图,并对架构图进行描述,说明分层的原因、层次的职责,并根据架构图绘制系统的物理部署图,描述系统的部署体系。

    3.4.       模块划分

    根据架构图进行模块的划分并阐明模块划分的理由,绘制模块物理图以及模块依赖图。

    3.4.1.       模块描述

    根据模块物理图描述各模块的职责,并声明其对其他模块的接口要求。。

    3.4.2.       模块接口设计

    对模块接口进行设计,并提供一定的伪代码。

    XXX概要设计说明书

    (概要设计重点在于将模块分解为对象并阐明对象之间的关系)

    一.  概述

    描述本文的参考依据、资料以及大概内容。

    二.  目的

    描述本文的编写目的。

    三.  模块概要设计

    引用架构设计说明书中的模块图,并阐述对于模块进行设计的大致思路。

    3.1.       设计思想

    阐明概要设计的思想,概要设计的思想通常是涉及设计模式的。

    3.2.       模块A

    3.2.1.       概要设计

    根据该模块的职责对模块进行概要设计(分解模块为对象、描述对象的职责以及声明对象之间的接口),绘制模块的对象图、对象间的依赖图以及模块主要功能的序列图,分别加以描述并相应的描述模块异常的处理方法。

    3.2.2.       模块接口实现

    阐明对于架构设计中定义的模块接口的实现的设计。

    XXX详细设计说明书

    (详细设计重点在于对模块进行实现,将模块的对象分解为属性和方法,并阐述如何实现)

    一.  概述

    阐述本文的参考依据、资料以及大概内容。

    二.  目的

    阐述本文的编写目的。

    三.  模块详细设计

    3.1.       设计思想

    阐述对模块进行详细设计的思想。

    3.2.       模块A

    3.2.1.       详细设计

    根据模块概要设计详细描述对于模块内对象的实现,包括对象的职责、属性、方法、对象内功能的流程图、对象关联的类、对象的异常。(需要绘制的主要为类图)

    在大型的项目中是有必要分开的…. 
    架构解决系统核心用例以及关键性需求的设计,形成抽象的基础结构,划分模块、形成模块接口. 
    概要解决模块以及模块接口的实现,形成模块中核心对象以及对象的接口定义..

    详细解决模块中具体对象的实现以及对象接口的实现

    演进架构中的领域驱动设计

    原文链接:http://www.infoq.com/cn/articles/ddd-evolving-architecture

    作者Mat Wall and Nik Silver译者王丽娟发布于2009年9月21日
    上午11时9分

    社区
    Architecture,
    Java
    主题
    设计,
    面向对象设计,
    建模
    标签
    Hibernate,
    领域驱动设计

    领域驱动设计能非常容易地应用于稳定领域,其中的关键活动适合开发人员对用户脑海中的内容进行记录和建模。但在领域本身不断变化和发展的情况下,领域驱动设计变得更具有挑战性。这在敏捷项目中很普遍,在业务本身试图演进的时候也会发生。本文分析了在反思、重建guardian.co.uk这一为期两年的计划背景下我们是如何利用DDD的。我们展示了如何确保在软件架构中反映最终用户演变的认知,以及怎样实现该架构来保证以后的变化。我们提供了模型中重要项目过程、具体演进步骤的细节。

    顶层标题:

    1. 计划背景
    2. 从DDD开始
    3. 增量计划中的DDD过程
    4. 进化的领域模型
    5. 代码级别的演进
    6. 演进架构中DDD的一些教训
    7. 附录:具体示例

    1. 计划背景

    Guardian.co.uk有相当长的新闻、评论、特性历史记录,目前已拥有超过1800万的独立用户和每月1.8亿的页面访问量。在此期间的大部分时间,网站都运行在原始的Java技术之上,但在2006年2月开始了一项重要的工作计划——将网站移植到一个更现代的平台上去,计划的最初阶段于2006年11月推出,当时推出了具有新外观的旅游网站,接着在2007年5月推出新的主页,之后相继推出了更多内容。尽管在2006年2月仅有少数几个人在做这项工作,但后来团队最多曾达到了104人。

    然而,计划的动机远不止是要一个新外观。多年的经验告诉我们有更好的办法来组织我们的内容,有更好的方式将我们的内容商业化,以及在此背后,还有更先进的开发方法——这才是关键之所在。

    其实,我们考虑工作的方式已超越了我们软件可以处理的内容。这就是为什么DDD对我们来说如此有价值。

    遗留软件中阻碍我们的概念不匹配有两个方面,我们先简单看一下这两方面问题,首先是我们的内部使用者,其次是我们的开发人员。这些问题都需要借助DDD予以解决。

    1.1. 内部使用者的问题

    新闻业是一个古老的行业,有既定的培训、资格和职制,但对新闻方面训练有素的新编辑来说,加入我们的行列并使用Web工具有效地工作是不可能的,尤其在刚来的几个月里。要成为一个高效的使用者,了解我们CMS和网站的关键概念还远远不够,还需要了解它们是如何实现的。

    比如说,将缓存内容的概念(这应该完全是系统内部的技术优化)暴露给编辑人员;编辑们要将内容放置在缓存中以确保内容已准备好,还需要理解缓存工作流以用CMS工具诊断和解决问题。这显然是对编辑人员不合理的要求。

    1.2. 开发人员的问题

    概念上的不匹配也体现在技术方面。举例来说,CMS有一个概念是“制品”,这完全是所有开发人员每天工作的核心。以前团队中的一个人坦言,在足足九个月之后他才认识到这些“制品”其实就是网页。围绕“制品”形成的含义模糊的语言和软件越来越多,这些东西让他工作的真正性质变得晦涩难懂。

    再举一个例子,生成我们内容的RSS订阅特别耗时。尽管各个版块的主页都包含一个清晰的列表,里面有主要内容和附加内容,但底层软件并不能对两者予以区分。因此,从页面抽取RSS订阅的逻辑是混乱的,比如“在页面上获取每个条目,如果它的布局宽大约一半儿、长度比平均长度长一些,那它可能是主要内容,这样我们就能抽取链接、将其作为一个订阅”。

    很显然,对我们来说,人们对他们工作(开始、网页和RSS订阅)及其如何实现(缓存工作流、“制品”、混乱逻辑)的认识之间的分歧给我们的效益造成了明显而惨重的影响。

    2. 从DDD开始

    本部分阐述了我们使用DDD的场景:为什么选择它,它在系统架构中所处的位置,还有最初的领域模型。在后面的章节中,我们会看一下如何把最初的领域知识传播给扩充的团队,如何演进模型,以及如何以此为中心来演进我们的编码技术。

    2.1. 选择DDD

    DDD所倡导的首要方面就是统一一致的语言,以及在代码中直接体现用户自己的概念。这能有效地解决前面提及的概念上的不匹配问题。单独看来,这是一个有价值的见解,但其本身价值或许并不比“正确使用面向对象技术”多很多。

    使其深入的是DDD引入的技术语言和概念:实体、值对象、服务、资源库等。这确保了在处理非常大的项目时,我们的大型开发团队有可能一致地进行开发——长远来看,这对维护质量是必不可少的。甚至在废弃我们更底层的代码时(我们稍后会进行演示),统一的技术语言能让我们恢复到过去、改进代码质量。

    2.2. 在系统中嵌入领域模型

    本节显示了DDD在整个系统架构中的地位。

    我们的系统逐渐建立了三个主要的组件:渲染应用的用户界面网站;面向编辑、用于创建和管理内容的应用程序;跟系统交互数据的供稿系统。这些应用都是基于Spring和Hibernate构建的Java Web应用,并使用Velocity作为我们的模板语言。

    我们可以看下这些应用的布局:

    Hibernate层提供数据访问,使用EHCache作为Hibernate的二级缓存。模型层包含领域对象和资源库,服务则处于其上一层。在此之上,我们有Velocity模板层,它提供页面渲染逻辑。最顶层则包含控制器,是应用的入口点。

    看一下这个应用的分层架构,仅仅将模型当做是应用的一个自包含的层是很有意思的。这个想法大致正确,但模型层和其它层之间还是有一些细微的差别:由于我们使用领域驱动设计,所以我们需要统一语言,不仅要在我们谈论领域时使用,还要在应用的任何地方使用。模型层的存在不仅是为了从渲染逻辑中分离业务逻辑,还要为使用的其它层提供词汇表。

    另外,模型层可作为代码的独立单元进行构建,而且可以作为JAR包导入到依赖于它的许多应用中。其它任何层则不是这样。对构建和发布应用来说,这意味着:在我们基础设施的模型层改变代码一定是跨所有应用的全局变化。我们可以在前端的网站中改变Velocity模板,只用部署前端应用就可以,管理系统或供稿系统则不用。如果我们在领域模型中改变了一个对象的逻辑,我们必须更新所有依赖于模型的应用,因为我们只有(而且期望只有)一个领域视图。

    这有一种危害,就是领域建模的这种方法可能会导致单一模型,如果业务领域非常庞大,改变起来的代价会非常昂贵。我们认识到了这一点,因此随着领域不断增长,我们必须确保该层没有变得太过笨重。目前,虽然领域层也是相当庞大和复杂的,但是这还没有带来什么问题。在敏捷环境中工作,我们希望无论如何每两周都要推出所有系统的最新变化。但我们持续关注着该层代码改变的成本。如果成本上升到不能接受的程度,我们可能会考虑将单一模型细分成多个更小的模型,并在每个子模型之间给出适配层。但是我们在项目开始时没有这样做,我们更偏向于单一模型的简单性,而不是用多个模型时必须解决的更为复杂的依赖管理问题。

    2.3. 早期的领域建模

    在项目初期,大家在键盘上动手开始编写代码之前,我们就决定让开发人员、QA、BA、业务人员在同一个房间里一起工作,以便项目能够持续。在这个阶段我们有一个由业务人员和技术人员组成的小型团队,而且我们只要求有一个稳妥的初次发布。这确保了我们的模型和过程都相当简单。

    我们的首要目标是让编辑(我们业务代表的关键组成部分)就项目最初迭代的期望有一个清楚的认识。我们跟编辑们坐在一起,就像一个整体团队一样,用英语与他们交流想法,允许各个功能的代表对这些想法提出质疑和澄清,直到他们认为我们正确理解了编辑需要的内容。

    我们的编辑认为,项目初期优先级最高的功能是系统能生成网页,这些网页能显示文章和文章分类系统。

    他们最初的需求可归纳为:

    • 我们应该能将一篇文章和任何给定的URL关联起来。
    • 我们要能改变选定的不同模板渲染结果页面的方式。
    • 为了管理,我们要将内容纳入宽泛的版面,也就是新闻、体育、旅游。
    • 系统必须能显示一个页面,该页面包含指向特定分类中所有文章的链接。

    我们的编辑需要一种非常灵活的方式来对文章进行分类。他们采用了基于关键字的方法。每个关键字定义了一个与内容相关的主题。每篇文章可以和很多关键字关联,因为一篇文章可以有很多主题。

    我们网站有很多编辑,每个人负责不同版块的内容。每个版块都要求有自己导航和特有关键字的所有权。

    从编辑使用的语言来看,我们似乎在领域中引入了一些关键实体:

    • 页面 URL的拥有者。负责选择模板来渲染内容。
    • 模板 页面布局,任何时候都有可能改变。技术人员将每个模板实现为磁盘上的一个Velocity文件。
    • 版块 页面更宽泛的分类。每个版块有一个编辑,还有对其中页面共同的感官。新闻、旅游和商业都是版块的例子。
    • 关键字 描述存在于版块中主题的方式。关键字过去用于文章分类,现在则驱动自动导航。这样它们将与某个页面关联,关于给定主题所有文章的自动页面也能生成。
    • 文章 我们能发布给用户的一段文本内容。

    提取这些信息后,我们开始对领域建模。项目早期做出的一个决定:编辑拥有领域模型并负责设计,技术团队则提供协助。对过去不习惯这种技术设计的编辑来说,这是相当大的转变。我们发现,通过召开由编辑、开发人员、技术架构师组成的研习会,我们能用简单、技术含量较低的方法勾画出领域模型,并对它持续演进。讨论模型的范围,使用钢笔、档案卡和Blu-Tak绘制备选解决方案。每个候选模型都会进行讨论,技术团队把设计中的每个细节含义告诉给编辑。

    尽管过程在最初相当缓慢,但很有趣。编辑发现这非常容易上手;他们能信手拈来、提出对象,然后及时从开发人员那里获得反馈,以知道生成的模型是否满足了他们的需求。对于编辑们能在过程中迅速掌握技术的要领,技术人员都感到很惊喜,而且所有人都对生成的系统是否能满足客户需求很有信心。

    观察领域语言的演变也很有趣。有时文章对象会被说成是“故事”。显然对于同一实体的多个名称,我们并没有一种统一语言,这是一个问题。是我们的编辑发现他们描述事物时没有使用统一的语言,也是他们决心称该对象为文章。后来,任何时间有人说“故事”,就会有人说:“你的意思不是文章吗?”在设计统一语言时,持续、公共的改进过程是种很强大的力量。

    我们的编辑最初设计生成的模型是这样的:

    [网页及其版块之间的关系由应用于文章的关键字导出,文章是网页中的核心内容。网页的版块由应用于文章的首个关键字的版块确定。]

    由于并非所有的团队成员都参与了该过程的所有阶段,所以我们需要向他们介绍工作进展,并将这些全部展现在了墙上。然后开发人员开始了敏捷开发之旅,而且由于编辑和开发人员、BA、QA都在一起工作,任何有关模型及其意图的问题都能在开发过程的任何时候获得第一手的可靠信息。

    经过几次迭代之后系统初具形态,我们还建立工具来创建和管理关键字、文章和页面。随着这些内容的创建,编辑们很快掌握了它们,并且给出了一些修改建议。大家普遍认为这一简单的关键模型能正常运行,而且可以继续下去、形成网站初次发布的基础。

    3. 增量计划中的DDD过程

    首次发布之后,我们的项目团队伴随着技术人员和业务代表们的成长,一起取得了进步,打算演进领域模型。很显然,我们需要一种有组织的方式来为领域模型引入新的内容、进行系统的演进。

    3.1. 新员工入门

    DDD是入门过程中的核心部分。非技术人员在整个项目生命周期内都会加入项目,因为工作计划是横跨各个编辑领域的,反过来,在恰当的时机我们也会引入版面编辑。技术人员很容易就能加入项目,因为我们持续不断地雇用新员工。

    我们的入门过程包括针对这两类人的DDD讲习,尽管细节不同,但高层次的议题涵盖两个相同的部分:DDD是什么,它为什么重要;领域模型本身的特定范围。

    描述DDD时我们强调的最重要的内容有:

    • 领域模型归业务代表所有。这就要从业务代表的头脑里抽象概念,并将这些概念嵌入到软件中,而不能从软件的角度思考,并试图影响业务代表。
    • 技术团队是关键的利益相关者。我们将围绕具体细节据理力争。

    覆盖领域模型的特定范围本身就很重要,因为它予以就任者处理项目中特定问题的真正工具。我们的领域模型中有几十个对象,所以我们只关注于高级别和更为明显的少数几个,在我们的情况中就是本文所讨论的各种内容和关键字概念。在这里我们做了三件事:

    • 我们在白板上画出了概念及其关系,因此我们能给出系统如何工作的一个有形的表示。
    • 我们确保每位编辑当场解释大量的领域模型,以强调领域模型不属于技术团队所有这一事实。
    • 我们解释一些为了达到这一点而做出的历史变迁,所以就任者可以理解(a)这不是一成不变的,而是多变的,(b)为了进一步开发模型,他们可以在即将进行的对话中扮演什么样的角色。

    3.2. 规划中的DDD

    入门是必不可少的,不过在开始计划每次迭代的时候,知识才真正得以实践。

    3.2.1 使用统一语言

    DDD强制使用的统一语言使得业务人员、技术人员和设计师能围坐在一起规划并确定具体任务的优先次序。这意味着有很多会议与业务人员有关,他们更接近技术人员,也更加了解技术过程。有一位同事,她先担任项目的编辑助理,然后成长为关键的决策者;她解释说,在迭代启动会议上她亲自去看技术人员怎样判断和(激烈地)评估任务,开始更多地意识到功能和努力之间的平衡。如果她不和技术团队共用一种语言,她就不会一直出席会议,也不会收获那些认识。

    在规划阶段利用DDD时我们使用的两个重要原则是:

    1. 领域模型归属于业务;
    2. 领域模型需要一个权威的业务源。

    领域模型的业务所有权在入门中就进行了解释,但在这里才发挥作用。这意味着技术团队的关键角色是聆听并理解,而不是解释什么可能、什么不可能。需求抽象要求将概念性的领域模型映射到具体的功能需求上,并在存在不匹配的地方对业务代表提出异议或进行询问。接着,存在不匹配的地方要么改变领域模型,要么在更高层次上解决功能需求(“你想用此功能达成什么效果?”)。

    对领域模型来说,权威的业务源是我们组织的性质所明确需要的。我们正在构建一个独立的软件平台,它需要满足很多编辑团队的需求,编辑团队不一定以同样的方式来看世界。Guardian不实行许多公司实行的“命令和控制”结构;编辑台则有很多自由,也能以他们认为合适的方式去开发自己的网站版面,并设定预期的读者。因此,不同的编辑对领域模型会有略微不同的理解和观点,这有可能会破坏单一的统一语言。我们的解决办法是确定并加入业务代表,他们在整个编辑台都有责任。对我们来说,这是生产团队,是那些处理日常构建版面、指定布局等技术细节的人。他们是文字编辑依赖的超级用户,作为专家工具建议,因此技术团队认为他们是领域模型的持有者,而且他们保证软件中大部分的一致性。他们当然不是唯一的业务代表,但他们是与技术人员保持一致的人员。

    3.2.2 与DDD一起计划的问题

    不幸的是,我们发现了在计划过程中应用DDD特有的挑战,尤其是在持续计划的敏捷环境中。这些问题是:

    1. 本质上讲,我们正在将软件写入新的、不确定商业模式中;
    2. 绑定到一个旧模型;
    3. 业务人员“入乡随俗”。

    我们反过来讨论下这些问题……

    EricEvans撰写关于创建领域模型的文章时,观点是业务代表的脑海中存在着一个模型,该模型需要提取出来;即便他们的模型不明确,他们也明白核心概念,而且这些概念基本上能解释给技术人员。然而在我们的情况中,我们正在改变我们的模型——事实上是在改变我们的业务——但并不知道我们目标的确切细节。(马上我们就会看到这一点的具体例子。)某些想法显而易见,也很早就建立起来了(比如我们会有文章和关键字),但很多并不是这样(引入页面的想法还有一些阻力;关键字如何关联到其它内容则完全是各有各的想法)。我们的教科书并没有提供解决这些问题的指南。不过,敏捷开发原则则可以:

    • 构建最简单的东西。尽管我们无法在早期解决所有的细节,但通常能对构建下一个有用的功能有足够的理解。
    • 频繁发布。通过发布此功能,我们能看到功能如何实际地运转。进一步的调整和进化步骤因此变得最为明显(不可避免,它们往往不是我们所预期的)。
    • 降低变化的成本。利用这些不可避免的调整和进化步骤,减少变化的成本很有必要。对我们来说这包括自动化构建过程和自动化测试等。
    • 经常重构。经过几个演进步骤,我们会看到技术债务累积,这需要予以解决。

    与此相关的是第二个问题:与旧模型有太多的精神联系。比如说,我们的遗留系统要求编辑和制作人员单独安排页面布局,而新系统的愿景则是基于关键字自动生成页面。在新系统里,Guantánamo Bay页面无需任何人工干预,许多内容会给出GuantánamoBay关键字,仅简单地凭借这一事实就能显示出来。但结果却是,这只是由技术团队持有的过度机械化的愿景,技术团队希望减少体力劳动和所有页面的持续管理。相比之下,编辑人员高度重视人的洞察力,他们带入过程的不仅有记述新闻,还有展现新闻;对他们来说,为了突出最重要的故事(而不仅仅是最新的),为了用不同的方法和灵敏性(比如9·11和Web
    2.0报导)区别对待不同的主题,个人的布局是很有必要的。

    对这类问题没有放之四海而皆准的解决办法,但我们发现了两个成功的关键:专注于业务问题,而不是技术问题;铭记“创造性冲突”这句话。在这里的例子里,见解有分歧,但双方表达了他们在商业上的动机后,我们就开始在同一个环境里面工作了。该解决方案是创造性的,源于对每个人动机的理解,也因此解决了大家了疑虑。在这种情况下,我们构建了大量的模板,每个都有不同的感觉和影响等,编辑可以从中选择并切换。此外,每个模板的关键区域允许手动选择显示的故事、页面的其余部分自动生成内容(小心不要重复内容),对于该手动区域,如果管理变得繁重,就可以随时关闭,从而使网页完全自动化。

    我们发现的第三个挑战是随着业务人员“入乡随俗”,也就是说他们已深深融入技术且牵涉到了要点,以至于他们会忘记对新使用系统的内部用户来说,系统该是什么样。当业务代表发现跟他们的同事很难沟通事情如何运转,或者很难指出价值有限的功能时,就有危险的信号了。KentBeck在《解析极限编程》第一版中说,现场客户与技术团队直接交互绝不会占用他们很多的时间,通过强调这一点,就可以保证在现场的客户。但我们在与有几十个开发人员、多名BA、多名QA的团队一起工作时,我们发现即使有三个全职的业务代表,有时也是不够的。由于业务人员花费了太多的时间与技术人员在一起,以至他们与同事失去联系成为真正的问题。这些都是人力解决方案带来的人力问题。解决方案是要提供个人备份和支持,让新的业务人员轮流加入团队(可能从助理开始着手进行,逐步成长为关键决策角色),允许代表有时间回归他们自己的核心工作,比如一天、一周等。事实上,这还有一个附加的好处,就是能让更多的业务代表接触到软件开发,还可以传播技巧和经验。

    4. 进化的领域模型

    在本章中,我们看看模型在方案的后期是如何演进的。

    4.1. 演进第一步:超越文章

    首次发布后不久,编辑要求系统能处理更多的内容类型,而非只有文章一类。尽管这对我们来说毫不稀奇,但在我们构建模型的第一个版本时,我们还是明确决定对此不予考虑太多。

    这是个关键点:我们关注整个团队能很好地理解小规模、可管理块中的模型和建模过程,而不是试图预先对整个系统进行架构设计。随着理解的深入或变化,稍后再改变模型并不是个错误。这种做法符合YAGNI编码原则(你不会需要它),因为该做法防止开发人员引入额外的复杂度,因而也能阻止Bug的引入。它还能让整个团队安排时间去对系统中很小的一块达成共识。我们认为,今天产出一个可工作的无Bug系统要比明天产出一个完美的、包括所有模型的系统更为重要。

    我们的编辑在下一个迭代中要求的内容类型有音频和视频。我们的技术团队和编辑再次坐在一起讨论了领域建模过程。编辑先跟技术团队谈道,音频和视频很显然与文章相似:应该可以将视频或音频放在一个页面上。每个页面只允许有一种内容。视频和音频可以通过关键字分类。关键字可以属于版面。编辑还指明,在以后的迭代中他们会添加更多类型的内容,他们认为现在该是时候去理解我们应该如何随着时间的推移去演进内容模型。

    对我们的开发人员来说,很显然编辑想在语言中明确引入两个新条目:音频和视频。音频、视频和文章有一些共同点:它们都是内容类型,这一点也很明确。我们的编辑并不熟悉继承的概念,所以技术团队可以给编辑讲解继承,以便技术团队能正确表述编辑所看到的模型。

    这里有一个明显的经验:通过利用敏捷开发技术将软件开发过程细分为小的块,我们还能使业务人员的学习曲线变得平滑。久而久之他们能加深对领域建模过程的理解,而不用预先花费大量的时间去学习面向对象设计所有的组件。

    这是我们的编辑根据添加的新内容类型设计的模型。

    这个单一的模型演变是大量更细微的通用语言演进的结果。现在我们有三个外加的词:音频、视频和内容;我们的编辑已经了解了继承,并能在以后的模型迭代中加以利用;对添加新的内容类型,我们也有了以后的扩展策略,并使其对我们的编辑来说是简单的。如果编辑需要一个新的内容类型,而这一新的内容类型与我们已有的内容类型相同、在页面和关键字之间有大致相同的关系,那编辑就能要求开发团队产出一个新的内容类型。作为一个团队,我们正通过逐步生成模型来提高效率,因为我们的编辑不会再详细检查漫长的领域建模过程去添加新的内容类型。

    4.2. 演进第二步:

    由于我们的模型要扩展到包括更多的内容类型,它需要更灵活地去分类。我们开始在领域模型中添加额外的元数据,但编辑的最终意图是什么还不是非常清楚。然而这并不让我们太过担忧,因为我们对元数据进行建模的方法与处理内容的方法一样,将需求细分为可管理的块,将每个添加到我们的领域中。

    我们的编辑想添加的第一个元数据类型是系列这一概念。系列是一组相关的内容,内容则有一个基于时间的隐含顺序。在报纸中有很多系列的例子,也需要将这一概念解释为适用于Web的说法。

    我们对此的初步想法非常简单。我们将系列添加为一个领域对象,它要关联到内容和页面。这个对象将用来聚集与系列关联的内容。如果读者访问了一种内容,该内容属于某个系列,我们就能从页面链接到同一系列中的前一条和后一条内容。我们还能链接到并生成系列索引页面,该页面可以显示系列中的所有内容。

    这里是编辑所设计的系列模型:

    与此同时,我们的编辑正在考虑更多的元数据,他们想让这些元数据与内容关联。目前关键字描述了内容是关于什么的。编辑还要求系统能根据内容的基调对内容进行不同的处理。不同基调的例子有评论、讣告、读者供稿、来信。通过引入基调,我们就可以将其显示给读者,让他们找到类似的内容(其它讣告、评论等)。这像是除关键字或系列外另一种类型的关系。跟系列一样,基调可以附加到一条内容上,也能和页面有关系。

    这里是编辑针对基调设计的模型:

    完成开发后,我们有了一个能根据关键字、系列或基调对内容进行分类的系统。但编辑对达到这一点所需的技术工作量还有一些关注点。他们在我们下次演进模型时向技术团队提出了这些关注点,并能提出解决方案。

    4.3. 演进第三步:重构元数据

    模型的下一步演进是我们的编辑想接着添加类似于系列和基调的内容。我们的编辑想添加带有贡献者的内容这一概念。贡献者是创建内容的人,可能是文章的作者,或者是视频的制作人。跟系列一样,贡献者在系统中有一个页面,该页面会自动聚集贡献者制作的所有内容。

    编辑还看到了另一个问题。他们认为随着系列和基调的引入,他们已经向开发人员指明了大量非常相似的细节。他们要求构建一个工具去创建系列,构建另一个工具去创建基调。他们不得不指明这些对象如何关联到内容和页面上。每次他们都发现,他们在为这两种类型的领域对象指定非常相似的开发任务;这很浪费时间,还是重复的。编辑更加关注于贡献者,还有更多的元数据类型会加入进来。这看起来又要让编辑再次指明、处理大量昂贵的开发工作,所有这些都非常相似。

    这显然成为一个问题。我们的编辑似乎已经发现了模型的一些错误,而开发人员还没有。为什么添加新的元数据对象会如此昂贵呢?为什么他们不得不一遍又一遍地去指定相同的工作呢?我们的编辑问了一个问题,该问题是“这仅仅是‘软件开发如何工作’,还是模型有问题?”技术团队认为编辑熟悉一些事情,因为很显然,他们理解模型的方式与编辑不同。我们与编辑一起召开了另一个领域建模会议,试图找出问题所在。

    在会议上我们的编辑建议,所有已有的元数据类型实际上源于相同的基本思想。所有的元数据对象(关键字、系列、基调和贡献者)可以和内容有多对多的关系,而且它们都需要它们自己的页面。(在先前的模型版本中,我们不得不知道对象和页面之间的关系)。我们重构了模型,引入了一个新的超类——Tag(标签),并作为其它元数据的超类。编辑们很喜欢使用“超类”这一技术术语,将整个重构称为“Super-Tag”,尽管最终也回到了现实。

    由于标签的引入,添加贡献者和其它预期的新元数据类型变得很简单,因为我们能够利用已有的工具功能和框架。

    我们修订后的模型现在看起来是这样的:

    我们的业务代表在以这种方式考虑开发过程和领域模型,发现这一点非常好,还发现领域驱动设计有能力促进在两个方向都起作用的共同理解:我们发现技术团队对我们正努力解决的业务问题有良好且持续的理解,而且出乎意料,业务代表能“洞察”开发过程,还能改变这一过程以更好地满足他们的需求。编辑们现在不仅能将他们的需求翻译为领域模型,还能设计、检查领域模型的重构,以确保重构能与我们目前对业务问题的理解保持同步。

    编辑规划领域模型重构并成功执行它们的能力是我们领域驱动设计guardian.co.uk成功的一个关键点。

    5. 代码级别的演进

    前面我们看了领域模型方面的进化。但DDD在代码级别也有影响,不断变化的业务需求也意味着代码要有变化。现在我们来看看这些变化。

    5.1. 构建模型

    在构建领域模型时,要确认的第一件事就是领域中出现的聚集。聚集可认为是相关对象的集合,这些对象彼此相互引用。这些对象不应该直接引用其它聚集中的其它对象;不同聚集之间的引用应该由根聚集来完成。

    看一下我们在上面定义的模型示例,我们开始看到对象成形。我们有Page和Template对象,它们结合起来能给Web页面提供URL和观感。由于Page是系统的入口点,所以在这里Page就是根聚集。

    我们还有一个聚集Content,它也是根聚集。我们看到Content有Article、Video、Audio等子类型,我们认为这些都是内容的子聚集,核心的Content对象则是根聚集。

    我们还看到形成了另一个聚集。它是元数据对象的集合:Tag、Series、Tone等。这些对象组成了标签聚集,Tag是根聚集。

    Java编程语言提供了理想的方式来对这些聚集进行建模。我们可以使用Java包来对每个聚集进行建模,使用标准的POJO对每个领域对象进行建模。那些不是根聚集、且只在聚集中使用的领域对象可以有包范围内使用的构造函数,以防它们在聚集外被构造。

    上述模型的包结构如下所示(“r2”是我们应用套件的名称):

     com.gu.r2.model.page 
    
     com.gu.r2.model.tag 
    
     com.gu.r2.model.content 
    
     com.gu.r2.model.content.article
    
     com.gu.r2.model.content.video
    
     com.gu.r2.model.content.audio 

    我们将内容聚集细分为多个子包,因为内容对象往往有很多聚集特定的支持类(这里的简化图中没有显示)。所有以标签为基础的对象往往要更为简单,所以我们将它们放在了一个包里,而没有引入额外的复杂性。

    不过不久之后,我们认识到上述包结构会给我们带来问题,我们打算修改它。看看我们前端应用的包结构示例,了解一下我们如何组织控制器,就能阐述清楚这一问题:

     com.gu.r2.frontend.controller.page
    
     com.gu.r2.frontend.controller.articl

    这里看到我们的代码集要开始细分为片段。我们提取了所有的聚集,将其放入包中,但我们没有单独的包去包含与聚集相关的所有对象。这意味着,如果以后领域变得太大而不能作为一个单独的单元来管理,我们希望将应用分解,处理依赖就会有困难。目前这还没有真正带来什么问题,但我们要重构应用,以便不会有太多的跨包依赖。经过改进的结构如下:

     com.gu.r2.page.model   (domain objects in the page aggregate)
    
     com.gu.r2.page.controller (controllers providing access to aggregate)
    
     com.gu.r2.content.article.model
    
     com.gu.r2.content.article.controller
    
     ...
    
     etc

    除了约定,我们在代码集中没有其它任何的领域驱动设计实施原则。创建注解或标记接口来标记聚集根是有可能的,实际上是争取在模型包锁定开发,减少开发人员建模时出错的几率。但实际上并不是用这些机械的强制来保证在整个代码集中都遵循标准约定,而是我们更多地依赖了人力技术,比如结对编程和测试驱动开发。如果我们确实发现已创建的一些内容违反了我们的设计原则(这相当少见),那我们会告诉开发人员并让他完善设计。我们还是喜欢这个轻量级的方法,因为它很少在代码集中引入混乱,反而提升了代码的简单性和可读性。这也意味着我们的开发人员更好地理解了为什么一些内容是按这种方式组织,而不是被迫去简单地做这些事情。

    5.2. 核心DDD概念的演进

    根据领域驱动设计原则创建的应用会具有四种明显的对象类型:实体、值对象、资源库和服务。在本节中,我们将看看应用中的这些例子。

    5.2.1 实体

    实体是那些存在于聚集中并具有标识的对象。并不是所有的实体都是聚集根,但只有实体才能成为聚集根。

    开发人员,尤其是那些使用关系型数据库的开发人员,都很熟悉实体的概念。不过,我们发现这个看似很好理解的概念却有可能引起一些误解。

    这一误解似乎跟使用Hibernate持久化实体有点儿关系。由于我们使用Hibernate,我们一般将实体建模为简单的POJO。每个实体具有属性,这些属性可以利用setter和getter方法进行存取。每个属性都映射到一个XML文件中,定义该属性如何持久化到数据库中。为了创建一个新的持久化实体,开发人员需要创建用于存储的数据库表,创建适当的Hibernate映射文件,还要创建有相关属性的领域对象。由于开发人员要花费一些时间处理持久化机制,他们有时似乎认为实体对象的目的仅仅只是数据的持久化,而不是业务逻辑的执行。等他们后来开始实现业务逻辑时,他们往往在服务对象中实现,而不是在实体对象本身中。

    在下面(简化)的代码片段中可以看出此类错误。我们用一个简单的实体对象来表示一场足球赛:

     public class FootballMatch extends IdBasedDomainObject
    
     { 
    
         private final FootballTeam homeTeam;
    
         private final FootballTeam awayTeam;
    
         private int homeTeamGoalsScored;
    
         private int awayTeamGoalsScored;
    
     
    
         FootballMatch(FootballTeam homeTeam, FootballTeam awayTeam) { 
    
             this.homeTeam = homeTeam; 
    
             this.awayTeam = awayTeam; 
    
         } 
    
     
    
         public FootballTeam getHomeTeam() { 
    
             return homeTeam; 
    
         } 
    
     
    
         public FootballTeam getAwayTeam() { 
    
             return awayTeam; 
    
         } 
    
         public int getHomeTeamScore() { 
    
             return homeTeamScore; 
    
         } 
    
     
    
         public void setHomeTeamScore(int score) { 
    
             this.homeTeamScore = score; 
    
         } 
    
     
    
         public void setAwayTeamScore(int score) { 
    
             this.awayTeamScore = score; 
    
         } 
    
     }

    该实体对象使用FootballTeam实体去对球队进行建模,看起来很像使用Hibernate的开发人员所熟悉的对象类型。该实体的每个属性都持久化到数据库中,尽管从领域驱动设计的角度来说这个细节并不真的重要,我们的开发人员还是将持久化的属性提升到一个高于它们应该在的水平上去。在我们试图从FootballTeam对象计算出谁赢得了比赛的时候这一点就可以显露出来。我们的开发人员要做的事情就是造出另一种所谓的领域对象,就像下面所示:

     public class FootballMatchSummary { 
    
    
    
         public FootballTeam getWinningTeam(FootballMatch footballMatch) { 
    
             if(footballMatch.getHomeTeamScore() >  footballMatch.getAwayTeamScore()) { 
    
                 return footballMatch.getHomeTeam(); 
    
             } 
    
             return footballMatch.getAwayTeam(); 
    
         } 
    
     }

    片刻的思考应该表明已经出现了错误。我们已经创建了一个FootballMatchSummary类,该类存在于领域模型中,但对业务来说它并不意味着什么。它看起来是充当了FootballMatch对象的服务对象,提供了实际上应该存在于FootballMatch领域对象中的功能。引起这一误解的原因好像是开发人员将FootballMatch实体对象简单地看成了是反映数据库中持久化信息,而不是解决所有的业务问题。我们的开发人员将实体考虑为了传统ORM意义上的实体,而不是业务所有和业务定义的领域对象。

    不愿意在领域对象中加入业务逻辑会导致贫血的领域模型,如果不加以制止还会使混乱的服务对象激增——就像我们等会儿看到的一样。作为一个团队,现在我们来检视一下创建的服务对象,看看它们实际上是否包含业务逻辑。我们还有一个严格的规则,就是开发人员不能在模型中创建新的对象类型,这对业务来说并不意味着什么。

    作为团队,我们在项目开始时还被实体对象给弄糊涂了,而且这种困惑也与持久化有关。在我们的应用中,大部分实体与内容有关,而且大部分都被持久化了。但当实体不被持久化,而是在运行时由工厂或资源库创建的话,有时候还是会混淆。

    一个很好的此类例子就是“标签合成的页面”。我们在数据库中持久化了编辑创建的所有页面的外观,但我们可以自动生成从标记组合(比如USA+Economics或Technology+China)聚集内容的页面。由于所有可能的标记组合总数是个天文数字,我们不可能持久化所有的这些页面,但系统还必须能生成页面。在渲染标记组合页面时,我们必须在运行时实例化尚未持久化的新Page实例。项目初期我们倾向于认为这些非持久化对象与“真正的”持久化领域对象不同,也不像在对它们建模时那么认真。从业务观点看,这些自动生成的实体与持久化实体实际上并没有什么不同,因此从领域驱动设计观点来看也是如此。不论它们是否被持久化,对业务来说它们都有同样的定义,都不过是领域对象;没有“真正的”和“不是真正的”领域对象概念。

    5.2.2 值对象

    值对象是实体的属性,它们没有特性标识去指明领域中的内容,但表达了领域中有含义的概念。这些对象很重要,因为它们阐明了统一语言。

    值对象阐述能力的一个例子可以从我们的Page类更详细地看出。系统中任何Page都有两个可能的URLs。一个URL是读者键入Web浏览器以访问内容的公开URL。另一个则是从应用服务器直接提供服务时内容依存的内部URL。我们的Web服务器处理从用户那里传入的URL,并将它转换为适合后端CMS服务器的内部URL。

    一种简化的观点是,在Page类中两个可能的URL都被建模为字符串对象:

     public String getUrl(); 
    
     public String getCmsUrl(); 

    不过,这并没有什么特别的表现力。除了这些方法返回字符串这一事实之外,只看这些方法的签名很难确切地知道它们会返回什么。另外想象一下这种情况,我们想基于页面的URL从一个数据访问对象中加载页面。我们可能会有如下的方法签名:

    public Page loadPage(String url);

    这里需要的URL是哪一个呢?是公开的那个还是CMS URL?不检查该方法的代码是不可能识别出来的。这也很难与业务人员谈论页面的URL。我们指的到底是哪一个呢?在我们的模型中没有表示每种类型URL的对象,因此在我们的词汇里面也就没有相关条目。

    这里还含有更多的问题。我们对内部URL和外部URL可能有不同的验证规则,也希望对它们执行不同的操作。如果我们没有地方放置这个逻辑,那我们怎么正确地封装该逻辑呢?控制URLs的逻辑一定不属于Page,我们也不希望引入更多不必要的服务对象。

    领域驱动设计建议的演进方案是明确地对这些值对象进行建模。我们应该创建表示值对象的简单包装类,以对它们进行分类。如果我们这样做,Page里面的签名就如下所示:

     public Url getUrl();
    
     public CmsPath getCmsPath();

    现在我们可以在应用中安全地传递CmsPath或Url对象,也能用业务代表理解的语言与他们谈论代码。

    5.2.3 资源库

    资源库是存在于聚集中的对象,在抽象任何持久化机制时提供对聚集根对象实体的访问。这些对象由业务问题请求,与领域对象一起响应。

    将资源库看成是类似于有关数据库持久化功能的数据访问对象,而非存在于领域中的业务对象,这一点很不错。但资源库是领域对象:他们响应业务请求。资源库始终与聚集关联,并返回聚集根的实例。如果我们请求一个页面对象,我们会去页面资源库。如果我们请求一个页面对象列表来响应特定的业务问题,我们也会去页面资源库。

    我们发现一个很好的思考资源库的方式,就是把它们看成是数据访问对象集合之上的外观。然后它们就成为业务问题和数据传输对象的结合点,业务问题需要访问特定的聚集,而数据传输对象提供底层功能。

    这里举一小段页面资源库的代码例子,我们来实际看下这个问题:

     private final PageDAO<Page> pageDAO; 
    
     private final PagesRelatedBySectionDAO pagesRelatedBySectionDAO; 
    
    
    
     public PageRepository(PageDAO<Page> pageDAO,
    
             EditorialPagesInThisSectionDAO pagesInThisSectionDAO, 
    
             PagesRelatedBySectionDAO pagesRelatedBySectionDAO) { 
    
         this.pageDAO = pageDAO; 
    
         this.pagesRelatedBySectionDAO = pagesRelatedBySectionDAO;
    
     } 
    
    
    
     public List<Page> getAudioPagesForPodcastSeriesOrderedByPublicationDate(Series series, int maxNumberOfPages) { 
    
         return pageDAO.getAudioPagesForPodcastSeriesOrderedByPublicationDate(series, maxNumberOfPages); 
    
     } 
    
    
    
     public List<Page> getLatestPagesForSection(Section section, int maxResults) {
    
         return pagesRelatedBySectionDAO.getLatestPagesForSection(section, maxResults); 
    
     }

    我们的资源库有业务请求:获取PublicationDate请求的特定播客系列的页面。获取特定版面的最新页面。我们可以看看这里使用的业务领域语言。它不仅仅是一个数据访问对象,它本身就是一个领域对象,跟页面或文章是领域对象一样。

    我们花了一段时间才明白,把资源库看成是领域对象有助于我们克服实现领域模型的技术问题。我们可以在模型中看到,标签和内容是一种双向的多对多关系。我们使用Hibernate作为ORM工具,所以我们对其进行了映射,Tag有如下方法:

    public List<Content> getContent();

    Content有如下方法:

     public List<Tag>  getTags(); 

    尽管这一实现跟我们的编辑看到的一样,是模型的正确表达,但我们有了自己的问题。对开发人员来说,代码可能会编写成下面这样:

     if(someTag.getContent().size() == 0){
    
         ... do some stuff
    
     }

    这里的问题是,如果标签关联有大量的内容(比如“新闻”),我们最终可能会往内存中加载几十万的内容条目,而只是为了看看标记是否包含内容。这显然会引起巨大的网站性能和稳定性问题。

    随着我们演进模型、理解了领域驱动设计,我们意识到有时候我们必须要注重实效:模型的某些遍历可能是危险的,应该予以避免。在这种情况下,我们使用资源库来用安全的方式解决问题,会为系统的性能和稳定性牺牲模型个别的清晰性和纯洁性。

    5.2.4. 服务

    服务是通过编排领域对象交互来处理业务问题执行的对象。我们所理解的服务是随着我们过程演进而演进最多的东西。

    首要问题是,对开发人员来说创建不应该存在的服务相当容易;他们要么在服务中包含了本应存在于领域对象中的领域逻辑,要么扮演了缺失的领域对象角色,而这些领域对象并没有作为模型的一部分去创建。

    项目初期我们开始发现服务开始突然涌现,带着类似于ArticleService的名字。这是什么呀?我们有一个领域对象叫Article;那文章服务的目的是什么?检查代码时,我们发现该类似乎步了前面讨论的FootballMatchSummary的后尘,有类似的模式,包含了本该属于核心领域对象的领域逻辑。

    为了对付这一行为,我们对应用中的所有服务进行了代码评审,并进行重构,将逻辑移到适当的领域对象中。我们还制定了一个新的规则:任何服务对象在其名称中必须包含一个动词。这一简单的规则阻止了开发人员去创建类似于ArticleService的类。取而代之,我们创建ArticlePublishingService和ArticleDeletionService这样的类。推动这一简单的命名规范的确帮助我们将领域逻辑移到了正确的地方,但我们仍要求对服务进行定期的代码评审,以确保我们在正轨上,以及对领域的建模接近于实际的业务观点。

    6. 演进架构中DDD的一些教训

    尽管面临挑战,但我们发现了在不断演进和敏捷的环境中利用DDD的显著优势,此外我们还总结了一些经验教训:

    • 你不必理解整个领域来增加商业价值。你甚至不需要全面的领域驱动设计知识。团队的所有成员差不多都能在他们需要的任何时间内对模型达成一个共同的理解。
    • 随着时间的推移,演进模型和过程是可能的,随着共同理解的提高,纠正以前的错误也是可能的。

    我们系统的完整领域模型要比这里描述的简化版本大很多,而且随着我们业务的扩展在不断变化。在一个大型网站的动态世界里,创新永远发生着;我们始终要保持领先地位并有新的突破,对我们来说,有时很难在第一次就得到正确的模型。事实上,我们的业务代表往往想尝试新的想法和方法。有些人会取得成果,其他人则会失败。是逐步扩展现有领域模型——甚至在现有领域模型不再满足需求时进行重构——的业务能力为guardian.co.uk开发过程中遇到的大部分创新提供了基础。

    7. 附录:具体示例

    为了了解我们的领域模型如何生成真实的结果,这里给出了一个例子,先看单独的内容……

    8. 关于作者

    Nik Silver是Guardian News & Media软件开发总监。他于2003年在公司引入敏捷软件开发,负责软件开发、前端开发和质量保证。Nik偶尔会在blogs.guardian.co.uk/inside上写Guardian技术工作相关的内容,并在他自己的站点niksilver.com上写更宽泛的软件问题。

    Matthew Wall是Guardian News & Media的软件架构师,深入研究敏捷环境下大型Web应用的开发。他目前最关心的是为guardian.co.uk开发下一代的Web平台。他在JAOO、ServerSide、QCon、XTech和OpenTech上做过关于此及相关主题的各种演讲。

    Web架构设计经验分享

    作者:朱燚
    来源:http://www.cnblogs.com/yizhu2000/archive/2007/12/04/982142.html

     

    本人作为一位web工程师,着眼最多之处莫过于 性能与架构,本次幸得参与sd2.0大会,得以与同行广泛交流,于此二方面,有些心得,不敢独享,与众博友分享,本文是这次参会与众同撩交流的心得,有兴趣者可以查看视频

    架构设计的几个心得:


    一,不要过设计:never over design

    这是一个常常被提及的话题,但是只要想想你的架构里有多少功能是根本没有用到,或者最后废弃的,就能明白其重要性了,初涉架构设计,往往倾向于设计大而化一的架构,希望设计出具有无比扩展性,能适应一切需求的增加架构,web开发领域是个非常动态的过程,我们很难预测下个星期的变化,而又需要对变化做出最快最有效的响应。。

    ebay的工程师说过,他们的架构设计从来都不能满足系统的增长,所以他们的系统永远都在推翻重做。请注意,不是ebay架构师的能力有问题,他们设计的架构总是建立旧版本的瓶颈上,希望通过新的架构带来突破,然而新架构带来的突破总是在很短的时间内就被新增需求淹没,于是他们不得不又使用新的架构
    web开发,是个非常敏捷的过程,变化随时都在产生,用户需求千变万化,许多方面偶然性非常高,较之软件开发,希望用一个架构规划以后的所有设计,是不现实的

    二,web架构生命周期:web architecture‘s life cycle

    既然要杜绝过设计,又要保证一定的前瞻性,那么怎么才能找到其中的平衡呢?希望下面的web架构生命周期能够帮到你

    architecture_life_cycle

    所设计的架构需要在1-10倍的增长下,通过简单的增加硬件容量就能够胜任,而在5-10倍的增长期间,请着手下一个版本的架构设计,使之能承受下一个10倍间的增长

    google之所以能够称霸,不完全是因为搜索技术和排序技术有多先进,其实包括baidu和yahoo,所使用的技术现在也已经大同小异,然而,google能在一个月内通过增加上万台服务器来达到足够系统容量的能力确是很难被复制的


    三,缓存:Cache

    空间换取时间,缓存永远计算机设计的重中之重,从cpu到io,到处都可以看到缓存的身影,web架构设计重,缓存设计必不可少,关于怎样设计合理的缓存,jbosscache的创始人,淘宝的创始人是这样说的:其实设计web缓存和企业级缓存是非常不同的,企业级缓存偏重于逻辑,而web缓存,简单快速为好。。

    缓存带来的问题是什么?是程序的复杂度上升,因为数据散布在多个进程,所以同步就是一个麻烦的问题,加上集群,复杂度会进一步提高,在实际运用中,采用怎样的同步策略常常需要和业务绑定

    老钱为搜狐设计的帖子设计了链表缓存,这样既可以满足灵活插入的需要,又能够快速阅读,而其他一些大型社区也经常采用类此的结构来优化帖子列表,memcache也是一个常常用到的工具

    钱宏武谈架构设计视频 http://211.100.26.82/CSDN_Live/140/qhw.flv

    Cache的常用的策略是:让数据在内存中,而不是在比较耗时的磁盘上。从这个角度讲,mysql提供的heap引擎(存储方式)也是一个值得思考的方法,这种存储方法可以把数据存储在内存中,并且保留sql强大的查询能力,是不是一举两得呢?

    我们这里只说到了读缓存,其实还有一种写缓存,在以内容为主的社区里比较少用到,因为这样的社区最主要需要解决的问题是读问题,但是在处理能力低于请求能力时,或者单个希望请求先被缓存形成块,然后批量处理时,写缓存就出现了,在交互性很强的社区设计里我们很容易找到这样的缓存

    四,核心模块一定要自己开发:DIY your core module

    这点我们是深有体会,钱宏武和云风也都有谈到,我们经常倾向于使用一些开源模块,如果不涉及核心模块,确实是可以的,如果涉及,那么就要小心了,因为当访问量达到一定的程度,这些模块往往都有这样那样的问题,当然我们可以把问题归结为对开源的模块不熟悉,但是不管怎样,核心出现问题的时候,不能完全掌握其代码是非常可怕的


    五,合理选择数据存储方式:reasonable data storage

    我们一定要使用数据库吗,不一定,雷鸣告诉我们搜索不一定需要数据库,云风告诉我们,游戏不一定需要数据库,那么什么时候我们才需要数据库呢,为什么不干脆用文件来代替他呢?
    首先我们需要先承认,数据库也是对文件进行操作。我们需要数据库,主要是使用

    展开全文
  • home" border=0 height=38 src="http://www.tenfei.net/ee-forum.org/eeflogo.gif" width=93>复杂系统的层级原理与模型驱动软件体系结构 余彤鹰 2002-5-17 写在前面 最近看到模型驱动在国内渐渐被更多的人注意,...

    eeflogo.gif -> home

    复杂系统的层级原理与模型驱动软件体系结构

     

    余彤鹰 2002-5-17


    写在前面

      最近看到模型驱动在国内渐渐被更多的人注意,前几天又看到一些关于UML优劣和应用方面的争论。作为繁忙工作中的一种休息,从过往的研究笔记中整理一点东西放在这里,与大家交流。

    层级理论是构建复杂软件体系的基本原则

      诺贝尔奖获得者赫伯特 A. 西蒙曾论述到:“要构造一门关于复杂系统的比较正规的理论,有一条路就是求助于层级理论……我们可以期望,在一个复杂性必然是从简单性进化而来的世界中,复杂系统是层级结构的”。对于软件这样复杂的人造事务,发现层级和运用层级,是分析和构建的基本原则。

    软件的体系结构是层级的

      粗略地观察一下软件表述方式(语言)的发展:从穿孔纸带(机器的语言)开始,首先是汇编语言,然后是高级语言,再往后有面向对象语言和所谓第四代语言(FGL)出现……应当留意:每一代的语言并不是在“取代”前一代语言,而是用上一代语言来“写”下一代语言。在这个自然的进化过程中,西蒙所论述的复杂体系的层级特征清晰地出现了。

      进一步看,在由简单到复杂的进化道路上,软件的体系结构、软件开发的体系结构、软件开发工具的体系结构等等,都呈现出层级的特征。“好”的软件体系具有更加清晰的层级。

    一维语言之后是模型

      这里不想展开讨论这个问题,只是提出一些思考的结果。与自然语言类似,现有的“程序设计语言”是单维的,它的基本语法是以前后顺序为基础的。当系统的复杂程度提高时,用这样的语言精确描述复杂系统变得越发困难,更遑论有效地修改维护;可视化开发平台、代码管理工具(甚至某种意义上共享组件也可包括在内)等的出现对此是一种补充,但仍然不是最终的解决方法。软件描述体系进化到这里,面临着一次突变,将有新的物种出现,这个新物种可能就是模型。笔者认为,模型与程序语言主要的区别不在于图形化,也不在于抽象的程度,而在于表达方式突破了“单一顺序”的限制,最简单的例子就是二维表。模型可以更容易和直接地表达复杂的结构。

    模型和语言都是对系统的描述

      传统的编程语言和模型都是一种表述的体系,前者适合表述顺序过程,后者适合表述复杂结构。模型的必要性可以通过下面这个例子看出来:

      为了精确地复现,你可以用语言精确地叙述一个立方体,甚至10个立方体组合的形状,但你不会试图用语言描述一栋房子,适当的方式是用工程图纸。

      建立企业应用系统的情形可以从以上例子得到启发,企业系统要表述的,主要是复杂的结构,过程占的比重很小,因此,模型就变得更加重要乃至必要了。

    OMG组织的MDA战略

      OMG最新的战略,是建立模型驱动体系架构(Model Driven Architecture, MDA),它的意义不是三言两语可以说清楚的,但从软件进化的角度来说,可能带有一种必然性,从上面的讨论,至少可以引申出两个理由:

    1. 更有效地描述复杂系统的需要;
    2. 系统复杂化带来的层级区分的需要。

    关于模型的几个分析要素

      笔者认为,以下特征对软件体系中模型的运用是十分重要,或者有特殊意义的:

    • 模型的时效性(time-effectiveness of model):关于这一点最重要的区分在于,是“运行期模型”(Run-Time Model),还是开发期模型?这个区别,有点类似于解释的语言和编译的语言间的区别,但其意义却非同一般,笔者认为,“运行期模型”,揭示了模型驱动的本质。
    • 模型的可进化性(evolutionableness of model):是否可以在系统的应用过程中,持续地适应应用环境与需求的变化,不断地由应用者或自适应地对模型进行改进?这是对模型“性能”的一种度量。
    • 模型的层级性(hierarchy of model):正如语言有多个层次一样,没有理由认为模型只有一个层次,当系统足够复杂时,模型的层次划分将会是必要的。

    UML和企业模型

      运用上面的要素分析一下,可以发现:

      UML是“紧贴”高级软件语言(例如C++)的模型体系,其时效是在软件生命周期的开发期间,而不是运行期间,其描述的层级是在软件的组件、对象一级,典型要素是软件中的对象,软件上一个操作的动作等。

      企业模型(比如ARIS, CIM-OSA, GERAM),典型的要素是组织,产品,过程等,它们是从企业的业务对象着眼的。二者在层级上有差距,而且企业模型追求的最终结果,是从“开发期模型”到达“运行期模型”,并且,笔者认为它最终应当是一种可进化的模型,这与UML的设计目标并不符合。

      它们两者间并不相互排斥,而应当考虑它们的“层接”。按照笔者的理解,OMG的MDA即使全面实现,也仍然不能做为或替代企业模型,但有可能成为企业模型的基础,这不是模型好坏或能力的问题,而是层级定位的问题。

    写在后面

      面向对象(Object Oriented, OO)作为软件体系结构方面的一种演进而出现,也曾经被一些人误解为对过程化语言(或面向过程的体系结构)的取代。笔者认为,尽管OO反应了一种世界观,是一种思维的方式,但并不代表一切;且从层级和进化的观点上,也不应当将它看作是对既有东西的一种简单的取代。模型或模型驱动同样如此,它可能是继面向对象之后,软件体系结构的又一个重大的进化,但不是用来取代面向对象或结构化设计。笔者在1998年撰写《迈向21世纪的企业信息技术应用》一文时,对于模型的地位和作用并没有今天这样的认识,现在我坚信,对于企业信息系统这样复杂的系统,要想做到有效、可控制地规划与构建乃至具有“柔性”、可在运行期间不断地调整,“模型”是必须的,而且,表达与构建复杂企业系统时所需的模型,可能是多层次的,所谓“通用企业平台上的专用执行系统”,就应当是一个由运行期模型驱动的系统。


    企业工程论坛  1998 - 2002

    展开全文
  • RTOS新特征适应高档汽车应用■ 李梅改善对分布式系统和多核系统的支持,RTOS可以满足高档汽车应用的需求。 我们的街道和高速公路正在变成嵌入式网络流动的线路图,这些由许多嵌入式系统组成的网络装在车轮上,随处...

    RTOS新特征适应高档汽车应用


    ■ 李梅



    改善对分布式系统和多核系统的支持,RTOS可以满足高档汽车应用的需求。

    我们的街道和高速公路正在变成嵌入式网络流动的线路图,这些由许多嵌入式系统组成的网络装在车轮上,随处流动。现代汽车完全可以说是一个计算平台,它有超过50个嵌入式处理器,计算机软件代码超过百万行。由于汽车制造商的注意力已经集中在“在任何可能的地方使用非定制的软件”,所以汽车公司内部的汽车规格的软件开发部门未来的工作重点是将其实践经验和独特的创造力用于汽车软件的需求制定和标准化方面。

    嵌入式系统的许多基本问题都可以通过实时操作系统(RTOS)来解决。一个很好的例子就是欧洲汽车工业OSEK/VDX 组织已经为汽车分布的嵌入式控制单元定义一个标准的架构。OSEK/VDX 要求RTOS能够很好地满足汽车嵌入式控制单元在动力系统、底盘与悬梁、车身电子等方面的需求。OSEK/VDX正在成为当前国际汽车工业界占据主导地位的汽车电子开放式系统及其接口的软件规范体系

    显然,OSEK/VDX还不能满足未来汽车应用在高性能传导系统、信息娱乐、安全与生命等方面的需求。很多人认为实时操作系统(RTOS)相当于软件中的赛车,要求小、快、高度协调。除此之外,一个好的RTOS能使应用系统始终满足时限的要求,能对任何时间要求苛刻的事件做出响应,在正确的时间做一个正确的动作。

    为高端汽车应用的可供选择的大量RTOS正在日益完善,以适应这些需求。

    RTOS内核

    大多数的RTOS内核均支持任务调度的基于优先权抢先占有机制。在RTOS中,过程按优先级执行。时限紧迫的过程投入运行时,可以立即从低优先级的过程接管CPU。高优先级过程在结束前,能一直继续运行,除非它被一个更高优先级的过程所抢占。这种“抢占” 调度方式可以使对于时间要求严格的过程满足时限的要求。

    一些RTOS也提供一些已经实践检验的任务调度选择,如最终任务调度或者分区调度等。它也提供存储器分配调度,以管理大容量RAM存储空间,就像设备I/O管理程序管理和组织大量的不同的设备驱动程序一样。例如,一个设备I/O管理程序对于管理一系列通信设备驱动程序如汽车远程通信系统中经常出现的驱动程序等是非常有效的。驱动程序可以包括:控制区域网 CAN (Controller Area Network)、局部互联协议LIN (Local Interconnect Network)、IEEE1094、高速容错网络协议FlexRay和用于汽车多媒体和导航的媒体定向系统传输MOST (Media-Oriented Systems Transport)等。

    为了提高系统的可靠性,RTOS一方面要对存储器进行保护;另一方面是在分布式系统环境下,可以将应用的任务分派到多个CPU,即使一个CPU失效,也不会停止应用程序的工作。

    分布式应用有它自己要解决的问题,例如,对大多数的RTOS,一般需增加为应用服务的专用的网络程序,使接在网络上的CPU能相互“对话”,进行服务。此外对于大多数RTOS,驱动程序、协议和应用程序是与内核紧密相连的,要把它们从一个核搬移到另一个核,需要建立一个适合各个CPU的新内核的映像,并仔细地对它进行测试。

    微核RTOS从两方面来解决这个问题:首先,使应用程序、协议和驱动程序全都与操作系统脱离,从而使它们从一个CPU 搬移到另一个CPU时,可以不需要对内核重新配置;其次,在微核操作系统中应用程序间通信的典型情况是通过传递消息进行的,如果实现得好,可不需要专用的网络程序。例如,当应用A发送一个消息到应用B时,它不用去了解应用B是使用同一个CPU板,还是由网络连接的另一个CPU。结果任何CPU上的一个过程可以对任何其他机器上的任何资源进行显式的存取,这个网络就像单个计算机那样工作。

    设备I/O监控程序提供一个标准的通道,让应用软件任务可以操作各种驱动程序。未来RTOS内核解决的主要问题应该是内部任务的通信与同步。

    间接与直接的消息传递机制

    大多数的RTOS为内部任务的通信提供了多种形式的异步消息传递机制。异步消息传递机制是对数据传输从一个任务到另一个任务的一种简单和松散连接方式。一个任务给另一个任务传递一个消息时,并不用等到接受任务发回任何的确认信息。

    不同的RTOS实施异步通信机制的方式各不相同。不过最简单的概念型的方法被称为直接异步通信机制,就是一个任务直接对另一个任务发送消息,如图1所示。


    图1 内部任务通信的直接消息传递机制

    这是一种直截了当和最佳的软件设计模型。而在另一方面,采用间接异步消息传递机制,应用软件会受到任务发送和接受消息的消息队列的影响,如图2所示,这是一个吃力不讨好的软件设计模型。


    图2 内部任务通信的间接消息传递机制

    对于一些高复杂性应用,如汽车信息娱乐(Infotainment)系统和安全系统,通过采用内部任务直接消息传递机制可以很好地控制软件的复杂性。基于同样的原因,直接消息传递机制在多核、分布式多核处理器和容错汽车系统设计中也是首选的通信机制。

    对分布式和多核系统的支持

    通过一个可选的附加的被称为Link Handlers的RTOS部件,就可以支持分布式和多核系统。


    图3 Link Handlers提供的通过处理器边界的消息传递方式

    Link Handlers为运行在不同的处理器之间的应用提供一个异步消息传递方式,它是在传统的通信网络环境下一流的和普遍的选择。Link Handlers通过使用一样的异步直接消息传递模型,并将其扩展到了分布式和多核多处理器系统来完成这一工作。目前大多数的RTOS内核在同一处理器中的任务到任务的通信就采用了异步直接消息传递模型。它保证在系统里各种不同的处理器是完全对等的。

    Link Handlers并不需要应用软件理解分布式系统的结构。实际上,一个任务的通信助手所在的位置对应用软件是透明的:仅当消息在一个任务传向另一个任务时应用代码才会连接。Link Handlers为消息通过处理器边界提供逻辑通道,而消息通过处理器的方式对应用软件是透明的。

    当使用Link Handlers时,连接各种处理器的物理通道可选的范围很广,如网络、串行或总线连接,以及共享存储结构。这些连接基于Handlers的透明通信模型,使得在一个分布式汽车系统里采用异构处理器包括数字信号处理(DSP)成为可能。

    高安全性和高可用性支持

    除了完成消息传递以外,Link Handlers也必须与运行在其他处理器上的“监视”任务协同工作,而这些处理器的出席对一些应用是至关重要的。当一些关键任务失败或者变得难以实现时,在任何处理器上运行的其他的任务会很快得到出现问题的通报。这些支持“监视眼”机制的RTOS对设计高安全、高可用性和基于冗余的容错系统大有好处。RTOS的Link Handlers在容错系统探测和报告上有一定的开销,因此卸载很多与此相关的应用代码也很必要。

    下一代的RTOS也应该提供快速的应用软件现场在线更新工具,不需要应用系统停止工作,以重新上载、修订或者卸载软件。这一功能通常被成为热交换。监视眼和热插拔一起成为RTOS基层架构的主要内容,支持高安全性和高可用性系统的设计。

    内存保护

    内存保护是面向安全的RTOS的另一个重要因素。 RTOS应该好好利用存储器管理单元,这是一个大多数现代微处理器中都有的构成部件。以传统的“平铺”(flat)体系结构为例,大多数“成品的”或“自建的”RTOS仍在使用这种体系结构。它把所有的模块放在同一个地址空间中,作为操作系统的内核,没有任何存储器的保护。结果任何模块,不管它是多么无关紧要,也能通过内核对存储器进行重写,有可能导致整个系统的崩溃。

    有少数的RTOS针对这个问题,使应用程序运行在分离的有存储器保护的地址空间。RTOS与处理器硬件的MMU(内存管理单元)一起保护处理器内存免受非授权的存取访问。如果一个应用程序试图侵害存储器,MMU就会捕获这个错误,从而把这个问题隔离开来。但不幸的是,这些操作系统仍和驱动程序、协议、文件系统绑在一起,并且其他系统可对此内核服务,从而使得这些模块中的任何一个都能导致内核发生致命的错误。

    不过,一些RTOS 的微核体系结构则向前迈了一步,可使任何系统级的软件部件在其各自的MMU所保护的地址空间运行。用这种方法,出错的驱动程序和协议则不再成为单独起作用的失效点,而是可以在它们引起其他服务失效前,就使其停止或重新启动,而不必重新开机引导。

    产生的结果是完全独立的软件拥有自己独立的内存空间地址。内存管理设备在其造成诸如数据写进了距离自己很远的地址一类的危害前,可以中途阻止迷失方向的存取访问。

    这些工具在汽车运行中将可以监视应用软件的安全和运行情况。

    汽车电子是本报长期关注的一个热点领域,我们欢迎有关汽车电子的技术、产品等方面的稿件,相关事宜请发邮件到liu_xuexi@ccw.com.cn

    展开全文
  • 【STM32】系统时钟RCC详解(超详细,超全面)

    万次阅读 多人点赞 2019-08-08 15:42:35
    时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。 为什么 STM32 ...
  • 操作系统系统概述——云计算

    千次阅读 2017-01-13 12:58:20
    摘要:系统地分析和总结云计算的研究现状,划分云计算体系架构为核心服务、服务管理、用户访问接口等3个层次。围绕低成本、高可靠、高可用、规模可伸缩性等研究目标,深入全面地介绍了云计算的关键技术及最新研究...
  • 复杂网络分析以及networkx学习

    万次阅读 2017-05-06 11:51:46
    原文地址:陈关荣老师整理的复杂网络的资源作者:zhengw789 http://www.ee.cityu.edu.hk/~gchen/ComplexNetworks.htm http://mrvar.fdv.uni-lj.si/sola/info4/programe.htm 原文地址:NetworkX的...
  •  伴随着用户群积累,社区的壮大,还有来自投资人对变现渴望的压力,似乎最容易想到的变现途径就是“我们也卖点东西吧”,如果直接给淘宝链接,会显得逼格太低,购买别人的系统,钱不少花,最后为了适应自己的
  • 降低软件复杂性的一般原则和方法

    千次阅读 2019-09-24 10:37:31
    其实,回答好第二个问题很重要,大型软件的设计已经复杂到没人能够一次就想到最佳方案,一个仅仅“可行”的方案,可能会给系统增加额外的复杂性。对聪明人来说,接受这点更困难,因为他们习惯于“一次搞定问题”。...
  • VUCA时代:软件架构解决复杂性之道

    千次阅读 2020-02-17 16:29:54
    本文来自、方法学专家张刚老师的分享。本文生动形象地从五大方面介绍了VUCA时代下的软件...1)系统在某种环境下的一组最基本的概念和属性,包括了元素、关系以及设计 和演化的原则——ISO/IEC 45010 Kructen4+1视...
  • 图片服务系统是各种针对C端系统常见的子系统,它的特点是存储规模大请求频度高,且单张图片的读请求远远高于写请求。后面几篇文章我们将从图片服务系统的需求分析开始,一起来讨论如何进行这类系统的技术选型、概要...
  • (一)外围架构 推荐系统是如何和其他网站进行接口的 一般来说,每个网站都会有一个UI系统,UI系统负责给用户展示网页并和用户交 互。网站会通过日志系统将用户在UI上的各种...下图便是这样的一个例子。 数据...
  • 在2010年,google发表了一篇名为“Dapper, a Large-Scale Distributed Systems Tracing Infrastructure”的论文,在文中介绍了google生产环境中大规模分布式系统下的跟踪系统Dapper的设计和使用经验。而zipkin/...
  • 系统间通信本来是一个很大的概念,我们首先重通信模型开始讲解。在理解了四种通信模型的工作特点和区别后,对于我们后文介绍搭建在其上的各种通信框架,集成思想都是有益的。 目前常用的IO通信模型包括四种(这里说...
  • 架构设计 例子和实践

    千次阅读 2012-01-20 09:45:51
    系统设计说明书(架构、概要、详细)目录结构 虽然这些文档一般来说公司都是有模板的,但我写这些文档以来基本上是每写一次就把目录结构给改一次,应该说这是因为自己对这些文档的理解开始加深,慢慢的越来越明白这些...
  • 系统学习机器学习之系统认识

    千次阅读 2015-12-07 16:31:35
    类比学习系统可以使一个已有的计算机应用系统转变为适应于新的领域,来完成原先没有设计的相类似的功能。 类比学习需要比上述三种学习方式更多的推理。它一般要求先从知识源(源域)中检索出可用的知识,再将其...
  • 复杂性思维中文第二版 十一、进化

    万次阅读 2018-04-14 12:17:02
    在现实世界中,适应性景观很复杂,但我们不需要建立现实模型。 为了诱导进化,我们需要基因型和适应性之间的某种关系,但事实证明它可以是任何关系。 为了证明它,我们将使用完全随机的适应性景观。 这是代表适应...
  • 我们迄今为止看到的模型可能具有“基于规则”的特征,因为它们涉及受简单规则支配的系统。 在本章和以后的章节中,我们将探索基于智能体(agent)的模型。 基于智能体的模型包含智能体,它旨在模拟人和其他...
  • 2014年的618显得和以往任何店庆促销日都不同,不仅仅是因为电子商务本身在中国不断飞速发展对京东系统带来的挑战,更为重要的是2014年5月22日刚走入美国纳斯达克殿堂的京东聚集了最耀眼的光芒,能不能保持这样的光芒...
  • 前言 构建,软件生命周期中重要的一环,在...而在现代,系统日益复杂,构建的灵活性要求越来越高,比如:构建过程中需要打包上传到服务器,Maven无法很好地支持这种复杂系统构建,所以,我选择了Gradle,一个基于Gro
  • VxWorks操作系统基础(适合初学者阅读)

    万次阅读 多人点赞 2019-03-31 18:45:54
    1 实时操作系统概述 &nbsp; &nbsp; &nbsp;1.1 实时操作系统 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;在计算的早期开发的操作系统的最原始的...
  • 船舶电力推进系统

    千次阅读 2018-03-06 19:27:32
    在考虑故障情况、恶劣天气和复杂的海上作业时,这尤其重要。然而,许多模拟器,包括这里提出的,在研究定位系统和电力系统时是独立的。作为海洋系统仿真器MATLAB / Simulink库的扩展,本文提出了一种将两个系统相...
  • Knewton适应性学习

    千次阅读 2018-06-21 10:40:29
    Knewton适应性学习 构造全球最强大的教育推荐引擎 1. 介绍 适应性学习:一个以课程应该适应每一个用户的思想为前提的教学方法。 (原文:Ateaching method premised on the idea that the curriculum should ...
  • 最经典的java 23种设计模式及具体例子

    万次阅读 多人点赞 2016-07-10 09:43:50
    最经典的java 23种设计模式及具体例子
  • 操作系统解析

    千次阅读 2019-09-15 17:45:42
    第三节: 操作系统简介3.1 为什么要有操作系统3.2 什么是操作系统3.3 操作系统与普通软件的区别3.4 操作系统发展史3.5 附录及参考资料...
  • AGV控制系统搭建

    万次阅读 多人点赞 2019-06-25 15:32:33
     本文介绍自动导引车(AGV)车载控制系统的实现过程,分为硬件搭建和软件设计两部分,并在其中穿插 AGV 控制的基础知识讲解。 1. 车载控制器 1.1 控制器的类型  车载控制器是控制系统乃至整个 AGV 的...
  • 操作系统复习笔记

    万次阅读 多人点赞 2021-01-20 15:11:12
    第一章 计算机系统概述 基本概念 基本构成:处理器、内存、输入/输出模块、系统总线 处理器中各寄存器的作用 处理器分为执行单元、控制单元、寄存器(用户可见寄存器、控制和状态寄存器) 用户可见寄存器 数据...
  • 大数据平台-元数据管理系统解析

    万次阅读 多人点赞 2018-03-14 09:25:24
    在前面的集成开发环境建设相关文章中,我们也提到过,元数据MetaData狭义的解释是用来描述数据的数据,广义的来看,除了业务逻辑直接读写处理的那些业务数据,所有其它用来维持整个系统运转所需的信息/数据都可以叫...
  • C#多线程简单例子讲解

    万次阅读 2012-10-09 21:35:34
    转载网址: ... .NET将关于多线程的功能定义在System.Threading名字空间中。因此,要使用多线程,必须先声明引用此名字空间(using ...线程池(ThreadPool)是一种相对较简单的方法,它适应于一些需要多个线程而又较短任务...
  • UBIFS文件系统介绍

    千次阅读 2013-10-12 14:50:14
    在了解UBIFS之前一定要注意UBIFS和任何传统的文件系统是不一样的:UBIFS不是运行在block device之上的(比如hard disk, MMC/SD卡,USB flash驱动等等)。UBIFS是运行于raw flash之上。请在开始UBIFS之旅前确保理解...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 82,644
精华内容 33,057
关键字:

复杂适应系统的例子