前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >软件架构预述

软件架构预述

作者头像
张逸
发布2023-03-23 16:00:30
3060
发布2023-03-23 16:00:30
举报
文章被收录于专栏:斑斓斑斓

《软件架构编年史》

作品连载

《软件架构编年史》是Herberto Graca的系列作品,我在ThoughtWorks的同事覃宇在征得作者同意与授权后,在简书陆续发布了该系列的译文。该系列回眸了软件架构的发展历程,对主流的架构模式与设计方法进行了系统的梳理和介绍,可以作为架构师的入门读物。

我见之心喜,认为这样的好文章不可错过,赶紧联系覃宇兄,得到了他的授权,允许在我的公众号「逸言」上首次发布这一高价值的系列文章。

从2021年3月11日开始,每周一、周四的上午九时,我会准时发布《软件架构编年史》的系列文章,借此机会感谢Herberto Graca和覃宇的无私奉献!

覃宇,(曾经的)Android开发者/ThoughtWorks技术教练//译者,热衷于探究软件开发的方方面面,从端到云,从工具到实践。喜欢通过翻译来学习和分享知识,译作有《Kotlin实战》、《领域驱动设计精粹》、《Serverless架构:无服务器应用与AWS Lambda》和《云原生安全与DevOps保障》。

这篇文章是软件架构编年史(译)的一部分,这部编年史由一系列关于软件架构的文章组成。在这一系列文章中,我将写下我对软件架构的学习和思考,以及我是如何运用这些知识的。

在这篇文章中,我将总结一些关于软件架构的最基本的概念,了解它们才能更好地理解后续的文章。

◐ 没有银弹

无论你如何理解我在软件架构编年史(译)中谈到的内容,首先要理解的是没有银弹,没有“普适性”的解决方案。尽可能地了解不同的方法,理解每一种方法的优劣,和它们解决的特定技术问题。

然后,当接受新的挑战时,先从理解业务和最终用户的需求开始。在搞清楚这些需求之后,你才能思考应该采用哪些架构风格和模式来更好地解决这些问题。

最后,自己做出选择,是实现一种已知的解决方案,还是创造适合自己的特定问题的独特设计。

有些架构风格号称是所有形式的软件的“银弹”。然而,优秀的设计这应该选择最符合解决特定问题需要的风格。——Roy Fielding, 2000 [1]

◐ 术语

在软件开发的世界中使用的术语很多都模棱两可,因此,我必须澄清一些我使用的术语的含义,然后继续。

功能性(Functional)

在应用中纯粹发挥技术作用的代码片段、方法、类、类的组合。它们和(业务)领域无关,仅仅代表应用中的一种技术能力。例如:

  • 层次(Layer)
  • 工厂(Factory)
  • 资源库(Repository)
  • 值对象(Value Object)
  • 视图(View)
  • 视图模型(ViewModel)

概念性(Conceptual)

在应用中标识一个(业务)领域概念的代码片段、方法、类、类的组合。它们和领域相关,代表应用中的一种业务能力。例如:

  • 用户
  • 产品
  • 库存管理
  • 产品变体
  • 结帐
  • 销售

这种划分并不是说一个代码单元不能同时具备两种能力(功能性和概念性)。例如,“Money”对象可以表示一个领域概念,同时也被设计成一个值对象。如果我把它当成领域概念,我指的就是领域内的金钱概念,但如果我涉及的是这个类中的功能性方面时,我指的就是值对象的技术特性(没有ID、可以是不变的等等)。

包(Package)

划分在一起的类组成的集合,理想情况下遵循一组规则进行划分。

模块(Module)

我使用Software Architecture in Practice[7]给出的定义,模块就是一个功能性包,它体现了应用中的一种技术能力。它是解耦的并且能够被其他的实现替换。我的理解是,模块即存在与较低的粒度级别,比如,“安全模块”或者“ORM”,也可以存在于像客户端和服务器这样的应用块。模块提供的是功能性内聚。

组件(Component)

我使用Software Architecture in Practice[7]给出的定义,作者将组件定义为一个代表业务能力的概念性包。理想情况下,它也是和其他组件和模块解耦的。例如“用户”、“产品”或“结帐”。

然而,最重要的是要记住,理想情况下,它代表了一个限界上下文(Bounded Context)。组件提供了概念性内聚。

应用(Application)

我将面向用户的代码即 UI 视为应用,它建立在组件之上。例如,我们可以基于一组组件构建网络商店。不管怎样,这个网络商店会提供一个(店面) UI 让用户浏览和购买商品和另一个(管理) UI 让商店管理员管理商品、库存、支付供应商,等等。这是在同样的业务组件之上构建的两个独立的应用。

系统(System)

我认为系统是一组以某种方式在一起工作,为各种企业必需品提供功能,形成一个企业范围内的系统,即企业应用。这些应用可能构建在相同或不同的组件上。在之前网络商店的例子中,系统就是作为一个整体的网络商店,包括两个基于同样业务组件构建的两个应用(店面和管理),还有其他像支付供应商或货运供应商这样的第三方应用。

架构(Architecture)

软件架构的简单定义有很多,我觉得都不错,但我认为理解它是什么很简单,而更重要的是,定义架构的产出,它应该给项目带来什么。

软件架构[…]是系统需要考虑的一组结构,它们包括软件元素和它们之间的关系,以及这些元素和关系的属性。—— Clements et al, 2010 [6]

下面是我考虑架构的方面:

  • 横跨所有特性开发的技术决策,例如,框架、代码标准、文档、流程,...;
  • 这是存在于项目中的一组很难在后期改变的技术决策 [3];
  • 它是系统的全景图[5]:pp.2,粗略的描绘,结构,组件及其关系[4] [6];
  • 它使项目做好变化的准备[5]:pp.30,常常是将决策推迟到最后允许的时刻[5]:pp.32;
  • 它让项目做好重用组件和模块的准备[7]:pp.29–35;
  • 它制定出结果的一致性标准并建立轻量的流程,比如编码规范、开发阶段、持续交付和持续部署;
  • 它不是某一个人的职责,而是由来自项目中不同特性团队的开发者组成的行会的职责。

如果你不熟悉行会的概念,可以观看下面关于Spotify 工程师文化的视频:

Spotify Engineering Culture part 1

Spotify Engineering Culture part 2

视频链接请点击文末“阅读原文”,在原文中打开视频。

架构师(Architect)

他是由行会讨论和决定的架构的发起人和守护者。他是部门/团队中经验最丰富的开发者之一,恰好承担着分析高层次问题和解决方案的额外职责。在做出架构决策时,他还拥有“质量票”(He also benefits from a “quality vote” when making an architectural decision.)。

可是,有一点值得注意,所有开发者某种程度上都是架构师,因为他们都要了解架构,他们都会议某种形式参与架构,他们都适当地承担着维护架构的职责。

象牙塔架构师(Ivory Tower Architect)

有一种架构师会做出和架构有关的所有决定,这种万能的象牙塔架构师是一种架构师的反模式。他对其他干系人对架构的贡献既不开放,也不轻易接收,而是阉割了这些贡献。

◐ 架构的坏味道 [8]

僵化(Rigidity)

如果软件难以修改是因为修改会导致更多关联修改,软件就是僵化的。它就会变成兔子洞:当我们以为修改快要完成时,突然发现还有更多的代码需要修改,把我们拉进无止尽的轮回之中。

脆弱(Fragility)

脆弱的软件在修改时,总会出现意料之外的、毫无关联的、无法预测的错误。

牢固(Immobility)

如果设计包含一些可以在其它系统中使用的部分,但将这些部分从原系统中分离出来需要大量工作甚至带来许多风险,我们就说设计是牢固的。

粘滞(Viscosity)

在一个粘滞的系统中,要做对困难重重,要做错却轻而易举。这意味着通过正常开发实现变更不如用非常手段来得容易。

如果执行单元测试和/或编译需要耗费很长时间,开发很可能导跳过这些过程,不跑任何自动化测试就实现非常规的修改,这就是系统范围的粘滞。

不必要的重复(Needless repetition)

当时间不够或经验不足导致必要的抽象缺失时,就会产生不必要的重复。这些代码也许并不是直接复制粘贴造成的重复,而是由在不同地方重复定义的相同业务规则带来的。

晦涩(Opacity)

代码写得混乱,难以理解,我们需要深人方法实现的细节才能搞清楚代码要干什么。

不必要的复杂(Needless complexity)

开发者采用了多种不同的抽象和未来潜在变化的应对措施,来积极地避免其他六种坏味道。良好的软件设计是轻量灵活的,理解起来更容易,最重要的是修改更容易,因此不必预判所有未来的潜在变化。

¶ 引用来源

[1] 2000 – Roy Fielding – Architectural Styles and the Design of Network-based Software Architectures

[2] 2000 – Robert C. Martin – Design Principles and Design Patterns

[3] 2006 – Booch, in [5 pg.2]

[4] 2007 – IEEE1471 in [5 pg.2]

[5] 2010 – James Coplien, Gertrud Bjornvig – Lean Architecture

[6] 2010 – Paul Clements, Felix Bachmann, Len Bass – Documenting Software Architectures

[7] 2012 – Len Bass, Paul Clements, Rick Kazman – Software Architecture in Practice

[8] 2014 – M. H. Jongerius – THE SEVEN DESIGN SMELLS OF ROTTING SOFTWARE

[9] 2017* – Wikipedia – Software Architecture

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 逸言 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档