软件开发团队发现,如果他们尽可能频繁地集成他们的工作,他们的生活会容易得多。他们还发现频繁发布到生产中是有价值的。但是团队不想向他们的用户公开半开发的特性。处理这种紧张关系的一个有用的技术是构建所有的后端代码,进行集成,但不要构建用户界面。该功能可以集成和测试,但用户界面会一直保留到最后,直到它像基石一样被添加到……。
此技术的一个简单示例可能是为客户提供紧急订单的选项。这样的订单需要定价,这取决于客户的居住地和在那里运营的快递公司。所涉货物的性质会影响仓库中使用的拣货方式。某些客户可能有资格获得紧急订单,这也可能取决于送货地点、一年中的时间和订购的商品类型。
总而言之,这是一个相当不错的业务逻辑,特别是因为它将涉及到与各种仓储、目录和客户服务系统的粗暴集成。这样做可能需要几周的时间,而其他功能需要每隔几天发布一次。但对于用户而言,紧急订单只是订单上的一个复选框。
为了使用复选框作为基石来构建它,团队在几个生产版本的过程中对底层业务逻辑和内部系统的接口进行开发工作。用户不知道所有这些潜在的代码。只有在最后一步中,才需要使Keystone复选框可见,这可以在相对较短的时间内完成。通过这种方式,所有潜在的代码都可以集成在一起,并成为投入生产的系统的一部分,从而减少了长生命周期带来的问题……。
潜伏的代码确实需要以与其处于活动状态时相同的置信度进行测试。如果设置了系统的体系结构,以便大多数测试不通过用户界面完成,则可以做到这一点。单元测试和测试金字塔的其他较低层应该很容易以这种方式运行。即使是广泛的堆栈测试也可以运行,只要有一种机制可以使它们成为皮下测试。在某些情况下,UI本身会有大量的行为,.。
并不是所有的应用程序都是这样构建的,它们可以通过皮下方式进行广泛的测试-但即使没有使用Keystone的能力,这样做所需的努力也是值得的。通过UI运行的测试设置起来总是比较麻烦,即使使用最好的自动化工具也是如此。将更多的测试转移到皮下和更低级别的测试,特别是单元测试,可以极大地加快部署管道并实现持续交付。
当然,大多数UI不仅仅是一个复选框,尽管它们通常对Keystone来说并不是太多的工作。在Web应用程序中,一个复杂的功能通常是一个独立的网页,可以完整地构建和测试,而Keystone只是一个链接。桌面可能有几个屏幕,其中Keystone是使它们可见的菜单项。
也就是说,在某些情况下,UI不能打包成一个简单的Keystone。如果是这种情况,那么就是使用功能切换的时候了。然而,即使在这种情况下,通过确保功能切换仅适用于UI,考虑Keystone也是有用的。这避免了在后端代码中散布大量的切换点,降低了应用切换的复杂性,允许使用简单的切换机制,并且在时机成熟时更容易删除。
最后开发UI有一个普遍的危险,即后端代码的设计方式可能一旦构建就不能与UI一起工作,或者UI直到很晚才得到它所需的关注,从而导致缺乏迭代和糟糕的用户体验。出于这些原因,Keystone方法在鼓励通过薄薄的垂直切片构建产品的整体方法中工作得最好,这将导致快速发布小但完全有效的特性。
我在这里使用了用户界面的例子,当然,同样的方法也可以用于任何其他界面,比如API。通过最后构建消费者的界面,并保持它的简单性,我们可以在小块中构建和集成甚至大的功能。
黑暗启动是一种变体,新功能一旦构建就会被调用,但不会向用户显示任何结果。这样做是为了衡量对后端系统的影响,这对某些更改很有用。一旦一切正常,我们就可以添加拱心石了。
我第一次看到这项技术的基石的比喻是在肯特·贝克的“极限编程解释”第二版中。皮特·霍奇森、布兰登·达夫和斯特凡·史密斯提醒我,我忘了这一点。