百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

构建可维护的软件 构建可维护的软件是什么

liebian365 2024-11-13 13:24 18 浏览 0 评论

将基础架构与应用程序分离

在过去的几年中,我遇到了一些我不想谈论的代码。 我总是想知道项目如何才能以这种状态结束,更重要的是,如何防止自己编写遗留代码。

开始一个新项目

开始一个新项目总是很令人兴奋。 使用许多新技术并编写比上次更好的代码的绝好机会。

这看起来像是微服务的完美项目!

别误会我,我喜欢微服务,但您不应该从它开始。 除非您已经在微服务环境中工作,否则这太过分了。

相反,请确保您的代码已准备好进行分离。 有很多方法可以做到这一点。 问题是,您需要走多远。 它仍然只是MVP,我们希望在数周而不是数月内发布项目。 但是,我们也不想为此做噩梦。

在我看来,有两种选择

· 快速而肮脏地建造东西。 当人们开始使用它时,我们会将其丢弃并正确构建。

· 分开应用程序的某些部分,以便我们在需要时可以替换它们。 节省执行时间,而不是分开。

建造和更换

这可能是一个非常好的方法,尤其是当我们快速想测试人们是否喜欢我们的产品时。

但是,当产品成功后,我们将不得不重写所有内容,说实话。 它在生产中运行后真的要从头开始构建吗? 可能不是。

当然,如果产品成功,则有一天它将被重写。 但这可能要花费数年的时间,而且如果不幸的话,您最终可能会处理具有超过一万行代码的文件。

我认为我已在10782行中找到了该错误。

这可能有点夸张,但您明白了。

如果您的目标是测试某个想法,请绝对考虑使用此选项,只需确保对其进行重构即可。

将基础架构与应用程序分离

这将花费更多时间,但是如果项目失败,我们可以将一些代码重用于另一个项目。 但是,如果执行不正确,我们可能最终仍会重构整个项目。

那么,我们如何分隔项目以保持其可维护性呢?

让我们从创建基础架构和应用程序层开始。

基础结构层将包含管理任何网络请求的所有类。 从接收API调用到与数据存储进行通信。 这是项目开始时最重要的部分。

假设我们为MVP选择了一个SQLite数据库。 只要确保实现隐藏在接口后面,我们就可以在必要时轻松替换数据存储。

处理传入请求有点不同。 但是目标是相同的。 我们可以使用命令对象将处理请求的方式与处理请求的方式分开。 让我们看看以下示例。

我们有一个控制器,它接收创建新主题的请求。 控制器会将数据从HTTP请求转换为命令对象。 该对象将包含我们要执行的突变所需的所有数据。 我们可以将此对象传递给位于应用程序层中的服务。 服务本身对HTTP请求一无所知。 因此,我们可以轻松地由消费者替换我们的控制器,甚至可以同时支持两个控制器:

然后,我们的主题服务将决定是否应创建主题。 主题独特吗? 标题符合要求吗? 这些业务规则应放在应用程序层内。 如果所有断言都通过,则服务将在存储库上执行create方法。 请务必仅通过接口引用存储库,这一点很重要。

假设我们现在想用MySQL数据库替换SQLite数据库。 为此,我们只需要创建一个新的存储库,实现现有接口并将其注入主题服务中即可。

通过将基础架构与业务逻辑分开,我们可以更轻松地替换应用程序的某些部分。 当然,仅创建两个文件夹和一些类不足以阻止现有的旧应用程序。 我们仍然需要不时更新我们的服务。

分离不同的上下文

确保将应用程序的不同部分分成各自的上下文。 我们不希望有一个包含数百个控制器的Controller文件夹。 每个上下文都应具有自己的基础结构和应用程序层。 某些类(例如记录器)可以在上下文之间共享。 这些共享的类可以放在Common文件夹中。

src/ Topic/ Application/ Infrastructure/ Account/ Application/ Infrastructure/ Common/

另外,请尝试避免直接引用其他上下文。 您可以使用事件在它们之间进行通信。 如果必须引用另一个上下文,请确保仅在基础结构层中引用它。 当您的应用程序变得很大时,这种分离使迁移到微服务体系结构变得容易得多。

最后的想法

新项目的截止日期通常很紧。 通过将项目分为两层,我们将能够在确保质量和可扩展性的同时快速交付。

关于这个话题还有很多要说的。 如果您喜欢将应用程序划分为不同的层,则可能还需要:

· 六角形建筑

· 分层架构

· 域驱动设计

感谢您阅读本文。 如果喜欢,请考虑关注我,下次再见!

(本文翻译自Stein Janssen的文章《Building Maintainable Software》,参考:https://levelup.gitconnected.com/building-maintainable-software-50c6bd09c611)

相关推荐

记录一个ComboBox的设置问题,你可能没遇到过

ComboBox这个控件使用频率太高了,我从VC6编程开始就用它,一直用到C#到现在的Net6,要说我这么一个编程老手还能在它身上栽跟头,我都不敢相信。但是今天竟然被它无情的戏耍了。记录下这个问题,看...

组合框(Combo Box)应用之一_combo简单组合框

【分享成果,随喜正能量】对别人期待太高,本质上是对自身无能的逃避和推托,与其期待别人,不如依靠自己。你不害怕孤独,就不再寄期望于他人陪伴;你有底气解决问题,就不在寄期望于他人向你伸出援手。一个人期待值...

Qt之QComboBox定制(二)_qt on_combobox_activated

上一篇文章Qt之QComboBox定制讲到了qt实现自定义的下拉框,该篇文章主要实现了列表式的下拉框,这一节我还将继续讲解QComboBox的定制,而这一节我将会讲述更高级的用法,不仅仅是下拉列表框,...

从零开始系列,用C#做软件产品:私人日记(九)ComboBox入门

第八节的内容早已写好发布,结果一直在审核中,不知道触动了哪条神经。评论中看到有一些网友都在问为什么不用WPF来开发,在这里我统一说明下:1)WPF界面设计相对复杂。由于它是矢量的,需要额外有很多容器做...

QT-QSharedMemory_qt450-10是什么材料

1.QSharedMemory介绍...

进入Python的世界19-pyqt6不只是UI设计,其他模块功能如何运用

今天是大年初四,继续探讨pyqt6,给出使用的建议。PyQt6绝不仅仅局限于UI设计...

从零开始学Qt - 10:一文读懂Qt的元对象系统

Qt本身并不是一种编程语言,它实质上是一个跨平台的C++开发类库。它是用标准C++编写的,为开发GUI应用程序和非GUI应用程序提供了各种类。Qt对标准C++进行了扩展,引入一些新的概念和功能,例如信...

QT实现抖动文字和滚动文字,附源码

前言不知道大家有没有发现今天的文章有什么不一样,哈哈,我自己胡拼乱凑弄了一个logo,好不好看就先不说了,最起码萌萌哒...当然这不是今天的重点,在做logo的时候,我原本想让文字动起来的,奈何技术有...

Qt Concurrent的使用_qt是什么意思

1.简介QtConcurrent命名空间提供了高级api,使得无需使用诸如互斥、读写锁、等待条件或信号量等低级线程原语就可以编写多线程程序。使用QtConcurrent编写的程序会根据可用的...

Qt使用FFmpeg播放视频_qt使用ffmpeg播放视频功能

一、使用场景...

Qt中使用匿名函数lambda表达式_匿名函数lambda

一、为什么要使用匿名函数lamdba首先,lambda表达式可以使代码变得简单,C++中,一个lambda表达式表示一个可调用的代码单元。如代码:...

EtherCAT运动控制卡开发教程之Qt(中):小线段连续轨迹加工

今天,正运动小助手给大家分享一下EtherCAT运动控制卡开发教程之Qt,主要介绍一下如何通过Qt编程实现小线段轨迹连续加工,暂停与继续。...

送亲人,用1小时制作精美电子相框 | Qt 示例

今天给大家分享:...

Python之面向对象:综合应用,基于GUI实现会动的游戏英雄

引言本打算以上一篇文章作为面向对象模块的收尾,但是,犹豫了许久,还是决定再补充一篇,也就是今天这篇文章,打算基于Python的PyQt6/PySide6框架开发一个GUI程序,模拟实现一个在电脑桌面活...

Qt——常用数据类型_qt基本数据类型

1.基础类型因为Qt是一个C++框架,因此C++中所有的语法和数据类型在Qt中都是被支持的,但是Qt中也定义了一些属于自己的数据类型,下边给大家介绍一下这些基础的数类型。...

取消回复欢迎 发表评论: