软件开发架构模式浅谈:一些思考和实践记录

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介: 在由不同开发人员持续迭代、进行功能升级的软件开发活动中,如何保障具有复杂逻辑的商家经营工具的产品质量呢?

image.png

作者 | 思禽
来源 | 阿里技术公众号

一 背景和问题

我个人平时会比较慎用“架构”这个词

  • 一方面是觉得业界有很多架构大师和架构模式,而我的认知和实践有限;
  • 另一方面是因为这个词看着挺高大上、有点务虚,如果不结合实际场景的具体问题来讨论,容易陷入“PHP是最好的语言”这样的辩论赛中。而不同场景中又有各自的问题,程序员们通过自己的理解和思考、针对实际场景对一些架构模式进行了扩展实践,以此来解决遇到的问题,也会基于同一个模式延伸出一些派生概念。

兵无常势,水无常形。所以,我个人的观点是:以要解决的问题为出发点,去讨论我们要采用的架构模式(技术方案)。

另外,由于我们是站在很多巨人肩膀上的,讨论时可以站在一些如SOLID等软件设计/开发原则的基础上。

写这篇文章,我也是从解决一些问题的目的出发的:

  1. 最近和团队同学讨论了相关话题,虽然大多数同学在实践上基本一致,但具体到话术、名词概念和具体使用的理解和实践上有些差异(这是很正常的,因为业界对同一个模式的理解和实践也不同)。我结合一些实际编码场景做了一番陈述,为了避免后续重复大费口舌,所以打算写下来,以后有需要直接发文章链接。
  2. 由于我个人的认知和实践有限,所以也希望能抛(huan)砖(ying)引(lai)玉(pen),让我学到更多。
  3. 虽然同一个架构模式在不同业务/技术领域的实施会有区别,但同一个团队内应该保持一致性,因为这样有助于日常的code review、功能模块的交接backup等活动,尤其是有利于使用统一的单测建设方案来保障我们的产品质量。
  4. 实际问题:我最近在开发商家合并发货的功能,但由于之前基础发货功能的界面和逻辑并不是我开发的,所以我在修改原有代码、支持有非常多细节逻辑的合并发货能力时,就在担心对原有发(zhong)货(yao)能力的影响。而这时候,如果有单测的保障,我就可以更放心地进行功能升级改造了 —— 别说更复杂的合并发货能力了,而这类诉求在复杂的交易场景里很普遍。

提炼一下我遇到的具体问题:

在由不同开发人员持续迭代、进行功能升级的软件开发活动中,如何保障具有复杂逻辑的商家经营工具的产品质量。

image.png

软件开发活动是整个流程的核心环节:接收产品和视觉设计需求/变更作为输入,然后输出客户可用的终端产品。

而统一的软件开发架构模式,则是我们保障软件开发质量的基础。(这里就不具体展开WHY了)

由于讨论的是具体面向客户使用的业务场景,少不了客户操作交互的视图层(View),所以我从MVC开始谈起。

二 从表现层的MVC谈起

image.png

虽然我平时比较慎用“架构”这个词,但我平时喜欢随手拍一些建筑物。因为建筑之美,会让我联想到软件的架构也应该有美感,毕竟Software Architecture这个概念也是起源于Architecture。
这时候,架构这个词就会给我一种接地气的感觉:有多少块砖,每块砖做什么用、放到哪里去,这块砖 和 那块砖怎么黏在一起或互相支撑。当然,由于软件的可移植性、可复用性,从某些角度来讲,软件架构相比建筑架构有其更复杂的地方。

MVC诞生至今已经超过40年了(Since 1979),10多年前就得到过很广泛的讨论和实践,穿越时空到今天肯定有其反脆弱性和内在核心价值。虽然如今乍看起来好像已经过气、被讨论过千百遍了,但仍然有很多程序员会有不同理解和看法,或多或少。这是很正常的,上面也提到了部分原因,这里具体再展开下。

1 MVC在经典三层架构里的位置

MVC是一种通用架构模式

  • 早期PC时代应用在桌面客户端,
  • 后来在Web时代变得流行(我以前写PHP也用过相关MVC框架),
  • 如今在移动互联网时代也得到广泛应用。

上面这三个场景的应用,都是面向客户的,需要交互表现的。

从MVC命名中的View(视图)也可以看出,MVC模式应用在软件系统架构里的表现层。

在业界某知名公司的官方文档里,也明确把MVC放在Web Presentation Patterns下。

image.png

我之所以没有在上图中对M-V-C添加箭头线条,是因为在这一点上,不同程序员也有不同理解和实践。

这是第一个需要明确的点:MVC架构模式在多层系统架构里的应用范围。

左侧 业务表现层-业务服务层-基础服务层 是移动端三层架构模式,未涉及到 C/S 交互;右侧是Web B/S场景的三层架构模式。

因为有些应用会比较简单,根本不需要业务服务或基础服务层,纯粹靠一个MVC(或者VC)就能交付出一个Mobile/Web App;

而且在一些业务系统里,Web前端/桌面客户端/移动App 也可能会被简化为 大前端/大终端表现层;

所以可能基于不同信息,不同程序员对此会有不同认知。

但随着用户终端应用的重要性和复杂度的提升,已经从简单应用发展到复杂多团队协同的平台型或航母级应用,仅靠一个MVC来完成交付是不合适的。

我们也可以反过来想,程序员会把以下代码放在客户端代码的哪一层:

  • 对Web引擎的扩展逻辑。
  • 通信协议的结构定义,以及相应的socket连接和通信代码。
  • 一个业务相关且UI无关的平台开放能力。
  • Crash捕获、卡顿监控、日志埋点等功能实现,比如Android在做APM相关事情时会采用AOP方式,利用ASM、AspectJ等方案来做字节码插桩。
  • ……

2 业界基于MVC模式的不同实践

前面提到不同程序员对MVC模式的理解和实践存在差异

业界大厂亦然,以下会结合业界一些知名且有影响力的公司在MVC模式上的实践,做进一步的展开讨论。

知名公司A

知名公司A在指导开发者使用MVC时,推荐下图方式:

image.png

可以看出在他们的实践上:

  1. Controller可以引用View和Model。
  2. View可以引用Model。
  3. 这里的Model倾向于是Passive。

同时,他们建议:

  • 在强类型视图场景,控制器从模型创建并填充ViewModel实例,该ViewModel 实例包含要在该视图上显示的数据。
  • 当控制器由于责任过多而变得过于复杂时,也就是业界戏称的“MVC means Massive View Controller”,需要将业务逻辑从控制器移出并推入域模型中。

知名公司B

说到Massive View Controller,知名公司B在移动互联网方兴未艾的时候,推荐下图所示的MVC实践方案:

image.png

上图呈现出:

  1. Controller引用View和Model。
  2. Model通过一些松耦合方式来触达Controller,如广播通知、callback等,驱动Controller做出响应。
  3. View通过代理模式等方案弱依赖Controller,由Controller对各种用户操作、UI渲染诉求做出响应。
  4. 而View和Model之间是隔离的,Model变化后对View的更新操作全部由Controller负责。

不过相应的官方文档已经被声明是过期文档了,并备注不一定是目前的最佳实践。

是的,随着移动互联网蓬勃发展,十年前的“最佳实践”被一路多种挑战 —— 在采用这种方案的开发领域中,如何重构Massive View Controller为Lighter View Controller已经成为了一个专题。

对比和思考

A和B的异同点

  • 相同点:Model包含 所需的数据结构封装,以及相应数据操作的方法定义。即Data + 本地或远端的CURD。
  • 差异点:在知名公司A给的图中,View可以引用Model,而在知名公司B给的图中则不行。

一些问题和思考

  • View有箭头指向Model,这里的引用关系是指什么?是View持有Model.Data数据对象,还是View调用Model.CURD方法。
  • Controller的本意是Controing Logic,那除了ViewController外,是否还可以有其它的XxController,比如DataSourceController、NotificationController?
  • 从命名上看,既然ViewController 既有View 又有Controller,那为什么把它放在 C里面,而不放在V里面呢?比如当我们在iOS/Android开发中引入MVVM模式后,ViewController或Activity属于M-VM-V的哪部分呢,代码放在哪个目录下呢?
  • 我有类名使用ViewModel后缀就代表我使用MVVM模式了吗?

Martin Fowler

作为

  1. 《重构 : 改善既有代码的设计》、《企业应用架构模式》等著作的作者;
  2. 敏捷软件开发宣言创作者之一;
  3. MVVM模式诞生时参考引用的技术专家。

Martin Fowler给的MVC模式图如下:

image.png

和上面知名公司A和B的图,又不一样了,不过他这里也是认为View可以引用Model的。

MVC和DDD

Martin Fowler和《领域驱动设计》作者Eric Evans也讨论过MVC中Model的设计理念:

  • 贫血模型:将Model分为简(pin)单(xue)的Model数据对象,和处理操作数据对象的Service/Manager/BizLogic等。

    • 示例:为aPerson修改name,则由 CitizenService.changeNameOfPerson( aPerson ) 这种方式来实现。
  • 充血模型:将对应领域的处理逻辑放到领域模型中,使得这个领域模型更饱(chong)满(xue)。

    • 示例:aPerson要刷牙,则由 aPerson.brushTeeth() 来实现。
    • 补充:充血模型更有面向对象编程的味道,尤其是搭配交易领域等业务场景,更有体感。不过稍微细想一下,可能就会发现DDD对设计的要求会更高,从而对研发周期和质量保障提出了新的要求,并且可能引起对现有系统的大规模重构。(盒马的DDD实践)

也就是说,大到MVC各个模块的依赖引用关系,细到Model中的代码设计方式,业界都有不同的理念和实践。

Java Web开发领域也对Model的设计产生过非常激烈的讨论。

小结

先抛开具体模块的代码设计方案,基于以上几种业界大厂或专家的描述,我小结了以下这张图并标注了待解问题:

image.png

问题一:如何解决MVC中Controller的膨胀臃肿问题?

要回答如何解决,需要先思考为什么膨胀。

问题二:View能否引用Model?

  • 要回答能否引用,需要先定义引用关系是什么。

    • 是持有对象,还是调用CURD接口操作对象。
    • 又或者这两者没有必要区分,因为持有的对象本身就可能带CURD接口。
  • 参考上面相关资料,目前业界有的支持、有的反对。

问题三:存在View -> Model,那么是否可以反过来存在 Model -> View?

和问题二在描述上相反但又有关联,如果对问题再进一步提问的话:

  • 使用 -> 引用关系,是为了解决什么问题?
  • 使用 -> 引用关系,会产生什么问题?

如同文章开头所说,以上问题需要结合具体场景来展开(见 实际案例结合),尽量从务虚到务实。

3 Redux-like Architecture and Framework

随着前后端分离得更彻底,终端设备性能和用户体验重要性的提升,前端领域也得到了蓬勃发展,开发方式也有了比较大的变化,MVC-like方式不再是主流:

  • UI开发方面从早期的命令式到现在的声明式。
  • 整体应用和业务逻辑实现方面,从早期的OOP写法,转向基于FP的响应式编程。比如Redux的数据流、React的Hook特性等。
  • 各种框架蓬勃发展,一些概念和模式的提出、实践应用方面,我个人认为是领先并影响客户端的。

    • 其中Redux是一个经典案例,并且我觉得Redux官方也挺开放包容的,比如Dan Abramov写的《You Might Not Need Redux》。

和MVC延伸派生出的MVC Family一样,Redux提出或重新带火了数据流、状态管理等概念,开始影响其它平台领域,并诞生了一些框架。

比如ReSwift、swift-composable-architecture,以及SwiftUI里的State and Data Flow。

image.png

虽然我也写过点React,但并没有怎么实践过Redux。

不过这些变化和影响,是我们在解决问题的过程中需要结合考虑的。

三 实际案例结合

1 常见的数据结构定义和使用

程序 = 数据结构 + 算法。
—— Nicklaus Wirth,Pascal之父,图灵奖获得者

这句话乍看起来可能会有点面向过程设计的感觉,但OOP中的对象其实也是由数据+方法组成,而FP则更不用说了。

image.png

在编码开发活动中,会存在以上3种数据结构定义和使用方式:

  1. 原生数据结构,比如list/array、map/dictionary、tuple等。
  2. 类似MyContact的数据结构定义,由服务端返回的数据进行转化,并可能根据业务逻辑按需加上一些标志位给Controller消费。
  3. 类似ContactViewModel这样的纯粹为视图View服务的数据结构定义。
补充:
(1)MyContact 和 ContactViewModel 只是特意区分的命名,实际上 MyContact 也可以是纯粹为视图View服务的数据结构定义。
(2)但是,合适的命名有助于帮助我们思考和编码,从表达上呈现出我们的倾向和重点。
"There are only two hard things in Computer Science: cache invalidation and naming things."
—— Phil Karlton

2 常见的多复杂卡片的列表场景

这个场景可以部分回答问题一:为什么Controller会膨胀,以及如何解决。

其它部分答案则落在复杂页面场景的多delegate、target-action、notification-observer等视图交互响应的处理逻辑上。

我认为,之前反对View引用Model,就是导致MVC变成Massive View-Controller的一个原因。

另一个原因我认为是工具链只提供了ViewController这样的Controller模板,隐式教导开发者都在这里写代码。

这也可能是因为十几年前移动互联网还没发展起来,移动App的复杂度低,所以提供了在当时简单够用的方案。

image.png

当只能由Controller 持有-> Model的时候,那么在多复杂卡片的列表场景中,必须由Controller来更新每个View的属性/状态。

  1. MyViewController需要为ContactCell更新它的各种相关属性,类似的还有AddressCell、PackageCell等。
  2. MyViewController在更新AddressCell展示前,可能还需要先为它计算出合适的富文本展示内容。
  3. MyViewController需要响应不同Cell的点击交互行为,包含但不限于按钮点击、输入框变化、富文本跳转、键盘起落等。
  4. MyViewController需要响应CollectionView/TableView的DataSource/Delegate各种方法实现。
  5. MyViewController需要响应Model层的变更通知,或者是另外一个ViewController抛过来的广播通知。
  6. ……

然后MyViewController就爆炸了。

针对这种场景,我的解法是:

1.通过让View->Model,基于工厂模式,把组件化Cell基于数据更新的布局逻辑交给View负责,如contactCell.configUIWithModel( contactModel )。这样有点类似上面DDD提到的充血Model,具备高内聚的特点,带来好处:

a.和减轻控制器负担、推入域模型类似,通过把数据驱动布局的代码推入组件域内,减轻了MyViewController的负担。

b.利于做这部分组件化Cell的UI测试。

c.利于这些组件化视图复用到其它场景,比如交易管理场景的订单卡片可以复用到搜索场景中,不用在SeachViewController里复制粘贴一大堆代码,只需要从Model取一个数据对象丢给组件化Cell即可。

2.基于ViewController,拆分出不同职责的扩展,比如MyViewController+Delegate专门复杂响应代理事件处理。

3.定义出其它类型的Controller,比如MyDataSourceController,专门为TableView提供数据源,可以类比参考Android中ListView的Adapter+ViewHolder。

工厂模式下,产品的刷漆、烘干、印花等操作会在内部完成,不会丢一个模型让客户去自己贴logo。MVC的每一部分都可以用不同的设计模式来组合实施,实现解耦或动态灵活的目标。

对应下图:

image.png

到这里已经回答了前面的问题一和问题二。
更多解法可以参考上面提到的相关建议,比如lighter view controllers

这里采用了 VIew -> Model 的方案,用来参与解决Massive View-Controller的问题,并且让View更容易复用和做UI测试,带来了好处。

可以结合前面提到的

“当控制器由于责任过多而变得过于复杂时,需要将业务逻辑从控制器移出并推入域模型中。”

再进一步讨论下。

我的理解和举例:

  1. 存在一个输入框,让用户提交物流单号。
  2. 用户在输入过程或者完成输入后,由View通过delegate模式路由给Controller做校验,而Controller可能还要进一步依赖Model去做更完整的校验(如网络请求到服务端,因为物流单号的规则很多而且可能动态更新)。
  3. 当Controller责任过多、代码膨胀、过于复杂时,就将物流单号这块业务逻辑推入 物流(单号)域模型中,即由View直接通过delegate模式交给 LogisticsModel来做校验。
  4. 也是 View -> Model 。

不一定对,抛(huan)砖(ying)引(lai)玉(pen)。

那么,存在VIew -> Model,有什么坏处吗?

3 一个Kotlin跨平台场景案例

这里不具体展开讲Kotlin及其跨平台相关内容,只是描述从MVC模式做跨平台迁移时遇到的问题。

image.png

这里的ViewController/Activity放在哪里,也和上面的一个问题相呼应。

虽然D-KMP主张通过全新构建工程写代码的方式来实践,但从实际情况出发,绝大多数现有系统都会是以单点尝试、渐进式的方式来落地,或发展、或回撤。

那么,如上图所示:

  1. 如果在既有MVC代码结构中,View -> Model,在这种渐进式迁移场景下,就需要修改View来适配新的ViewModel。
  2. 如果 View 不引用 Model,则是由 Controller来做胶水层设置更新视图(命令式UI)。
  3. 后者的好处是,保持View的独立性,只需要修改这个业务场景对应的单个Controller即可。因为View具有可复用性,可能在另外还没准备迁移/改变的模块里也有使用。

所以,此处不建议 View -> Model。那么,谁对呢?

4 谁对谁错的务虚讨论

当有程序员要推荐使用其它架构模式的时候,通常开头的一句话就是先说MVC模式的问题。

比如ReSwift在写 Why ReSwift? 时,开头第一句话就是:Model-View-Controller (MVC) is not a holistic application architecture.

我个人认为

  • 架构是一个名词(n.)+动词(v.)。

    • 架构(n. & v.)是为了帮助 开发者在交流时有一致的理解、在业务需要时能够便于扩展、在出问题时能够快速定位等等(对抗熵增)。具体还是看采用这个架构的得失,要解决什么问题或带来什么好处,然后带来什么成本或付出什么代价。
    • 架构(v.)通过分配每部分代码的职责并为他们取名(好比iOS/Android开发工程师这样的岗位名称,让别人一看就知道是做什么的),然后几个名字加在一起 形成了架构模式这个抽象概念。
    • 从具体到抽象,然后再由这个抽象概念去指导程序员实践写代码,促进了架构的传播,比如MVC、MVP、MVVM、MVVM-C、MVI、MV-Whatever,VIPER,Redux and More……
  • 有时候并不一定是架构模式的错,还有可能是平台/框架在让架构模式自传播时采用的具体方案出了点问题,又或者是开发者自己写代码的问题。
  • 有时候架构模式之间也不是互斥的,也可以在不同场景下互补。比如在MVC里,每个业务表现模块不一定要有三个元素齐聚,甚至也可以 VC-M-VC 共用一个M(可参考斯坦福iOS开发课程内容)。

有一个实际的业务场景是这么实践的:

image.png

MVC和MVVM在一个业务场景里相结合。

这里提到了MVVM,前面的Kotlin跨平台图,除了涉及到 View -> Model 的引用关系是否应该存在的讨论,也涉及到了Declarative-UI和MVVM架构模式等概念,再顺便展开下。

1)MVVM 和 MVW

MVC、MVP 和 Declarative-UI 这三个名词概念都有几十年历史了,其中声明式UI在近十年又开始火了起来;而MVVM则有十几年历史。

官方对MVVM有这么一些描述:

  • V和VM是一对多的关系,即View 1:n ViewModel。相比于 MVC里 Controller 1:n View,显然MVC的C更容易膨胀,所以上面也提到了使用多Controller方案。
  • V引用VM,VM操作M,而VM不需要引用V(和MVP不同)。VM作为V的上下文,包含V所需用来展示的数据,响应V被用户触发的事件。
  • V对M无感知,反过来 M 对 V和VM 也无感知。整体是松散解耦的模式。
  • 当VM的属性值发生变化时,通过数据绑定方式传达给V。这就需要有机制支撑,有对应的机制MVC也能做数据绑定。

基于上述描述我画了下图:

image.png

总体来说,MVVM是基于事件驱动的、以数据绑定机制为支撑的松散解耦架构模式。

  • 它的前提是有系统/平台/框架的机制支撑,不然实现成本和复杂度有点大。
  • 相比MVC,它的优势是视图控制逻辑不太会膨胀,代码单元更容易被测试,在可读性、可维护性上更好。
  • 它可能带来的成本/问题是入门上手较难,简单场景下使用容易过度设计,复杂场景下出问题调试比较麻烦。

考虑到ViewController在该场景的薄胶水特质,以及也参与视图展示和用户响应,所以我把它放在V里。

由于业界有太多MV-开头的模式名词了,所以Angular官方直接声明了一个MVW:

I hereby declare AngularJS to be MVW framework - Model-View-Whatever. Where Whatever stands for "whatever works for you".

这种声明有个好处,就是免去了谁对谁错/谁好谁坏的争执,而重点关注于谁适合。

5 谁对谁错的务实案例:VIPER和分层演变

关于谁对谁错/谁好谁坏,可以再来看一个案例。

VIPER架构模式的应用

VIPER概念由View、Interactor、Presenter、Entity、Router几个元素组成,大致如下:

image.png

我之前写过MVC、MVP、MVVM、VIPER等架构模式下的代码,完全实现或不完全实现。

有一次,我在某个业务表现模块里应用VIPER,然后定义了一个XxxNetworkInteractor类,用来负责做网络请求。

image.png

VIPER架构模式的演变

后来随着业务场景的变化,一个业务模块可能需要对接多套网关服务,XxxNetworkInteractor就要做抽象隔离,消除业务逻辑对多套网关请求的感知,并且应用到其它业务模块。这就有点像 VPER - I - VPER 模式 —— 多个业务模块对 Interactor 进行了复用。

image.png

进化

  • 随着对接网关数的增加、网关能力的增强,XxxNetworkInteractor也配套建设了更多能力。
  • 随着使用XxxNetworkInteractor的模块越来越多,不同业务的一些通用诉求和处理逻辑也随之增加。
  • 随着XxxNetworkInteractor的功能越来越强大,代码越来越多,逐渐需要抽离出一个单独模块,不管是从提高编译速度,还是从封装暴露等角度。

于是,XxxNetworkSDK.framework诞生了。

image.png

退化

再后来,随着技术和业务的变化,底层网关服务ATop成为了领域范围内的事实标准,之前遇到的问题也消失了,而XxxNetworkSDK又带来一些成本,比如要配套ATop的能力升级进行迭代维护。

此时,XxxNetworkSDK可以退出历史舞台了,让业务模块直接面向ATop编程,这样既降低了维护成本,又带来了一定的包大小收益。

image.png

以后,假如有另外一个领域范围的业务场景(采用了XTop),要复用最上层的业务模块,由于在另外一个领域范围,业务模块要从 调用ATop 改为调用XTop。

那么,接手或负责迁移复用的开发者,会不会在想:为什么这些业务模块直接调用ATop,而没有使用一个XxxNetworkInteractor来做分层隔离呢?让业务不要感知具体的数据库或网络服务实现。

  • 如果有,他只要做一件事情:让XxxNetworkInteractor对接XTop即可。
  • 如果没有,他需要去替换修改每个业务模块的调用代码、返回值处理等等。

四 写在最后,回到问题

不管是务虚的讨论,还是务实的案例,或者是Angular的“whatever works for you”的观点,结论是没有谁对谁错、谁好谁坏,只有实际场景下要解决的核心问题。

兵无常势,水无常形。那么,回到想要解决的问题:

在由不同开发人员持续迭代、进行功能升级的软件开发活动中,如何保障具有复杂逻辑的商家经营工具的产品质量。

我的想法是以可测性作为手段,来保障功能升级改造或代码重构后,可在合理时间范围内得到充分回归验收,保障相关组件、模块或整体产品的质量。

具体的方案实施上,因为是以可测性为重要关注点,再结合目前的技术方向,我会倾向于采用MVVM。

  • MVVM的架构模式在理解和认知上比较成熟(应该是移动端开发领域TOP2流行的),便于实施和传播,并通过模式的名称来体现要强调的关注点:可测性。
  • MVVM可以更好地结合SwiftUI+Combine、Kotlin跨平台等技术方向。
  • MVVM完全版的上手门槛和简单场景的过度设计问题,可以通过采用不完全版MVVM来解决。

    • 不完全版的MVVM可以cover适用于简单场景的MVC,近似于 超集-子集 关系。
    • 虽然也可以通过多Controller的方式来解决MVC膨胀问题,但MVC的命名在实践中就容易让程序员弱化掉可测性这个关注点(也可能是我个人理解和实践不够正确)。
  • 复杂场景的调试问题、更多可测性的实践,需要再摸索下,也希望得到相关分享和指点。

阿里云|MongoDB中国区域游戏行业私享会重磅来袭!

诚邀您与Mongo DB、阿里云数据库专家团队, 以及游戏行业同行共同探讨如何使用Mongo DB帮您打造全球化高效、易用、稳定的数据库架构,为您详细解MongoDB5.0新特性在游戏行业的最佳实践。

点击这里,查看详情!

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
1月前
|
负载均衡 测试技术 持续交付
高效后端开发实践:构建可扩展的微服务架构
在当今快速发展的互联网时代,后端开发扮演着至关重要的角色。本文将重点探讨如何构建可扩展的微服务架构,以及在后端开发中提高效率的一些实践方法。通过合理的架构设计和技术选型,我们可以更好地应对日益复杂的业务需求,实现高效可靠的后端系统。
|
1月前
|
设计模式 API 数据库
构建高效微服务架构:从理论到实践
【2月更文挑战第29天】 在现代软件开发领域,微服务架构已经成为一种流行的设计模式,它通过将大型应用程序拆分成一系列小型、独立的服务来提高系统的可维护性、扩展性和敏捷性。本文将深入探讨微服务的核心概念、设计原则以及如何在实际项目中实现和优化微服务架构。我们将从微服务的定义出发,讨论其与传统单体架构的区别,并分析微服务的优势与挑战。接着,文章将提供一套实践指南,包括服务划分、通信机制、数据一致性问题以及安全性考虑等方面,以指导开发者构建和维护一个高效的微服务系统。
|
16天前
|
Kubernetes 安全 Java
构建高效微服务架构:从理论到实践
【4月更文挑战第9天】 在当今快速迭代与竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性及容错性,成为众多企业转型的首选。本文将深入探讨如何从零开始构建一个高效的微服务系统,覆盖从概念理解、设计原则、技术选型到部署维护的各个阶段。通过实际案例分析与最佳实践分享,旨在为后端工程师提供一套全面的微服务构建指南,帮助读者在面对复杂系统设计时能够做出明智的决策,并提升系统的可靠性与维护效率。
|
1月前
|
消息中间件 敏捷开发 运维
构建高效可靠的微服务架构:策略与实践
随着现代软件开发的复杂性增加,微服务架构逐渐成为企业解决大型应用系统分解、敏捷开发和持续部署问题的有效手段。本文深入探讨了构建一个高效且可靠的微服务架构的关键策略,包括服务的合理划分、通信机制的选择、数据一致性保障以及容错处理。通过分析这些策略在具体案例中的应用,我们旨在为开发者提供一套可行的微服务设计及实施指南。
132 6
|
1月前
|
Cloud Native 安全 持续交付
构建未来:云原生架构的演进与实践
【2月更文挑战第30天】 随着数字化转型的深入,企业对于信息技术的需求日益复杂化和动态化。传统的IT架构已难以满足快速迭代、灵活扩展及成本效率的双重要求。云原生技术作为解决这一矛盾的关键途径,通过容器化、微服务、持续集成/持续部署(CI/CD)等手段,实现了应用的快速开发、部署及运维。本文将探讨云原生架构的最新发展,分析其如何助力企业构建更加灵活、高效的业务系统,并结合实际案例,展示云原生转型过程中的最佳实践和面临的挑战。
|
8天前
|
消息中间件 运维 监控
现代化软件开发中的微服务架构设计与实践
本文将深入探讨现代化软件开发中微服务架构的设计原则和实践经验。通过分析微服务架构的优势、挑战以及常见的设计模式,结合实际案例,帮助开发者更好地理解如何构建可靠、可扩展、高效的微服务系统。
|
8天前
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【4月更文挑战第17天】Spring Cloud是Java微服务治理的首选框架,整合了Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心)。通过Eureka实现服务注册与发现,Ribbon提供负载均衡,Hystrix实现熔断保护,Zuul作为API网关,Config Server集中管理配置。理解并运用Spring Cloud进行微服务治理是现代Java开发者的关键技能。
|
9天前
|
敏捷开发 监控 前端开发
深入理解自动化测试框架Selenium的架构与实践
【4月更文挑战第16天】 在现代软件开发过程中,自动化测试已成为确保产品质量和加快迭代速度的关键手段。Selenium作为一种广泛使用的自动化测试工具,其开源、跨平台的特性使得它成为业界的首选之一。本文旨在剖析Selenium的核心架构,并结合实际案例探讨其在复杂Web应用测试中的高效实践方法。通过详细解读Selenium组件间的交互机制以及如何优化测试脚本,我们希望为读者提供深入理解Selenium并有效运用于日常测试工作的参考。
14 1
|
12天前
|
Linux 数据安全/隐私保护
Linux基础与服务器架构综合小实践
【4月更文挑战第9天】Linux基础与服务器架构综合小实践
1239 8
|
21天前
|
消息中间件 监控 API
构建高性能微服务架构:从理论到实践
【4月更文挑战第4天】 在当今互联网应用的快速迭代和高并发需求下,传统的单体应用架构已不足以满足市场的灵活性与扩展性要求。微服务架构以其独立部署、弹性伸缩、技术多样性等优势,成为众多企业转型升级的首选方案。本文将深入探讨如何构建一个高性能的微服务系统,涵盖关键组件的选择、系统设计的考量以及性能优化的策略,旨在为开发者和架构师提供一套实用的指导思路和具体实践步骤。