DDD该如何学?

2006年,国内互联网才刚刚萌芽,大家甚至还不习惯网购,大多数在校生都在宿舍里刷魔兽世界副本。但企业软件开发却得到了蓬勃发展,各大公司和事业单位都纷纷进行信息化转型。

然而大家很快发现,企业应用业务逻辑的复杂度要远远高于技术本身,且企业IT人员很难描述清楚他们真正的业务,广大程序员也普遍缺乏挖掘真正需求的能力。整个开发过程更多的是瀑布式,开发人员一次性收集需求,可能半年后才会和业务人员再次沟通。大多数企业软件就是在这样的环境下硬着头皮上线的,其质量可想而知。

随着《领域驱动设计》中文版的首次发布,DDD(Domain-Driven Design,领域驱动设计)的概念正式进入中国。当时业界普大喜奔,认为它能指导程序员更精准地收集领域知识,进行更合理的设计,企业应用的银弹出现了。

当时的我正处于多层架构的启蒙阶段,挣扎于企业系统的泥潭,又刚刚被Martin Fowler的《企业应用架构》洗了一遍脑,自然也随波逐流地买了一本,捧在手里翻来翻去,但反反复复就是看不懂。当时以为在贫血模型里面加几个方法就是领域模型了,把DAL或DAO改名成Repository就是资源库了。而且身为程序员,自然愿意去关注那些能指导我们写代码的战术设计方法,对那些真正能帮助我们进行合理设计的战略设计方法,则视而不见(可能是因为看也看不懂)。

多年过去,这本书仍然作为我的镇宅之宝戳在书架显眼的位置,希望能有识货的朋友来访时能一眼瞧见,伸出大拇指羡慕嫉妒地说“这么老的书你都有”。或者偶尔拿出来拍张照片在朋友圈晒晒,以炫耀自己当初的见识。顺便翻开一页,把鼻子凑上去闻一闻来自12年前的墨香。

7年之后Vaughn Vernon出版了Implement Domain-Driven Design,简称IDDD。一年之后由同事翻译的中文版《实现领域驱动设计》也相应出版,当时被看做是能让DDD落地的书(毕竟书名里有个“实现”嘛)。然而我在项目技术负责人的带领下,在众多有经验的架构师的指导下,仍然没有弄明白。之前看过的相关知识均已遗忘殆尽。限界上下文、上下文映射这些名词只是似曾相识。

两年之后《领域驱动设计模式、原理与实践》问世,简称PPPDDD。社区对这本书的评价非常之高,甚至认为在IDDD之上。只可惜这本书的翻译质量并不高,我翻了几页之后又束之高阁了。

今年年初,项目上的架构小组又开始组织学习DDD。所使用的“教材”是英文版的PPPDDD。在同事的激励下,我开始重整旗鼓,啃这本英文版大部头。开始精读之后,才发现这是一本很水的好书。说它水是因为它的编排并不足够细心,甚至有不同章节的两段文字完全相同的现象,还会花30页的篇幅去介绍一个基于NHibernate的资源库实现。说它好是因为面面俱到,把所有战略模式和战术模式都介绍了个遍,还有大量代码去帮你实现各种战术模式,可以说相当落地。

在学习的过程中,我常常翻阅IDDD中的相关章节进行补充阅读,发现当初晦涩难懂的概念慢慢变得容易起来。应用服务和领域服务不再傻傻分不清楚,不同的上下文映射方式也能在工作中找到对应的例子。对于DDD,感觉快要开始入门了。

与此同时,IDDD的精华版DDDD(Domain-Driven Design Distilled)也出版了。作者总结了过去几年在DDD方面的实战经验,将IDDD中的诸多内容精简升华。在很多概念处都标注了IDDD中的相关章节,可以算是IDDD的一个索引。

其中文版《领域驱动设计精粹》由ThoughtWorks同事覃宇和笪磊合作翻译。这是我读过的最良心的一本书籍,因为它包含了大量译者注解,解释了很多书中没有解释清楚的概念(毕竟是精粹本)。还有些有争议的观点,译者也毫不客气地给出自己的看法。

像这样注解超过原文的情况在其他书中是很少见的。每一处注解都倾注了译者的心血和精力,这背后势必包括大量资料的查阅和研究,而且很多解释都夹带了浓浓的ThoughtWorks特色,使得这样一本薄薄的书变得丰满充实起来。

如果你读书快的话,可能两个小时就读完这样一本书。但如果把原书和注解中的推荐文章和书籍读完,恐怕要一个月。我顺着书中的指引,找到了ThoughtWorks洞见上的所有DDD文章,读完之后,世界观崩塌了,感觉自己刚要入门就要放弃了。具体原因请参考链接中的文章。

其实,不管是DDD、IDDD、PPPDDD还是DDDD,讲的都是理论,充其量会附加一些作者杜撰的示例。相信我,光学习理论是没有用的,你必须将其应用于实践,在自己的真实项目里演练DDD。这时你才会发现,那些白纸黑字的概念,在读书时似乎搞清楚了,但一使用起来,反而更迷惑了。就像最基本的子域和限界上下文的关系问题,ThoughtWorks的首席咨询师肖然就和Vaughn Vernon的理解就相去甚远。到底该“信谁”?那就似乎更要通过实践来出真知了。


更多精彩洞见,请关注微信公众号:思特沃克

Share

技术雷达第十九期正式发布,用百余个条目更新你的技能图谱!

ThoughtWorks每年都会出品两期技术雷达,这是一份关于技术趋势的报告,由ThoughtWorks 技术战略委员会(TAB)经由多番正式讨论给出,它以独特的雷达形式对各类最新技术的成熟度进行评估并给出建议,为从程序员到CTO的利益相关者提供参考。

它比那些我们能在市面上见到的其他技术行情和预测报告更加具体、更具可操作性,因为它不仅涉及到新技术大趋势,更有细致到类库和工具的推荐和评论,因此更容易落地。经过半年的追踪与沉淀,ThoughtWorks TAB(ThoughtWorks技术咨询委员会)根据我们在多个行业中的实践案例,为技术者产出了第十九期技术雷达,对百余个技术条目进行分析,阐述它们目前的成熟度,并提供了相应的技术选型建议。

本期主题

粘性十足的云平台

云提供商知道他们正在严峻的市场中进行竞争。为了获胜,他们需要吸引用户注册并长期留住他们。因此,为了保持竞争力,他们在新增产品特性上你争我抢,使得彼此不相上下。这一点可以从本期雷达试验环中以下云提供商的排名看出: AWS、 Google Cloud Platform 和 Azure 。然而,一旦用户注册,这些云提供商就倾向于与用户建立尽可能高的粘性,以阻止他们使用其他提供商的服务。这通常表现为其云服务会与其服务和工具套件紧密集成。用户只有继续使用其云服务,才能获得更好的开发者体验。通常在用户决定是否将其部分或全部工作负载移动到另一朵云上,或发现云服务的使用和账单多到失控时,就能明显感觉到这种粘性。我们鼓励客户使用 架构适应度函数度量成本 的技术来监控运维成本,并将其作为衡量云供应商粘性的指标。或者使用Kubernetes和容器,并通过运用基础设施即代码来提升工作负载的可移植性,降低切换到另一个云提供商的成本。在本期雷达中,我们还会介绍两个新的云基础设施自动化工具:Terragrunt和Pulumi。虽然我们支持通过粘性的高低来评估云提供商的新产品,但提醒你不要落入只使用通用云服务功能的陷阱。根据我们的经验,创建和维护与云无关的抽象层的开销,会超出退出某个特定云提供商的花费。

挥之不去的企业级应用反模式

无论技术如何快速变化,一些企业仍然想方设法地重新实现过去的反模式。雷达中的许多暂缓条目都在揭穿一些“新瓶装旧酒”的老把戏。比如:用Kafka重新创建ESB的反模式、分层式微服务架构、Data-hungry packages、过度庞大的API网关、Low-code 平台和一些其他有害的旧实践。一如既往的根本问题,是如何在隔离和耦合之间取得平衡:我们隔离组件,使其在技术角度便于管理。但是我们也需要协调组件,使其有助于解决业务问题。这就产生了某种形式的耦合。因此,上述旧模式就不断重新冒出来。新的架构和工具为解决这些问题提供了适当的方法,但这需要刻意去理解如何正确地使用它们,而不仅仅是使用崭新的技术去重新实现旧模式。

持之以恒的工程实践

随着技术创新步伐加快,新技术的发展呈现出一种从爆发到沉淀不断循环的模式。每当能够颠覆我们对软件开发固有认知的新技术出现时,都会引起业界的争相追捧,容器化、响应式前端和机器学习都是很好的例子。这时技术处在爆发阶段。然而,只有在明确如何与长期以来的工程实践(持续交付、测试、协作等)相结合之后,新技术才能真正的发挥功效,并进入沉淀阶段,为下一次爆发性扩张打下坚实的基础。在沉淀阶段,我们尝试在新技术的背景下应用实践,比如进行全面的自动化测试以及创建脚本代替重复操作,通常也会创造出新的开发工具。虽然表面看来技术创新是行业发展的唯一驱动力,但事实上,创新与持之以恒的工程实践相结合才是我们不断进步的基础。

速度 = 距离 / 时间

通常,我们会选取本期雷达中部分共性条目的精彩集锦展现在雷达主题中,但本主题涉及自技术雷达诞生以来出现过的所有条目。我们发现(并通过一些调研证明)雷达条目停留在雷达上的时间正在缩减。当我们在10年前启动技术雷达时,如果某个条目在雷达上的位置不再移动,它依然会保留两期(大约一年)时间,之后才会自动移出雷达。然而正如标题中的公式所说,速度 = 距离 / 时间: 软件开发生态系统中的变化一直在持续加速。在时间保持不变(依然是每年发布两次)的前提下,雷达中技术创新所跨越的距离明显地增大了。这为精明的读者提供了显著的证据:技术变革的步伐正在不断加快。我们不仅看到雷达中的各个象限在加速变化,也看到了客户对新兴的及多样化的技术选择所表现出的兴趣。因此我们将改变传统的默认模式:雷达不再默认保留其上的条目,它们是否出现在雷达上完全取决于它们当前的价值。我们在深思熟虑后做出了这项改变,并认为只有这样才能更好地跟上技术生态系统中前所未有的狂热变化节奏。

象限亮点抢先看

Event Storming(事件风暴)

快速市场响应能力是组织进行微服务转型的主要驱动之一。然而只有沿长期业务领域边界对服务(及其支持团队)进行清晰划分时,这种期望才可能实现。否则,现实需求只有在跨组织和跨服务的通力合作才下能完成,这自然会在规划产品路线图时产生冲突。良好的领域模型设计是解决此问题的方案,事件风暴(EVENT STORMING)也迅速成为我们最喜爱的方法之一,它使我们能够迅速识别问题领域中的关键概念,并用最好的方式与各方利益相关人制定解决方案。

Microservice Envy

微服务已成为现代云计算系统中的领先的架构模式,但我们依旧认为团队在使用该架构时应谨慎。 MICROSERVICE ENVY特指那些盲目追赶微服务潮流的现象,很多团队在实践微服务时并没有简化其系统架构,大多数的实践方案只是将一些简单的服务聚合在一起而已。目前,Kubernetes等平台简化了复杂的微服务系统的部署问题,其他服务提供商们也正在推进他们的微服务治理方案,这些强大的工具都可能裹挟团队走上微服务之路。 但请千万谨记,微服务是通过开发复杂度来换取运维复杂度,并需要自动化测试、持续交付和DevOps文化提供坚实的支撑。

Observability as Code(可观测性即代码)

可观测性是运转分布式系统与微服务架构必不可少的一部分。我们依赖不同的系统输出来推断分布式组件的内部状态,比如分布式追踪、日志聚合、系统指标等,进而诊断问题所在,并找到根本原因。可观测性生态系统的一个重要方面就是监控——可视化以及分析系统的输出——并且在检测到异常时报警。传统的监控报警配置,都是通过图形界面的操作完成。这种方法导致控制面板页的配置不可重复,从而无法持续测试和调整报警,来避免报警疲劳或错过重要的报警,进而偏离组织的最佳实践。我们强烈建议使用代码来配置可观测性生态系统,称为可观测性即代码(OBSERVABILITY AS CODE),并且采取基础设施即代码的方式搭建其基础设施。因此,在选择提供可观测性的工具时,要选择支持通过代码版本控制进行配置,并能通过基础设施持续交付流水线执行API或命令行的产品。可观测性即代码,是基础设施即代码中经常被遗漏的一部分,我们认为这一点非常重要,需要明确指出。

Four key metrics(四个关键指标)

2014年首次发布的DevOps状态报告指出,高效团队创造了高效的组织。最近,该报告背后的团队编写了Accelerate一书,描述了他们在报告中使用的科学方法。两份材料的核心点都支持了软件交付性能的四个关键指标(FOUR KEY METRICS):前置时间,部署频率,平均恢复时间(MTTR)和变更失败百分比。作为帮助许多组织转型的咨询公司,反复使用这些指标测量,可以帮助组织确定他们是否在提高整体效能。每个指标都创造了一个良性循环,并使团队专注于持续改进:缩短交付周期,减少浪费的活动,从而使你可以更频繁地部署;部署频率迫使你的团队改进他们的实践和自动化流程;通过更好的实践,自动化和监控可以提高你从故障中恢复的速度,从而降低故障频率。

Run cost as architecture fitness function(架构适应度函数)

随着软件架构及其业务的演进,我们理应密切关注应用的运行成本,但发现并非所有的组织都如此。尤其是在使用无服务器架构时,开发者们认为无服务器架构会更便宜,因为他们只需按消耗的计算时间付费。然而几家主要的云服务提供商在热门的无服务器函数上定价十分精明,虽然无服务器在快速迭代上很有优势,但与专属云(或内部私有云)相比,它的开销可能随着使用量迅速增长。我们建议团队将应用的运行成本纳入架构适应度函数(RUN COST AS ARCHITECTURE FITNESS FUNCTION)来考量,这意味着:追踪并权衡应用的运行成本与交付价值;当它们之间产生较大出入时,就需要考虑改进软件架构了。

Debezium

DEBEZIUM是一个change data capture (CDC)平台,可以将数据库的变更以流的形式传入 Kafka 主题中。CDC是一种流行的技术,具有多个使用场景,包括将数据复制到其他数据库中,为分析系统提供数据,从单块系统中提取微服务,以及令缓存数据无效等。我们一直在寻找这个领域的工具或平台(包括在之前的技术雷达中讨论过的 Bottled Water),而Debezium 是一个极佳的选择。它使用了基于日志的CDC方法,意味着能以对数据库日志文件的变更进行响应的方式进行工作。Debezium使用了Kafka连接,这使得它具有高度的容量伸缩性,以及对故障的系统韧性。它拥有包括Postgres、Mysql和MongoDB在内的多个数据库的CDC连接器。目前,我们正在一些项目上使用该平台,并取得了很好的效果。

Quorum

在区块链技术领域,Ethereum(以太坊)是一个领先的开发者生态系统。我们看到了一些新兴的解决方案,它们旨在将Ethereum这项技术传播到一些企业环境中。这些企业通常需要网络权限和交易隐私管理,另外还需要更高的吞吐量和更低的延迟。 QUORUM 就是其中的一个解 决方案。Quorum最初由J.P. Morgan开发,其定位是“企业版的Ethereum”。与创建了新的以太坊虚拟机(EVM)的Hyperledger Burrow 节点不同,Quorum的代码源自以太坊官方客户端的一个分支,所以能与以太坊一起进化。在保留了以太坊账本的大多数功能的前提下,Quorum将共识协议从工作量证明机制更改为更高效的协议,并增加了私有交易支持。使用Quorum,开发人员可以使用他们的以太坊知识来构建企业级的区块链应用,这些知识包括 Solidity语言和 Truffle 合约。然而根据我们的经验,Quorum还没有为应用于企业做好充足的准备;比如:它缺乏针对私有合约的访问控制机制,无法用于负载均衡,并且只支持部分数据库。所有的这些限制都为用户的部署与设计带来显著的负担。我们建议在使用Quorum的时候保持警惕,同时密切关注它的后续发展。

IPFS

在多数情况下,区块链不适合存储 blob 文件 (例如:图像,音频),当人们开发 DApp 时,一种选择是将blob文件存放在一些链下的集中式数据存储中,这种做法通常会导致信任缺失,另一种选择是将它们存储在星际文件系统 IPFS上,这是一种内容可寻址、版本化、点对点的文件系统。它旨在高效地分发大规模数据,并能阻止任何中心化机构删除数据,文件存储在不需要相互信任的对等节点上。IPFS 保存文件的每一个版本,这样你将永远不会丢失重要文件,我们将IPFS视为区块链技术的好的补充。除了区块链应用程序外,IPFS还有一个愿景是对现有的网络基础设施进行去中心化重塑。

Resin.io

RESIN.IO 是一个物联网(IoT)平台。虽然只做把容器部署到设备中这一件事,但它做得很好。开发人员使用一个软件即服务( SaaS)的门户来管理设备,并为这些设备分发由 Dockerfile 定义的应用。该平台可以为多种硬件类型构建容器,并通过无线的方式部署容器镜像。Resin.io 使用balena 来管理容器。而balena是一个基于 Mobby 框架的容器引擎,由Docker 出品。该平台仍在开发中,有些功能尚需完善,也缺少一些特性(比如与私有容器注册服务协同工作)。但是目前的特性集(包括从 Web 门户使用 ssh 访问一 个设备上的容器)表明它的未来充满希望。

Knative

作为应用开发者,我们喜欢专心解决核心业务问题,而让底层平台来处理那些枯燥且困难的任务(如部署、容量伸缩及应用程序管理)。虽然无服务器架构往这个方向迈出了一步,然而大多数流行的产品都会与某个专有实现绑在一起。而这意味着供应商绑定。KNATIVE试图以开源无服务器平台的方式来解决此问题。它良好地集成了流行的Kubernetes生态系统。利用 Knative ,可以对随时请求的计算进行建模(其间可以从一些框架中进行选择,如 Ruby on Rails、Django和Spring 等),可以订阅、交付和管理事件,可以集成用户所熟悉的 CI和CD 工具,可以从源代码构建出容器。该平台提供一组中间件组件,来构建以源代码为中心且基于容器(能够实现资源伸缩性)的应用。这使得它成为一个颇有吸引力的平台,当有无服务器需求时,值得对其进行评估。

Apache Atlas

随着企业数据需求的不断增长和多样化,对元数据管理的需求也在不断地增长。APACHE ATLAS 是一款用于满足企业数据治理需求的元数据管理框架。Atlas支持元数据类型建模、数据资产分类、数据来源追踪和数据发现。但是,在搭建元数据管理平台的时候,我们也必须小心避免重蹈主数据管理的覆辙。

Cypress

运行端到端测试时经常会遇到一些棘手的问题,比如运行时间过长,测试过于零碎,还需要修复无头模式下运行的测试所导致的 CI 失败。我们的团队借助 CYPRESS 很好地解决了性能差、响应时间长、资源加载慢等常见问题。Cypress 是一款很有用的工具,可以帮助开发者构建端到端测试,还可以将所有测试步骤保存为 MP4 视频,便于检查错误。

VS Live Share

VISUAL STUDIO CODE 是微软推出的免费 IDE 编辑器,可以跨平台使用。我们曾用它同时进行前端 React、TypeScript 和后端 GoLang 的开发,而无需在不同的编辑器之间切换,体验很好。 Visual Studio Code 中的工具、语言支持和扩展插件数量都在迅猛增长,也越来越好用。我们要特别推荐在实时协作及远程结对编程时使用 VS Live Share 。固然微软或 Jetbrains 成熟的 IDE 对使用静态类型语言(如 Java 、 .NET 或 C++ )的复杂项目支持得更好,但我们也发现 Visual Studio Code 正逐渐成为基础设施开发组和前端开发组的首选工具。

Stanford CoreNLP

越来越多的项目需要处理非结构化的数据,而从文本中提取出有意义的业务信息是一项关键技术。 STANFORD CORENLP 是一组基于 Java 的自然语言处理(NLP)工具集,支持英语、汉语和阿拉伯语等多种语言的命名实体识别、关系抽取、情感分析与文本分类,也提供了用于标记语料库和训练模型的工具。 Stanford CoreNLP 协助我们使用NLP 领域的最新研究成果来解决各种业务问题。

LocalStack

使用云服务时面对的一个挑战是如何在本地进行开发和测试。 LOCALSTACK 为 AWS 解决了这个问题。它提供了各种 AWS 服务的本地 测试替身 实现,包括 S3 、 Kinesis 、Dynamodb 和 Lambda 等。它基于现有的最佳工具如Kinesalite 、 Dynalite 、 Moto 等构建,并增加了进程隔离与错误注入的功能。 LocalStack 的使用很简单,并附带了一个简单的 JUnit 运行器以及 JUnit 5扩展。我们在一些项目中使用过 LocalStack ,并对它印象深刻。

Bitrise

构建、测试和部署移动应用,尤其是由一条流水线从代码仓库打通到应用商店的时候,会涉及许多复杂的步骤。虽然这些步骤可以由脚本或普通 CI/CD 工具提供的流水线自动完成,但对于专注移动应用开发,而不需要与后端的构建流水线做集成的小组来说,使用专用工具可以降低复杂度和维护开销。 BITRISE 配置简单,并预置了一组完整的步骤,可以满足绝大多数移动应用开发所需。

PredictionIO

PREDICTIONIO 是开源的机器学习服务框架。无论是普通开发者还是数据科学家,都可以利用它创建用于预测的智能应用。和所有其他智能应用类似,PredictionIO 由三个部分组成:数据收集和存储、模型训练以及模型部署和服务暴露。开发者只需要基于它提供的相应接口实现数据处理逻辑、模型算法和预测逻辑,无需在诸如存储数据以及训练模型之类的事情上投入额外精力。从我们的经验来看,在不要求高并发处理的情况下,PredictionIO 能支持不同大小的数据集。大多数时候我们使用 PredictionIO 来为中小企业构建预测类智能服务,或者在构建复杂定制化预测引擎的过程中进行概念验证。

Q#

量子计算目前已经可供测试,但何时真正到来尚未明确。在硬件到位之前,我们已经可以通过语言和模拟器来实验和学习它。尽管IBM等公司已经取得了不错的进展,我们对微软在 Q# 语言及其模拟器(本地32量子比特,Azure云上40量子比特)方面的工作更加关注。如果你想开始了解这项编程的前景,请查看他们在 GitHub 上的范例。

MockK

MOCKK 是用 Kotlin 编写的模拟库。它的核心理念是像 Coroutines 和 Lambda 表达式一样,为 Kotlin 提供一等公民级别的语言特性支持。不同于 Mockito 或PowerMock 的蹩脚封装,作为原生的开发库,它能帮助开发团队在测试 Kotlin 应用时编写干净、简洁的代码。

WebFlux

Spring Framework 5 已发布一年有余,它采用了响应式流 —— 一套非阻塞背压(backpressure)式异步流式处理标准。在传统的 Spring MVC 模块之外,WEBFLUX 为在 Spring 生态下编写 Web 应用提供了一个响应式替代品。经过一系列应用的试用,WebFlux 给我们的团队留下了深刻的印象,并汇报说这种响应式(函数式)实现增强了代码的可读性和系统的吞吐量。但他们也确实注意到,采用 WebFlux 需要在思维方式上做出一些重大转变,建议在WebFlux vs. Spring MVC 的技术选型中考虑这一点。

Jepsen

随着 微服务 架构越来越多地被采用,相比以前,我们构建了更多的分布式应用程序。尽管解耦架构带来了许多好处,但证明整个系统正确性所需的工作量和复杂程度正急剧增加。 JEPSEN 提供了许多我们所需要的工具,来帮助我们验证协调任务调度程序的正确性,测试分布式数据库的最终一致性、 线性一致性 ( Linearizability)和 可串行性(Serializability)。我们在一些项目中使用了 Jepsen,令人惊喜的是,我们可以测试驱动配置,注入和修复故障,验证系统恢复后的状态。


以上是我们在最新一卷技术雷达中随机摘取的几个Blip,欲获取整版技术雷达,请点击技术雷达官方网站进行下载!

Share

这个夏天,再一次coding with her

“毕竟我们只有这一次结对的机会,一个题目总要善始善终,所以不知不觉就写到了凌晨两点,和小伙伴用git协作,寝室只有我的电脑屏幕发出微弱的光,感觉夜晚如此静谧,而我们的大脑和手指都在激烈又高速运转着,我喜欢这样忘我的感觉。”

再遇见

在参加完第三季ThoughtWorks最佳编程体验之旅活动后,凯欣在自己的博客中写下了这样的回顾,这是她第二次参与最佳编程之旅。同样经过了为期四周的线上编程挑战,同样是从一千多名网申报名者中脱颖而出,最终与其他127名学生一起来到ThoughtWorks位于北京、武汉、西安、成都、深圳五城的根据地体验结对编程。

(第三季最佳编程体验——五城集结)

这次活动从开始报名到最终落幕共历时一个月,大家在其中学会的第一课可能就是——坚持。平心而论,今年的线上题目难度并不高,在题目截止之前,ThoughtWorks工程师还在线上分享过程中“无心插柳”的讲解了考题,并对同学们在这一过程中所遇到的问题进行解答。意在让大家遇到难题时能够选择直视问题、正面出击,毕竟在真实的工作场景中,“退缩”从来都不可取。

但即便如此,仍然有近90%的报名者在两轮线上答题赛中退出。最终,留到最后的128名同学在6月8号聚集在了一起。提到这次相聚,凯欣用了“久违”二字。这其中并不全是怀念,在去年的编程体验中,她算是抱憾而归。在侧重于“交付完整产品”的比赛中,由于纯粹追求设计思想与代码质量,忽视了内部研究,最终与第一名失之交臂,还错失了心心念念的“无人机”奖品。在朋友圈看到活动信息后,她第一时间报了名,想看看今年的玩法会有什么不同。

确认过眼神,遇上对的人

第三季最佳编程体验之旅的主题是“Coding with her”,作为全球最佳女性科技雇主,ThoughtWorks认为在科技领域男性和女性没有差别,在校招过程中也一直坚持男女比例1:1。在第一天的碰面中,同学们就见到了来自ThoughtWorks气场全开的几位小姐姐,她们都是公司内部非常厉害的程序媛,能文能武,可以利落的解决技术问题,也可以很好的兼顾工作与家庭,被内部同事称为“刀马旦”。

初遇“刀马旦”,倾听她们讲述ThoughtWorks的文化理念、职业经历与个人实践,学生们也在这个过程中“确认眼神、找到对的人”,定下后面两天结对编程的coach。凯欣选择了北京办公室的大姐大——禚娴静作为coach,因为“喜欢她的气场,感觉莫名亲切,喜欢投缘的人。”

紧张Coding,快速交付

作为第二次参加的“过来人”,凯欣对结对编程的概念及方法、TDD(TDD是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码)等实践方法都有所了解。在听完讲解、拿到需求后,就迫不及待的想要开始做整体设计。

这时大姐大却提醒她们,要着眼于当下需求,“我们就很听话地从实现第一个需求开始测试驱动开发,我写测试,小伙伴写实现,一路乒乒乓乓,极其尽兴,几乎忘了所有人的存在,沉浸在程序世界无法自拔,不知不觉就到了五点半截止时间,代码还有一点不太完美的地方,纠结要不要继续改,担心犯规什么的,我们俩最后一致决定要完成它,在最后完成所有基础需求的时候,我们给大姐大做审阅,大姐大咔咔咔指出n个不足,最有感触的一句话是:测试要从需求层面写,我当时好佩服啊,架构师就是不一样,一眼就能看出问题,给我们宏观的把握,接受完指点后感觉自己好幸运,那天晚上非常愉快地从大厦出来,和小伙伴一路商讨,回顾大姐大的点评,想到代码有哪些不完美,我们俩就哪哪都不舒服,也顾不上什么规则了,决定晚上回去继续做。”

在为期两天的编程和showcase过程中,大姐大一直守护在身后,对凯欣小组所遇到的问题进行引导。在这个过程中,回答问题并非主要目的,更重要的在于“授之以渔”,让她们拥有解决问题的思路。这不同于课堂上的直线教学,在真实项目中,问题是无法精确预见的,只有解题思路能够常存心中。这也是为什么ThoughtWorks要把最终脱颖而出的学生聚集到一起、让大家去体验真实的开发过程和工作场景。

(凯欣小组)

最终,在最后一天三分钟的showcase过程中,凯欣和小伙伴赢得了在场coach的称赞,并成功拿下“小蜜蜂”奖品。更让她开心的是,这次奖品的设置是从多个角度进行衡量的,——“这和平时的单一评判标准(分数)决定学生好坏的片面评价不一样,衡量一件事就该多方面衡量,每个方面做的出色的同学都该得到鼓励和表扬,这一点就比第二期的活动做的更好, 很走心。”

尾声

6月10日下午,为期两天半的线下结对编程结束,走在回去的路上。凯欣在回味大姐大点评的同时或许也会想到大姐大的开场分享,“我不知道我50岁的时候会在做什么,但是,一想到很可能是在写代码,我就很开心。我也曾经无数次的想过要选择放弃,但是我站在这里就是最好的答案。”


更多精彩洞见,请关注微信公众号:思特沃克

Share

创新,最重要的是信念 | 产品创新读书雷达发布啦!

首先,读书,当然不能保证我们可以做出成功的产品。

不记得在哪里看过说,“读书,其实是为了培养信念”,对于产品创新这件事也是一样。读书,会让我们明白:

  • 有那么多事,值得我们去改变;
  • 原来,我们也能够去改变;
  • 原来有这么些逻辑和方法,可以避免愚蠢的错误;
  • 只要具有钢铁般的意志,终将抵达彼岸。

“我这辈子遇到的来自各行各业的聪明人,没有一个不是每天阅读的——没有,一个都没有。而巴菲特·沃伦读书之多,可能会让你感到吃惊,他是一本长了两条腿的书!”巴菲特合伙人查理·芒格曾这样评价巴菲特。

但我们也不想让大家为读书而焦虑。因此,基于以下的原则,我们筛选出了32本书:

  • 聚焦产品创新主题;
  • Less is More,少就是多;
  • 兼顾格局、视野与实用、落地;
  • 趣味和思想 胜于 全面和细致。

如果你是想尝试产品创新、已经在做产品、或是想在组织里培养更多产品创新者的人,那么下面这份读书雷达或许可以帮到你:

Share

2018年5月期技术雷达正式发布!

ThoughtWorks每年都会出品两期技术雷达,这是一份关于技术趋势的报告,由 ThoughtWorks 技术战略委员会(TAB)经由多番正式讨论给出,它以独特的雷达形式对各类最新技术的成熟度进行评估并给出建议,为从程序员到CTO的利益相关者提供参考。

它比那些我们能在市面上见到的其他技术行情和预测报告更加具体、更具可操作性,因为它不仅涉及到新技术大趋势,更有细致到类库和工具的推荐和评论,因此更容易落地。经过半年的追踪与沉淀,ThoughtWorks TAB(ThoughtWorks技术咨询委员会)根据我们在多个行业中的实践案例,为技术者产出了第十八期技术雷达,对百余个技术条目进行分析,阐述它们目前的成熟度,并提供了相应的技术选型建议。

本期四大主题

浏览器增强,服务端式微

为了实现应用逻辑,浏览器在持续扩展成为部署目标的能力。当平台能照顾好横切关注点和非功能性需求的同时,我们注意到后端逻辑的复杂性有逐步降低的趋势。 WebAssembly 的引入为web应用创建逻辑提供了新的语言选择,同时把处理过程更加推向金属侧(以及GPU)。 Web Bluetooth让浏览器能够处理那些原本是本地应用才能处理的功能,而且我们看到越来越多像 CSS Grid Layout和 CSS Modules这样的开发标准正在替换掉自定义的库。对更好用户体验的追求,正在持续地把功能装进浏览器里,许多后端服务因此变得越来越薄,复杂性也因而降低。

不断蔓延的云环境复杂性

虽然AWS继续凭借令人眼花缭乱的新服务保持领先,但我们逐渐看到 Google Cloud Platform (GCP)和 Microsoft Azure 已经成为可行的替代方案。像 Kubernetes 这样的抽象层以及持续交付和基础设施即代码这样的实践,能支持更容易的演进式变化,从而促进云环境之间的过渡。但随着 PolyCloud (这允许组织根据差异化的功能在多个供应商之间进行挑选)以及越来越多的监管和隐私问题的出现,云策略必然会变得更加复杂。例如,许多欧盟国家现在依法对数据所在地做出要求。这使得数据存储的管辖权和其主机的管理策略成为评估云计算环境的新维度。云计算环境的可选范围也在扩大,比如在“函数即服务”和“管理更长寿命集群”这两者之间,就可以选择提供了“容器即服务”(CaaS) 的 AWS Fargate 这个有趣的选项。虽然各个组织对云技术的应用日臻成熟,但伴随使用这些新技术构建真实解决方案的,是逐渐蔓延又无法避免的复杂性。

信任但要验证

对于几乎所有的软件开发来说,安全问题仍然是至关重要的。当前我们观察到传统的“全局权限管理”的安全策略正在转变为更为细致的本地化方法。现在许多系统会在更小的领域内管理信任,并在不同系统之间使用一些新的机制创建可传递的信任。其理念正在由“永远不信任领域外所有东西”以及“从不验证领域内任何东西”转变为“信任但是需要验证领域内外任何东西”——也就是说可以假设和系统其它部分有本意良好的互动,但一定要在本地验证这份信任。这使得团队可以对自己的基础设施、设备和应用程序栈有高度的权限控制,从而实现高度可视化,并可以在必要时候提供高级访问护栏。类似 Scout2的工具以及 BeyondCorp 这样的技术反映了关于信任更成熟的视角。我们欢迎这种向本地化管理的转变,特别是当工具和自动化策略可以确保同等或更好的合规性时。

物联网的发展

物联网(IoT)生态系统持续稳步发展,关键成功因素包括安全和成熟的工程实践。我们看到了整个物联网生态系统的增长,从设备上的操作系统到连接标准,尤其是基于云服务的设备管理和数据处理。我们看到了一些成熟的工具和框架,支持良好的工程实践,比如持续交付、部署以及为实现最终广泛使用的大量其他必要实践。除了主要的云服务提供商——包括 Google IoT Core ,AWS IoT 和 Microsoft Azure IoT Hub ——像阿里巴巴和阿里云这样的公司也在大力投资物联网 PaaS 解决方案。可以从我们的 EMQ 和Mongoose OS 条目一瞥当今物联网生态系统的主流功能,它们也例证了 物联网 的良好的发展状态。

象限亮点抢先看

要记住,就像适用于其他软件领域一样,封装也同样适应于事件和事件驱动的体系结构。特别是,我们需要考虑一个事件的范围,以及我们是否期望它在同一个应用程序、同一个领域或整个组织中被消费。DOMAIN-SCOPED EVENT将在其发布的同一个领域内被消费,因此我们期望消费者能够访问特定的上下文、资料或引用,进而对事件进行处理。如果这个事件的消费在组织内更广泛地发生,且事件的内容需要有所不同,我们就要注意不要“泄漏”其他依赖领域的实现细节。

身份管理是平台的关键组件之一。外部用户在使用移动应用的时候,需要对其身份进行验证,开发人员需要被授权才能访问基础设施组件,而微服务也需要向彼此证明自己的身份。你应该考虑的是,身份管理是否真的有必要自己来搭建和维护。根据我们的经验,HOSTED IDENTITY MANAGEMENT AS A SERVICE( SaaS)这种解决方案更为可取。我们相信,像Auth0和Okta这样的顶级托管商可以在“正常运行时间”和“安全”两方面提供更好的SLA。也就是说,虽然有时候自行搭建和维护身份管理解决方案是一个现实的选择,特别是对于那些有操作规范和资源的企业来说,这个选择更为安全。但大型企业的身份解决方案通常包含更广泛的功能,例如集中授权、治理报告和职责分离管理等等。不过,这些担忧通常与员工身份更相关,特别是那些受遗留系统限制的企业,尤其如此。

在实践微服务的过程中,为了将后端资源进行聚合,我们实践了一个又一个的模式。之前,我们经常使用类似于Netflix Falcor这样的工具帮助我们实现BFF(Backend for Frontend ),现在很多项目已经开始使用GRAPHQL FOR SERVER-SIDE RESOURCE AGGREGATION。GraphQL可以让客户端直接使用特定的查询语句去访问BFF以获取数据。使用这项技术时,后端服务可以继续暴露 RESTful API,而GraphQL可以轻易的将这些服务所提供的资源聚合在一起,并且对客户端十分友好。我们推荐GraphQL是因为其简化了BFF和其他聚合服务的实现。

在高度分布式的微服务架构中,其可观察性有一个两难问题 —— 要么记录一切,代价是巨量的存储空间;要么随机抽样记录,代价是有可能丢失某些重要事件。最近我们注意到一项技术,它在这两种方案之间提供了一个折衷方案。通过跟踪请求头中传入的某个参数来LOG LEVEL PER REQUEST。使用跟踪框架(可能基于OpenTracing标准),你可以在一次事务中的多个服务之间传递一个相关的ID。还可以在开始事务时注入其它数据(比如期望的日志级别),并且与跟踪信息一起传递它。这样可以确保这些额外数据在系统中总是和相应的单个用户事务一起流动。这在调试时也是个很有用的技巧,因为服务可能会暂停或以逐个事务的方式进行修改。

Headless CMS( Content Management Systems, 内容管理系统) 正在成为数字化平台的常见组件。CONTENTFUL是一个现代化的 headless CMS。我们的团队已经成功把它集成到开发工作流中。我们特别喜欢其“API 优先”的特点,及其CMS as Code的实现。它支持强大的内容建模原语代码和内容模型演化脚本,并允许将其视为其他数据存储的schema,并将演进式数据库设计实践应用到 CMS 开发中。我们所喜欢的其他特性包括:默认包含两个 CDN以提供多媒体资源和 JSON文档,本地化的良好支持和与Auth0集成的能力(尽管需要做出一些努力)。

EMQ是一个可伸缩的开源多平台 MQTT代理。为了追求高性能,它使用Erlang/OTP语言编写,能处理数百万的并行连接。它能支持多种协议,包括MQTT、MQTT传感器网络、CoAP以及WebSockets,使其适用于物联网和移动设备。我们已经开始在项目中使用 EMQ,很享受其安装以及使用的便捷性,以及它能将消息路由到不同目的地(包括Kafka和PostgreSQL)的能力,还有它在监控和配置上所采用API驱动的策略。

TICK STACK是一个由开源组件组成的平台。使用它就可以轻松地收集、存储、绘制基于时间序列的数据(如度量和事件)来触发告警。TICK Stack 的组件包括:收集和报告各种指标的服务器代理telegraf、高性能时间序列数据库InfluxDB、平台的用户界面 Chronnograf,以及可以处理来自 InfluxDB 数据库的流式数据和批量数据的数据处理引擎Kapacitor。不像基于“拉”模型的Prometheus,TICK Stack是基于“推”模型来收集数据的。InfluxDB 组件是该系统的核心,同时也是目前最好的时间序列数据库。虽然这套组件栈基于 InfluxData ,而且需要使用诸如数据库集群这样的 InfluxData 企业版的功能,但在监控方面它仍然是一个不错的选择。我们正在一些生产环境上使用该平台,并且获得了一些很好的体验。

WEB BLUETOOTH能够直接从浏览器控制任意低功耗蓝牙设备。这样以前只能通过原生手机应用来处理的场景,现在也可以适用了。该规范由 Web Bluetooth Community Group 发布,并且定义了一个 API,通过蓝牙 4.0 无线标准发现设备并在设备间通信。 当前,Chrome 是唯一支持这个规范的主流浏览器。借助Physical Web和 Web Bluetooth,现在有了其他途径来让用户与设备进行交互, 且无需让他们在手机上安装另一个应用。这是一个令人兴奋的领域, 值得密切关注。

我们很开心使用 BACKSTOPJS 来做 web 应用的可视化回归测试。作为可视化比较工具,它的可配置视窗和可调节容错能力可以很容易定位到细微差别。它有很优秀的脚本功能,并且可以选择在无界面Chrome、PhantomJS 和SlimerJS 中运行。我们还发现,它在实时组件样式规范的基础上运行时尤其有帮助。

世界上有数不清的问题都可以用数学优化问题来表达,而其中可以用凸问题来描述的那部分常常能够得到有效解决。CVXPY便是一种针对凸优化问题所开发的开源Python嵌入式建模语言。它由斯坦福大学的学者维护,已经为数个开源和商业解决方案提供了功能齐备的安装套件。它的文档中也包含了许多能够引起开发者使用兴趣的例子。尽管有些时候,我们仍然需要类似Gurobi和IBM CPLEX这类商业解决方案,但CVXPY在原型设计阶段可以说所向披靡。在多数情况下,有CVXPY就足够了。同时,基于最近的优化进展,其开发者一直在为我们提供更多的扩展包(例如DCCP)和相关软件(例如CVXOPT)。

HELM是Kubernetes的包管理器。共同定义某个应用的Kubernetes资源集合被打包成图表。这些图表可以描述单个资源,例如Redis pod,或者全栈的Web应用程序:HTTP服务器、数据库和缓存。Helm 默认带有一些精选的 Kubernetes应用,维护在官方的图表仓库里。想要为内部用途搭建私有的图表仓库也很容易。Helm有两个组件:一个是称为Helm的命令行工具,另一个是称为Tiller的集群组件。保护Kubernetes集群是一个宽泛而微妙的话题,但我们强烈建议在基于角色的访问控制(RBAC)环境中搭建Tiller。我们在很多客户的项目中使用了Helm,它的依赖管理、模板和钩子机制极大地简化了Kubernetes中应用程序的生命周期管理。

ARCHUNIT是用来检查架构特征的Java测试库,比如包与类的依赖关系、注解验证、甚至层级一致性。它可以在你现有的测试方案中,以单元测试的方式运行,但目前只能用于Java架构。ArchUnit测试套件可以合并到C(I 持续集成)环境或部署流水线,使我们很容易地以演进式架构的方式实现适应度函数。

Hyperledger项目现在已经发展成包含一系列子项目的大工程。针对不同业务需求,可以支持不同的区块链实现方式。例如,Burrow专门用来实现带权限控制的Ethereum,而Indy更专注于数字身份。在这些子项目中,Fabric是最成熟的一个。当开发者们谈到使用 Hyperledger 技术时,实际上大多数时候是在考虑 Hyperledger Fabric。然而,chaincode的编程抽象相对底层,因为它直接处理账本的状态数据。此外,在编写第一行区块链代码之前,搭建基础设施也经常耗去很多时间。HYPERLEDGER COMPOSER 构建于Fabric基础之上,加速了将想法实现为软件的过程。Composer 提供 DSLs 来建立业务资源模型、定义访问控制和构建业务网络。使用 Composer,可以在不搭建任何基础设施的情况下,仅通过浏览器来验证我们的想法。需要明确的是,Composer 本身并不是区块链,仍然需要把它部署在 Fabric 上。

RASA是聊天机器人领域的新成员。 它并非使用简单的决策树,而是通过神经网络将用户意图和内部状态映射到回应上。Rasa 集成了自然语言处理解决方案(spaCy)。与技术雷达中的其他同类工具不同,Rasa是开源软件,可以自行托管,对于担心数据所有权的使用者来说 Rasa 是一个可行的方案。我们在内部应用中使用了Rasa Stack,效果良好。

RIBs即路由器(Router)、交互器(Interactor)和构建器(Builder)的缩写, 是来自 Uber 的跨平台移动架构框架。RIBs的核心思想是将业务逻辑从视图树中分离出来,从而确保应用程序由业务逻辑驱动。 可以将其看作是Clean Architecture模式在移动应用程序开发领域的一次应用。通过在原生 Android 和 iOS 应用上使用一致的架构模式,RIBs为应用提供了清晰的状态管理模式和良好的可测试性。尽管我们一直建议尽量将业务逻辑放在后端服务,不要将其泄漏到前端视图中,但移动应用程序非常复杂,RIBs可以帮助管理这种复杂性。

REACTOR是一个基于Reactive Streams规范的、用于开发非阻塞式应用程序的 JVM 库,支持 JVM 8 及以上版本。响应式编程强调将命令式逻辑转换成异步、非阻塞和函数式风格的代码,特别是在处理外部资源时。Reactor 实现了 Reactive Streams 规范,并且提供了两个不同的发布者API:Flux (0 到 N 个元素) 和 Mono( 0 或 1 个元素),可以高效地对基于推送的流处理进行建模。Reactor 项目非常适合微服务架构,并且为HTTP、WebSockets、TCP和UDP等提供了支持背压(backpressure)的网络引擎。

以上是我们在最新一卷技术雷达中随机摘取的几个Blips,欲获取整版技术雷达,请点击这里

Share