首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

软件架构风格

软件架构是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。软件架构会包括软件组件、组件之间的关系,组件特性以及组件间关系的特性。软件架构可以和建筑物的架构相比拟。软件架构是构建计算机软件,开发系统以及计划进行的基础,可以列出开发团队需要完成的任务。

软件架构是在软件的基础架构上进行决策,决定后再做修改的代价很大。软件架构中的决策包括在软件设计时的一些特殊结构性选项,例如要控制太空船登陆艇的系统需要快速而且可靠,因此需要选择适合实时计算的语言,而且为了满足可靠度的需求,程序需要有数个冗余的复本,各复本运作在不同的硬件上,以便比对各程序的结果。

将软件架构文档化有助于和项目关系人之间的沟通,在高层设计时就可以提早进行决策,也可以在各项目之间复用设计组件。

软件体系结构是构建计算机软件实践的基础。与建筑师设定建筑项目的设计原则和目标,作为绘图员画图的基础一样,软件架构师或者系统架构师陈述软件架构以作为满足不同客户需求的实际系统设计方案的基础。从和目的、主题、材料和结构的联系上来说,软件架构可以和建筑物的架构相比拟。一个软件架构师需要有广泛的软件理论知识和相应的经验来实施和管理软件产品的高级设计。软件架构师定义和设计软件的模块化,模块之间的交互,用户界面风格,对外接口方法,创新的设计特性,以及高层事物的对象操作、逻辑和流程。

软件架构师与客户商谈概念上的事情,与经理商谈广泛的设计问题,与软件工程师商谈创新的结构特性,与程序员商谈实现技巧,外观和风格。

软件架构是一个系统的草图。软件架构描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。在面向对象领域中,组件之间的连接通常用接口来实现。

软件架构的范围有许多不同的定义:

巨观系统架构:这是指高阶的软件系统抽象化,其中包括了许多的组件(component),以及描述各模块之间关系的“连接器”(connector)。

重要的东西,无论是什么都可以:这是指软件架构师需要根据项目判断,哪些决策对系统以及项目关系人有高度影响。

了解系统环境的基础。

一些人们认为不容易改变的事务:设计架构是在软件生命周期一开始就要进行的,软件架构师需专注在一些“一开始就要正确”的决策,依照这个思路,若有些问题是可逆的,软件架构上的问题就可以转换为非架构性的问题。

许多的架构设计决策:软件架构不能只考虑许多的模型及结构,也要考虑造成这些特殊结构的决策,以及背后的原因。此见解引发了大量有关软件架构知识管理的研究。

在软件架构、设计、需求工程之间,没有具体明显的分界。这些是“一连串意图的结合”,从高阶的设计意向到低端的设计细节。

整体与分布式定义

当我们谈论单体或分布式架构时,我们指的是应用程序的部署类型,也就是说,应用程序应该作为一个整体部署,以单一方式(单体)部署,还是部署多个孤立的工件独立(分布式)?作为开发人员,我一直认为分布式架构是单体架构之后的一种解决方案。随着时间的推移和应用程序用户的增加,需要隔离代码的某些部分,因为它们会使其余部分崩溃。我没有错,但这不是到达那里的唯一途径;此外,可能必须从某些分布式架构开始,以满足不同的需求,例如安全性、弹性和法律问题 ,尽管这并不常见。

软件架构风格

单体架构

这种软件架构风格具有重要的好处,尤其是在启动域处于非常早期阶段并且上下文之间的界限非常模糊的应用程序时。需要记住的重要一点是,无论应用程序投入生产多长时间,都必须对域进行更改。这不是可以遗漏的东西;我们必须尽可能频繁地更新我们的实现以忠实地代表领域,没有任何架构可以免于此。

单一软件架构风格可以带来的好处是可以更快地进行更改。这并不意味着使用分布式架构就无法做到这一点;我们正在谈论它所花费的时间和这样做时的安全性(这意味着开发成本)。在开发层面,它在初始阶段也简化了很多,只谈论单一语言的单一存储库。

在部署级别,它有点复杂。在应用程序的早期阶段,简化部署可以更加专注于领域。如果在这个阶段引入微服务,你将不仅要处理领域,还要处理随之而来的所有基础设施。但是,随着应用程序的增长,由于安全问题,部署往往会随着时间的推移而变慢和间隔开。例如:在电子商务中,想要更改产品列表的一小部分意味着不仅要部署该部分,还要部署其余部分,包括结账系统或其他更重要的部分,以避免提供好处的东西被一个微小的变化破坏,在低流量时段将几个小的变化归为同一个变化。

在可扩展性层面,我认为与部署相同;在早期阶段,在收集指标时平均扩展整个项目,以便稍后可以看到项目的哪一部分需要或多或少地扩展 。随着时间的推移,会发现没有必要扩展整个项目;产品列表很可能比结帐或用户个人资料页面访问次数更多,因此我们可以在部署此应用程序时考虑进行一些更改。

分布式架构

当我们谈论分布式架构时,我们指的是这样一种应用程序,其中模块独立部署,与其他模块隔离,并且它们之间使用远程访问协议(例如,HTTP、grpc、队列等)进行通信。

它们因其可扩展性和可用性等因素而广为人知。性能通常是它们的强项之一,尤其是取决于服务的粒度。此外,这种架构通常非常依赖最终一致性,因此事件是一种广泛使用的服务间通信方式。这意味着通过不等待我们向其发送消息的服务的响应,我们可以更快地处理我们收到的请求。

发送事件为服务之间的通信开辟了广泛的可能性,但我们仍然需要服务之间的交易。这就是分布式架构的弱点之一:分布式事务。

分布式事务的替代方案是 ACID 事务,根据我们定义服务的方式,这是不可能实现的。在基于服务的架构或微服务中,它更受领域驱动 (DDD),服务更粗粒度,事务将是 ACID(如果不是,则很可能是设计问题)。而在其他架构中,例如 EDA,事务将是分布式的,我们将需要额外的部分(例如 SAGA、2PC)来完成事务,无论是否令人满意。如果任何部分发生故障,则必须补偿其余部分。

何时使用单体架构或分布式架构

虽然这是一个被问得很多的问题,但答案永远是“视情况而定”,因为每个项目都会有不同的要求,并且根据这些要求做出决定,但这不是应该做出的决定很快,它需要一定的标准、经验和考虑。

正是在这里,开发人员发挥了重要作用,并且能够从另一个角度(更全球化的角度)看待项目。开发人员总是倾向于在我们的日常工作中考虑更多,而不是长期考虑;我们将根据我们的经验和知识做出决定,或者仅仅通过学习,跟随炒作的潮流。能够将注意力转移到项目上的开发人员将做出该决定。他们将根据业务需求定义应用程序的特征,无论是显式的(他们将出现在电视广告中)还是隐式的(这是电子商务,例如销售、黑色星期五等) ; 他们将评估不同的架构及其权衡,并决定哪一个更方便。

也就是说,正如我们已经提到的,单体架构通常是好的,除其他因素外,因为它易于更改,这就是为什么它是你开始开发时推荐的架构。这并不是说不应该考虑将来隔离单体应用的特定组件的可能性。

我们通常所说的软件架构风格,指的是顶层风格,即定义第一层的架构。一个明显的例子是模块化整体架构,在顶层,我们看到一个整体组件被划分为按域分隔的模块。尽管如此,如果我们放大每个领域,我们会看到清晰识别的分层架构,这将通过技术组件(表示、领域或基础设施等)将层分开。

模块化单体

巨石还是“大泥球”?

经常会遇到“单体”受到严厉批评的项目。当你更深入地研究这个项目时,你会意识到批评并不是针对架构的类型,而是针对所谓的“缺乏”架构,即“大泥球”。

这导致妖魔化建筑,这是不应该落入主观性的东西。关于整体架构是否适合项目的决定应该通过重要的论据做出,权衡废弃架构和将要引入的架构的所有权衡。

事实上,从主观上讲,单体架构已经失去了很多重量,这导致了完整的项目重组,从大泥球转移到选择的架构、微服务,将我们带到了一个被称为“分布式大泥球”的新架构. 不用说,将有专门的团队专门负责此,在进行此类重组时停止(或试图)业务。

我们不仅没有解决任何问题,反而让系统变得更加复杂,不仅难以修改,而且在此过程中增加了更多的故障点和延迟,还有一个稍微大一点的 DevOps 团队。

更好的方法是以更直接的方式攻击“大泥球”,同时通过遵循某些模式来提供业务价值,这些模式将帮助我们以更健康的方式迁移到另一种架构。

结论

缺乏对架构的关注导致许多公司做出并非最佳的决策。即使他们会工作,他们也不会像他们应该的那样工作。马克理查兹曾说过:“建筑没有错误的答案,只有昂贵的答案。” 而且他是绝对正确的:当基于单一问题而不是从全局的角度来做出决策时,结果并不像预期的那样。

项目会取得进展,但对业务的交付会一点一点地变慢,导致“团队”之间的摩擦,直到达到无法返回的地步,向项目交付价值将无法承受,并且可能会重写需要考虑,包括这一切。

以下是我的一些结论:

如果性能是要考虑的功能或基于我们代码的不稳定性的耦合级别,则根据响应延迟或吞吐量等指标尽可能客观地做出决策。

通过书籍、文章或与同事的简单对话,阅读或聆听他人的经验。

对我来说,最重要的是自我批评,把自我放在一边;最有可能的是,错误不在于我们如何部署代码,而在于糟糕的设计。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230220A01MEA00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券