维护软件架构的动态特性

一些Microsoft Office案例研究

演化成熟的复杂产品的一个关键挑战是随着新功能的添加,随着时间的推移保持核心架构支柱。 这些体系结构的支柱包括设计的静态元素(关键数据结构和类层次结构的设计)以及设计的动态特性,即代码在实践中的实际执行方式。 我经常发现,随着时间的流逝,动态特性很难维护。

静态组件本质上更易于理解和描述。 您可以查看代码并了解数据结构和用于修改它们的算法。 对于动态特性,您需要查看并了解运行时行为。 在某些情况下,团队会努力设计软件,以确保在进行新开发时不会使运行时行为约束无效。 例如,随着时间的推移,Microsoft Office开始越来越频繁地使用的一种方法是使用线程边界和异步编码模式来严格分离组件。 这些线程设计仍然具有复杂的运行时特性,例如资源管理和拥塞控制,但这些异步技术有助于使运行时设计更加明确和易于维护。

或者,许多产品都使用了诸如空闲时间工作的分块之类的技术,这些技术往往难以维护。 在这种方法中,工作被分解为小块,可以在程序空闲时执行,通常与所有其他UI活动在同一线程上执行。 该程序执行一小部分工作,然后希望返回到处理用户输入,而没有任何可检测到的延迟。 这简化了线程协调(因为所有关键工作都发生在单个线程上),并且在线程甚至没有作为OS概念存在之前就已被使用。 这种方法所面临的挑战是,要使代码有效,程序员需要确保分块的许多微妙属性:确实需要将分块保持较小,以确保UI不会延迟,分块的成本必须较小,因此存在执行一些基本计算的开销并不合理,并且重新启动块的开销必须很小,这样程序才能真正有效地完成工作。 请注意,将块保持较小和粒度的目标通常与保持块分离的开销较小的目标直接冲突。 这些是代码的动态特性,需要代码库以更加分散的方式进行维护。

作为一个复杂代码库的示例,Word 2016可以管理70多个空闲时间活动-所有这些都没有引入任何可检测到的UI延迟。

显然,大多数团队还使用诸如广泛的性能基准测试之类的工程实践,以明确衡量运行时行为的一个方面。 这很重要,但在设计和实现过程中必然是下游的。 与早期的桌面应用程序相比,现代应用程序(客户端和服务)还大量使用运行时遥测。

我有很多示例,这些示例打破了这些隐式动态假设时会出现问题。 Word中一个有趣的案例要求更改已有20多年的核心数据结构。 Word中的核心内部数据结构之一是“ plex”,它基本上是结构的可扩展数组(即,随着您插入或删除新元素,该数组会增长或收缩)。 该数据结构的实现使用一种通用方法,其中分配的大小可能大于实际使用的大小。 实际上,在数组末尾保留了空白空间,因此可以以非常便宜的价格在末尾插入(或删除)新元素(包括将需要重新分配新数组并复制现有元素(如果已分配的话)复制的摊余成本在内)超出大小)。 将数组随机删除或插入到数组中是相对昂贵的操作-O(N),因为需要复制元素以压缩开放插槽或为新插槽腾出空间。 Word的核心行为是这种操作不必经常发生。 特别是,加载文档以批量或线性方式填充了各种plex数据结构,并且在文档的一个位置上具有较高局部性进行编辑并不需要进行重大调整。

添加HTML加载后,动态用法发生了变化。 最初加载了文档,然后对文档进行了进一步遍历,结果导致在描述格式的各种plex结构中发生了许多插入和删除操作。 实际上,您有一个O(N)算法被执行了O(N)次-或O(N²)运行行为。 最初错过了这个问题,因为对于相对简单的HTML,N很小。 随着Word开始处理更复杂的HTML文档(尤其是在Outlook的HTML邮件组件的上下文中),N变得越来越大,性能也因此受到影响。

我有一个直觉,即空缓冲区可以更好地解决动态使用模式。 我之前已经写过间隙缓冲区,但简要地讲,它是可扩展数组的另一种实现,它允许在数组中的任何位置出现空白空间,并且如果访问模式表现出良好的局部性,则支持在数组中的任何位置进行廉价的插入和删除操作。 在完成工作之前(实际上是其他人完成了最后的实现),我在plex数据结构中添加了遥测功能,并验证了实际上访问模式具有很高的局部性。 我们将plex转换为间隙数据结构。 它的动态用法仍然有非常隐含的约束,但是可以更好地处理更广泛的动态模式,包括Word的HTML加载代码所使用的模式。

文档应用程序中的另一种常见架构模式是设计算法,该算法相对于用户编辑操作的成本而言是递增的,而不是根据整个文档的大小进行缩放。 应用程序设计人员努力工作以确保他们限制处理,因此当用户进行少量编辑时,他们只会做少量工作。 这是保持良好响应能力的关键,对于整体功耗和电池寿命也很重要。

Excel中的一个示例是在任意编辑后如何确定在屏幕上绘制的内容。 它从一个已知的左上角单元格开始,然后可以逐步遍历列宽和行高,直到屏幕被填满。 该算法根据屏幕的大小(边界良好)缩放,而不是根据工作簿的大小(可能很大)缩放。

将Office Art形状添加到Excel中增加了一种扭曲。 形状固定到特定的单元格,但是可以从该单元格位置应用任意偏移。 其结果是,在任意用户编辑之后,Excel确实需要检查锚定在工作表中任何位置的每个单个形状的位置,以确定它是否与当前视口重叠。 这违反了视图构建过程的基本增量,因为该工作随用户内容的大小而缩放。 在实际使用中,形状的数量往往很少,因此可以(通常)快速计算出形状。 但实际上,从根本上违反了动态建筑设计。 随着时间的流逝,出现了用例,这些用例涉及具有大量Office Art形状的文档。 编辑这些文档将变得非常缓慢(即使在具有形状的区域之外操作时)。 最终,Excel需要扩展如何集成形状的设计,以确保它们具有确定视口重叠的更快增量方式。

这也是一个有趣的案例研究,因为Office Art确实是以PowerPoint为核心设计点/模型而产生的,并且PowerPoint可以利用其强大的幻灯片边界以Excel无法提供的方法提供一定程度的增量更新。 我们经常发现,在维护动态约束时,一些最困难的挑战是在集成最初分别具有不同约束的大型组件时。

只允许增加一定数量的过程(相对于用户输入而言)的约束特别容易受到违反。 如果一项新功能不仅仅适合现有的设计模式,那么它通常需要对核心数据结构和算法进行非平凡的扩展才能提供支持。 团队需要应对的一个常见工程模式是,设计和实现该功能的初始非增量版本,其目的是“我们将在以后再进行递增”。 由于增量设计可能是整体功能中最困难的部分,因此这很少是一个好方法。 当我们无法开发出一种经济有效的方式来实现增量更新时,我已经明确删除了“有效”的功能。

在团队内部,需要进行的培训和学习的重要部分是确保动态约束与核心数据结构的静态设计一样被理解。 从根本上来说,动态特性很难理解和维护,因此需要付出额外的努力以确保整个团队都具有深刻的理解。 在最好的情况下,存在严格的测试(例如性能测试),这些测试专门测试动态约束是否继续得到满足。 当验证的完整性很大程度上取决于所操作的数据集的特征时,这尤其具有挑战性(如上述示例中所示)。

From: https://hackernoon.com/maintaining-dynamic-characteristics-of-software-architecture-228820e1d727

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值