欢迎来到培训无忧网!

全国切换

咨询热线 400-001-5729

位置:培训无忧网 > 新闻资讯 > 电脑/IT > 程序开发 >  软件开发架构模式浅谈

软件开发架构模式浅谈

来源:www.pxwy.cn 发布人:彭二胖

2022-01-09 10:15:21|已浏览:115次


       一  背景和问题
       我个人平时会比较慎用“架构”这个词

       一方面是觉得业界有很多架构大师和架构模式,而我的认知和实践有限;
       另一方面是因为这个词看着挺高大上、有点务虚,如果不结合实际场景的具体问题来讨论,容易陷入“PHP是最好的语言”这样的辩论赛中。而不同场景中又有各自的问题,程序员们通过自己的理解和思考、针对实际场景对一些架构模式进行了扩展实践,以此来解决遇到的问题,也会基于同一个模式延伸出一些派生概念。
       兵无常势,水无常形。所以,我个人的观点是:以要解决的问题为出发点,去讨论我们要采用的架构模式(技术方案)。
       另外,由于我们是站在很多巨人肩膀上的,讨论时可以站在一些如SOLID等软件设计/开发原则的基础上。
       写这篇文章,我也是从解决一些问题的目的出发的:
       最近和团队同学讨论了相关话题,虽然大多数同学在实践上基本一致,但具体到话术、名词概念和具体使用的理解和实践上有些差异(这是很正常的,因为业界对同一个模式的理解和实践也不同)。我结合一些实际编码场景做了一番陈述,为了避免后续重复大费口舌,所以打算写下来,以后有需要直接发文章链接。
       由于我个人的认知和实践有限,所以也希望能抛(huan)砖(ying)引(lai)玉(pen),让我学到更多。
       虽然同一个架构模式在不同业务/技术领域的实施会有区别,但同一个团队内应该保持一致性,因为这样有助于日常的code review、功能模块的交接backup等活动,尤其是有利于使用统一的单测建设方案来保障我们的产品质量。
       实际问题:我最近在开发商家合并发货的功能,但由于之前基础发货功能的界面和逻辑并不是我开发的,所以我在修改原有代码、支持有非常多细节逻辑的合并发货能力时,就在担心对原有发(zhong)货(yao)能力的影响。而这时候,如果有单测的保障,我就可以更放心地进行功能升级改造了 —— 别说更复杂的合并发货能力了,而这类诉求在复杂的交易场景里很普遍。
       提炼一下我遇到的具体问题:
       在由不同开发人员持续迭代、进行功能升级的软件开发活动中,如何保障具有复杂逻辑的商家经营工具的产品质量。
       软件开发活动是整个流程的核心环节:接收产品和视觉设计需求/变更作为输入,然后输出客户可用的终端产品。
       而统一的软件开发架构模式,则是我们保障软件开发质量的基础。(这里就不具体展开WHY了)
       由于讨论的是具体面向客户使用的业务场景,少不了客户操作交互的视图层(View),所以我从MVC开始谈起。
       二  从表现层的MVC谈起
       虽然我平时比较慎用“架构”这个词,但我平时喜欢随手拍一些建筑物。因为建筑之美,会让我联想到软件的架构也应该有美感,毕竟Software Architecture这个概念也是起源于Architecture。
       这时候,架构这个词就会给我一种接地气的感觉:有多少块砖,每块砖做什么用、放到哪里去,这块砖 和 那块砖怎么黏在一起或互相支撑。当然,由于软件的可移植性、可复用性,从某些角度来讲,软件架构相比建筑架构有其更复杂的地方。
       MVC诞生至今已经超过40年了(Since 1979),10多年前就得到过很广泛的讨论和实践,穿越时空到今天肯定有其反脆弱性和内在核心价值。虽然如今乍看起来好像已经过气、被讨论过千百遍了,但仍然有很多程序员会有不同理解和看法,或多或少。这是很正常的,上面也提到了部分原因,这里具体再展开下。
       1  MVC在经典三层架构里的位置
       MVC是一种通用架构模式
       早期PC时代应用在桌面客户端,
       后来在Web时代变得流行(我以前写PHP也用过相关MVC框架),
       如今在移动互联网时代也得到广泛应用。
       上面这三个场景的应用,都是面向客户的,需要交互表现的。
       从MVC命名中的View(视图)也可以看出,MVC模式应用在软件系统架构里的表现层。
       在业界某知名公司的官方文档里,也明确把MVC放在Web Presentation Patterns下。
       我之所以没有在上图中对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时,推荐下图方式:
       可以看出在他们的实践上:
       Controller可以引用View和Model。
       View可以引用Model。
       这里的Model倾向于是Passive。
       同时,他们建议:
       在强类型视图场景,控制器从模型创建并填充ViewModel实例,该ViewModel 实例包含要在该视图上显示的数据。
       当控制器由于责任过多而变得过于复杂时,也就是业界戏称的“MVC means Massive View Controller”,需要将业务逻辑从控制器移出并推入域模型中。
       知名公司B
       说到Massive View Controller,知名公司B在移动互联网方兴未艾的时候,推荐下图所示的MVC实践方案:
       上图呈现出:
       Controller引用View和Model。
       Model通过一些松耦合方式来触达Controller,如广播通知、callback等,驱动Controller做出响应。
       View通过代理模式等方案弱依赖Controller,由Controller对各种用户操作、UI渲染诉求做出响应。
       而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
       作为
       《重构 : 改善既有代码的设计》、《企业应用架构模式》等著作的作者;
       敏捷软件开发宣言创作者之一;
       MVVM模式诞生时参考引用的技术专家。
       Martin Fowler给的MVC模式图如下:
       和上面知名公司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的设计产生过非常激烈的讨论。
       小结
       先抛开具体模块的代码设计方案,基于以上几种业界大厂或专家的描述,我小结了以下这张图并标注了待解问题:
       问题一:如何解决MVC中Controller的膨胀臃肿问题?
       要回答如何解决,需要先思考为什么膨胀。
       问题二:View能否引用Model?

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

       是持有对象,还是调用CURD接口操作对象。

       又或者这两者没有必要区分,因为持有的对象本身就可能带CURD接口。

       参考上面相关资料,目前业界有的支持、有的反对。
       问题三:存在View -> Model,那么是否可以反过来存在 Model -> View?
       和问题二在描述上相反但又有关联,如果对问题再进一步提问的话:
       使用 -> 引用关系,是为了解决什么问题?
       使用 -> 引用关系,会产生什么问题?
       如同文章开头所说,以上问题需要结合具体场景来展开(见 实际案例结合),尽量从务虚到务实。

       本文由培训无忧网长沙牛耳教育课程顾问老师整理发布,希望能够对想在长沙参加影视动漫培训的学生有所帮助。更多课程信息可关注培训无忧网电脑IT培训频道或添加老师微信:15033336050


      注:尊重原创文章,转载请注明出处和链接 https://www.pxwy.cn/news-id-13948.html 违者必究!部分文章来源于网络由培训无忧网编辑部人员整理发布,内容真实性请自行核实或联系我们,了解更多相关资讯请关注程序开发频道查看更多,了解相关专业课程信息您可在线咨询也可免费申请试课。关注官方微信了解更多:150 3333 6050

留下你的信息,课程顾问老师会一对一帮助你规划更适合你的专业课程!
  • 姓名:

  • 手机:

  • 地区:

  • 想学什么:

  • 培训无忧网
免 费 申 请 试 听
提交申请,《培训无忧网》课程顾问老师会一对一帮助你规划更适合你的专业课程!