0530-3433334

网站建设 APP开发 小程序

知识

分享你我感悟

您当前位置>首页 >> 知识 >> 软件开发

(干货)软件设计/开发原则的基础上的问题

发表时间:2023-10-12 10:00:52

文章来源:炫佑科技

浏览次数:184

菏泽炫佑科技

(干货)软件设计/开发原则的基础上的问题

1. 背景和问题

就我个人而言,我通常更谨慎地使用“架构”这个词。

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

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

在写这篇文章时,我也着手解决一些问题:

我*近与我的团队成员讨论了相关话题。 虽然大多数学生在实践中基本一致,但对具体词汇、名词概念和具体用法的理解和实践存在一些差异(这是正常的,因为行业使用相同的模型,理解和实践也不同)。 我根据一些实际编码场景做了一个表述。 为了避免以后重复,我打算写下来,以后有需要的话直接贴出文章的链接。 由于我个人的见识和实践有限,所以也希望通过抛(hua)砖(ying)、感应(lai)玉(笔)能够学到更多。 虽然同一个架构模型在不同的业务/技术领域的实现会有所不同,但在同一个团队内应该保持一致性,因为这将有助于日常代码、功能模块的交接等活动,特别是使用统一的单测试施工计划,以确保我们的产品质量。 实际问题:*近在开发者之家实现了拼运功能,但是由于之前基础拼运功能的接口和逻辑不是我开发的,所以我正在修改原来的代码来支持拼运功能,有很多细节逻辑。 当时我很担心对原来的送(zhong)货(yao)能力造成影响。 这个时候,如果有单体测试的保证,我就可以更加放心地进行功能升级和改造——更不用说更复杂的组合发货能力了,而这种请求在复杂的交易场景中是很常见的。

总结一下我遇到的具体问题:

在不同开发者不断迭代升级功能的软件开发活动中,逻辑复杂的商户管理工具如何保证产品质量。

软件开发活动是整个流程的核心:接收产品和视觉设计要求/变更作为输入并输出客户可用的*终产品。

统一的软件开发架构模型是我们保证软件开发质量的基础。 (这里就不详细解释为什么了)

由于我们讨论的是客户使用的具体业务场景,因此客户操作和交互的视图层(View)是必不可少的,所以我将从MVC开始。

2、我们先从表现层的MVC开始

虽然我通常谨慎使用“建筑”这个词,但我通常喜欢随意拍摄建筑物的照片。 因为架构之美提醒我软件的架构也应该有美。 毕竟这个概念也是起源的。

这时,建筑这个词会给我一种踏实的感觉:有多少块砖,每块砖是用来做什么的,放在哪里,这块砖和那块砖是如何粘在一起或相互支撑的。 当然,由于软件的可移植性和可重用性,从某些角度来看,软件架构比构建架构更为复杂。

MVC诞生至今已经40多年了(Since 1979)。 十多年前,它已被广泛讨论和实践。 它一定有它的反脆弱性和内在的核心价值,跨越时空走到今天。 尽管乍一看似乎已经过时,并且已经被讨论了一千遍,但仍然有很多程序员或多或少地有不同的理解和意见。 这是正常的,上面提到了一些原因。 让我们在这里详细展开它们。

1 MVC在经典三层架构中的地位

MVC是一种常见的架构模式

以上三种场景的应用都是面向客户的,需要交互性能。

从MVC命名中的View也可以看出,MVC模式应用在软件系统架构的表示层。

在业界某知名公司的官方文档中,也明确将MVC放在了Web之下。

上图中我之所以没有给MVC添加箭头线,是因为在这一点上,不同的程序员有不同的理解和做法。

这是首先需要明确的一点:MVC架构模式在多层系统架构中的适用范围。

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

因为有些应用比较简单,根本不需要业务服务或者基础服务层。 /Web App 可以纯粹依靠 MVC(或 VC)来交付;

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

因此,不同的程序员根据不同的信息可能会有不同的认知。

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

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

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

前面提到,不同的程序员对MVC模式有不同的理解和实践。

对于行业内的主要参与者来说也是如此。 下面将结合业界一些知名且有影响力的公司对MVC模式的实践进行进一步探讨。

知名企业A

知名公司A在指导开发人员使用MVC时推荐以下方法:

从他们的实践中可以看出:

View和Model可以参考。 View可以引用Model。 这里的模型往往是。

与此同时,他们建议:

知名企业B

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

上图显示:

参考视图和模型。 模型是通过一些松耦合的方式达到的,比如广播通知等,驱动响应。 View弱依赖代理模式等解决方案来响应各种用户操作和UI渲染请求。 View 和 Model 是隔离的,Model 更改后对 View 的所有更新负责。

不过,相应的官方文档已被宣布已经过时,并且需要指出的是,这并不一定是当前的*佳实践。

是的,随着移动互联网的蓬勃发展,十年前的“*佳实践”受到了多方面的挑战——在采用这种解决方案的开发领域,如何将View重构为View已经成为一个专题。

比较和思考

A和B之间的异同

一些问题和思考

作为

着有《重构:改进现有代码的设计》、《企业应用架构模式》等著作; 敏捷软件开发宣言的创建者之一; MVVM模型诞生时一位技术专家引用的。

给出的MVC模式图如下:

与上面知名公司A、B的图片不同,但他也认为View可以引用Model。

MVC 和 DDD

《领域驱动设计》一书的作者Eric Evans也讨论了MVC中Model的设计理念:

也就是说,业界有不同的理念和做法,小到各个MVC模块的依赖引用关系,小到Model中的代码设计方法。

Java Web开发领域对于Model的设计也有非常热烈的讨论。

概括

抛开具体模块的代码设计,根据以上各大厂商或者业内专家的描述,我总结了下图,并标注了需要解决的问题:

问题1:如何解决MVC中臃肿的问题?

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

问题2:可以查看参考模型吗?

问题3:如果View -> Model存在,Model -> View是否可以反过来存在?

描述相反,但与问题 2 相关。如果您提出进一步问题:

正如文章开头提到的,上述问题需要结合具体场景来制定(见实际案例组合),尽量从实用主义走向实用主义。

3 类似 Redux 和

随着前端和后端更加完全分离以及终端设备性能和用户体验的重要性增加,前端领域也蓬勃发展,开发方式也发生了重大变化。 类似MVC的方法不再是主流:

与MVC扩展衍生的MVC一样,Redux提出或重新点燃了数据流、状态管理等概念,开始影响其他平台领域,并催生了一些框架。

例如,swift--以及状态和数据流。

虽然我写过一些React,但是我并没有太多练习Redux。

但在解决问题的过程中需要考虑这些变化和影响。

结合三个实际案例

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

程序=数据结构+算法。

——沃斯之父、图灵奖获得者

这句话乍一看有点面向过程的设计,但OOP中的对象实际上是由数据+方法组成的,更不用说FP了。

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

原生数据结构,比如list/array、map/、tuple等。类似的数据结构定义,服务器返回的数据经过转换,可以根据需要根据业务逻辑添加一些flag进行消费。 像这样的数据结构定义纯粹是为视图服务的。

补充:

(1) 和 只是故意区分的名称。 事实上,它们也可以是纯粹为视图服务的数据结构定义。

(2)然而,适当的命名可以帮助我们思考和编码,并表达我们的倾向和优先事项。

“只有两个硬盘:缓存和。”

——菲尔

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

这个场景可以部分回答问题一:为什么会发生扩容以及如何解决。

其他答案落在了复杂页面场景下多个、-、-视图交互响应的处理逻辑上。

我认为之前对View引用Model的反对是MVC成为View-的原因之一。

我认为的另一个原因是工具链只提供了这样的模板,隐含地教开发人员在这里编写代码。

这也可能是因为十多年前移动互联网还没有发展起来,移动应用的复杂度较低,所以在当时提供了简单而充分的解决方案。

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

需要更新它的各种相关属性,例如等等。在更新之前,您可能还需要计算适合您的显示的富文本显示内容。 需要响应不同Cell的点击交互行为,包括但不限于按钮点击、输入框变化、富文本跳转、键盘上下起伏等,需要响应/实现各种方法。 需要响应Model层的变更通知,或者另外抛出过来的广播通知。 ……

然后它爆炸了。

对于这种场景,我的解决方案是:

1.通过让View->Model,基于工厂模式,将基于数据更新的组件化Cell的布局逻辑交给View,如。 ()。 这有点类似于上面DDD提到的拥塞模型。 具有高内聚的特点,带来的好处:

A。 与减轻控制器负担并推入域模型类似,通过将数据驱动的布局代码推入组件域,减轻了负担。

b. 有利于对这个组件化的Cell进行UI测试。

C。 它有助于在其他场景中重用这些组件化视图。 例如,交易管理场景中的订单卡可以在搜索场景中复用。 无需在那里复制并粘贴大量代码。 您只需要从模型中取出一个数据对象并将其扔给组件化即可。 只是细胞。

2.在此基础上,拆分出不同职责的扩展,比如+专门的复杂响应代理事件处理。

3、定义其他类型,比如er,专门提供数据源,可以类比参考文献中的+。

在工厂模式下,产品的喷漆、烘干、印刷等操作都将在内部完成,不会留下任何模型供客户贴上自己的标志。 MVC的每个部分都可以使用不同的设计模式进行组合和实现,以实现解耦或动态灵活性。

对应下图:

至此,前面的问题一和问题二已经得到解答。

更多解决方案请参考上面提到的相关建议,例如查看

这里采用了VIew -> Model的方案来参与View问题的解决,并且更容易复用View以及对View进行UI测试,带来了好处。

可以与前面提到的结合起来

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

让我们进一步讨论这个问题。

我的理解和例子:

有一个输入框允许用户提交物流订单号。 在输入过程中或者用户完成输入后,View通过模式路由进行验证,并且可能进一步依赖Model进行更完整的验证(比如网络请求服务器,因为物流单号的规则很多,可能会动态变化)更新)。 当职责过多、代码臃肿、过于复杂时,将物流单号的业务逻辑推入物流(单号)域模型中,即View直接将其通过模型进行传递确认。 另请查看 -> 模型。

不一定对,抛(huan)砖(ying)铅(lai)玉(笔)。

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

3 跨平台场景案例

这里不会详细介绍跨平台的内容,只是描述从MVC模型迁移到跨平台时遇到的问题。

在哪里/哪里把它放在这里也呼应了上面的问题。

虽然D-KMP提倡通过新的建设项目、编写代码来实践,但根据实际情况,大多数现有系统都会以单点试用、增量的方式实施、开发或退出。

那么,如上图所示:

如果在现有的MVC代码结构中,View -> Model,在这种渐进式迁移的场景下,View需要进行修改以适应新的。 如果视图不引用模型,则使用粘合层设置来更新视图(命令式 UI)。 后者的优点是保持View的独立性,只需要修改该业务场景对应的单个即可。 由于 View 是可重用的,因此它可以在尚未准备好迁移/更改的其他模块中使用。

因此这里不推荐View -> Model。 那么,谁是对的呢?

4 务实讨论谁对谁错

当程序员想要推荐使用其他架构模式时,**句话通常就是谈论MVC模式。

比如写Why?时,开头**句是:Model-View-(MVC) is not a。

在我看来

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

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

这里提到了MVVM。 前面的跨平台图,除了讨论View->Model的引用关系是否应该存在之外,还涉及到UI、MVVM架构模式等概念,然后在此展开。

1)MVVM和MVW

MVC、MVP和-UI这三个名词概念已经有几十年的历史了。 其中,声明式UI在过去十年再次流行; 而MVVM已经有十多年的历史了。

MVVM官方的描述如下:

根据上面的描述我画了下图:

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

考虑到场景的薄胶性质,以及它对视图呈现和用户响应的参与,我将其放置在 V 中。

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

我是 MVW - 模型-视图-。 “为你工作”在哪里。

这种说法的好处是消除了谁对谁错/谁好谁坏的争论,而集中于谁适合。

5 个谁对谁错的实用例子:VIPER 和分层的演变

关于谁对谁错/谁好谁坏,我们可以看另一个案例。

VIPER架构模式的应用

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

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

有一次,我在业务性能模块中使用了VIPER,然后定义了一个类来负责发出网络请求。

VIPER架构模式的演变

后期随着业务场景的变化,某个业务模块可能需要连接多组网关服务,那么就需要进行抽象隔离(干货)软件设计/开发原则的基础上的问题,消除业务逻辑对多组网关请求的感知,并应用到其他业务模块中。 这有点像VPER-I-VPER模型——多个业务模块对被重用。

进化

因此,。 出生于。

退化

后来随着技术和业务的变化,底层网关服务ATop成为了该领域事实上的标准。 之前遇到的问题消失了,但也带来了一些成本,比如迭代维护来支持ATop的能力升级。 。

这时候,你就可以退出历史舞台,让业务模块直接为ATop编程了。 这不仅降低了维护成本,还带来了一定的封装尺寸优势。

以后如果有另一个域的业务场景(使用XTop),就必须复用顶层业务模块,因为在另一个域软件开发,业务模块需要从调用ATop变为调用XTop。

那么,接手或者负责迁移复用的开发人员,可能会想:为什么这些业务模块直接调用ATop,而不是用一个来进行层次隔离呢? 让业务不知道具体的数据库或网络服务实现。

四写在*后,回到问题

无论是务实的讨论、务实的案例,还是“为你工作”的视角,结论都是没有对错、好坏之分,只有实际场景中需要解决的核心问题。

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

在不同开发者不断迭代升级功能的软件开发活动中,逻辑复杂的商户管理工具如何保证产品质量。

我的想法是,以可测试性为手段,确保功能升级或代码重构后,能够在合理的时间范围内获得全面的回归验收,以保证相关组件、模块或整体产品的质量。

关于方案的具体实现,由于可测试性是一个重要的关注点,结合目前的技术方向,我会倾向于使用MVVM。

作者 | 斯勤

原文链接:

炫佑科技专注互联网开发小程序开发-app开发-软件开发-网站制作等

相关案例查看更多