写点什么

Nuxt Apps 中的领域驱动设计实践

  • 2020-12-08
  • 本文字数:2479 字

    阅读完需:约 8 分钟

Nuxt Apps中的领域驱动设计实践

我在Vue StorefrontVue Storefront Next中实验 Vue apps 的领域驱动方法有一段时间了。使用这种方法能显著改善你的代码库的可维护性和复杂度。在这个系列,我想分享一些在 Vue Storefront 中对我们有效,且容易应用到任何 Vue 应用程序中的模式。


我将展示如何在 Nuxt 和“普通”Vue 项目中如何应用这些模式。本文中,我们将聚焦理论和 Nuxt 实现。


什么是领域驱动设计?


领域驱动设计(Domain-Driven Design,DDD)概念是,将业务概念优先于代码库的其它分类类型(例如,按文件类型分组)。这意味着,你应该基于你主要的业务领域(“问题”)及其子领域(问题的细分部分)来组织你的代码。例如,在电子商务领域,我们有产品目录、客户、订单、库存等子领域。


虽然 DDD 概念来自面向对象编程,依赖于类及其关系,但其核心理念可以很容易地应用到其它范式。


为什么领域驱动设计很棒?


领域驱动设计越来越受欢迎最简单的解释是,它是一种非常简单的模式,在大多数情况下,它都会在编程最困难和最痛苦的领域之一——代码维护性上带来显著改善。


我记得,我在思考组织代码库的最佳方式时度过的无眠之夜和漫长的淋浴。如果你曾经尝试过,你就会明白这项任务非常困难,而且结果永远不会完美,因为你必须考虑到你的项目在将来可能演变的所有可能的方式。随着时间的推移,我们对试图解决问题的理解不断增长,这会带来更有效的解决问题的方法,从而改变我们最初的方案。


我们都经历过并且知道,改变最初的架构会付出多大的成本。


这就是领域驱动设计的亮点。基于业务需求对系统进行建模要容易得多,因为这个方案不受技术限制和困难的影响。我们改变核心业务需求的频率比改变底层技术的频率要少得多。


此外,领域驱动设计推崇在编写代码时考虑实际的业务需求,这意味着我们根据业务功能(例如客户)而不是技术术语(组件、存储、服务),来组织我们的代码和文件结构。这种管理代码的方式让代码更容易维护。


下图显示了一个“标准的”Vue 文件结构 vs 基于业务领域的文件结构:




如果与某个功能相关的所有东西都放在一个地方,就会很容易理解它是如何工作的,因为不存在忽略某些部分的风险。完全删除某个功能也同样非常简单,因为这个功能相关的代码不会分布在整个代码库中。


另一个好处是,我们只需查看应用程序的文件夹结构,就能很容易地推断出其业务和功能。这也很容易找到一个开始上手的地方,因为我们的任务大部分时候是用业务语言编写的。我能够给出很多其它例子,但是我确信你已经明白为什么这个方案现在被认为是更容易维护的了。


领域驱动设计和根据功能组织代码的最大好处之一,就是限制了不同模块之间的关联数量。通常,我们在应用程序中有一组扩展点被所有模块使用。理想情况下,所有的连接都应该通过一个单独的地方进行,例如一个共享模块或事件总线。使用这种方法更容易维护这些模块,因为连接不同功能的部分通常是导致应用程序复杂性增加最多的地方。如果我们设法避免不必要的复杂性并简化连接,那么让你的代码库保持简单也就非常容易了。


弄清楚如何使你的模块独立并封装,是另外一篇文章(或者是一系列文章)的主题,因此现在如果你想要深入了解这一点,我建议你阅读hexagonal architecture,并应用这种方法中的大部分有用的理念。


那么,我们该如何在 Vue 中应用领域驱动设计理念呢?


Nuxt 中的领域驱动设计


我们从 Nuxt 开始介绍,它有了一个很好的内置机制,使得应用这个理念非常容易——模块。


Nuxt 模块通常用于在你的应用程序中包含第三方功能,例如授权或 i18n。虽然编写第三方代码是最常用的利用它们的方法,但是 Nuxt 模块也可以很好地在我们的内部架构中发挥作用。


因为 Nuxt 模块可以挂接到应用程序的不同部分,例如路由或 Vuex store,所以我们能很容易地使它成为一个特定子领域与我们的应用程序连接的唯一地方!


看看这个简单的 Nuxt 模块:

// index.jsmodule.exports = function ProductCatalogModule (moduleOptions) {  this.extendRoutes((routes) => {    routes.unshift({      name: 'product',      path: '/p/:slug/',      component: path.resolve(themeDir, 'pages/Product.vue')    });  );  // we can't register stores through Nuxt modules so we have to make a plugin  this.addPlugin(path.resolve(__dirname, 'plugins/add-stores.js'))}
复制代码


// plugins/add-stores.jsimport CategoryStore from '../stores/category.js'import ProductStore from '../stores/product.js'
export default async ({ store }) => { store.registerModule(CategoryStore) store.registerModule(ProductStore)};
复制代码


…有如下文件:


.├── pages|   |── Category.vue │   └── Product.vue├── components|   |── ProductTile.vue│   └── ProductGallery.vue├── plugins│   └── add-stores.js├── store|   |── category.js│   └── product.js└── index.js
复制代码

我们这里就是一个小的 Nuxt.js 应用程序,专注于我们的应用程序的某一个子领域。现在,当我们想要在应用程序中包含所有目录相关的功能时,我们只需要一行代码就可以做到这一点!


// nuxt.config.jsexport default {  modules: [    '~/modules/product-catalog/index.js',  ]}
复制代码


现在,每当我们在 Jira 中看到产品目录相关的问题时,我们就会立即知道从哪里开始改。而且,使用这种模块化方案,新来的人也能很快知道我们应用程序中有什么功能,因此可以更快地理解业务和技术背景!


.├── pages│   └── index.vue├── modules|   |── product-catalog|   |── orders|   |── payment|   |── shipping|   |── inventory│   └── customers└── index.js
复制代码


总结与展望


基于业务领域及其子领域来组织代码,是使应用程序更易于维护的最简单有效的方法之一。尽管还有一些已知的挑战,例如不同模块之间的通信,了解基础知识就足以为代码库带来巨大的好处。应用本文中的模式不需要高级编程技巧,这让所有层次的开发人员都可以使用它。


原文链接:


https://vueschool.io/articles/vuejs-tutorials/domain-driven-design-in-nuxt-apps/

2020-12-08 14:511666
用户头像

发布了 165 篇内容, 共 76.6 次阅读, 收获喜欢 343 次。

关注

评论

发布
暂无评论
发现更多内容

TDengine 签约青山钢铁,实现冶金全流程质量管控智能化

TDengine

数据库 tdengine 时序数据库

圆满解决!13/14代酷睿不稳定问题更新可解决,性能没影响

E科讯

如何快速开发一个受欢迎的小说听书软件平台?看这里!

软件开发-梦幻运营部

深入浅出React中的refs

高端章鱼哥

DevOps 组织的建设密码——人才胜任力模型全解析

嘉为蓝鲸

Cisco Catalyst 9800-CL IOS XE 17.15.1 发布下载,新增功能概览

sysin

Cisco 9800 WLC IOS-XE

用豆包MarsCode,这不直接”躺“了嘛!

豆包MarsCode

人工智能 程序员 AI 智能化

地平线静态目标检测 MapTR 参考算法-V1.0

地平线开发者

自动驾驶 算法

技术引领筑生态,万物智联创未来 第三届OpenHarmony技术大会即将盛大启幕

最新动态

OpenAI为高级语音模式添加五种声音,已正式推出!华为发布业界首个L4自动驾驶网络|AI日报

可信AI进展

AI西游记:企业如何闯过大模型的「火焰山」?

白洞计划

AI

运营商实战成果——分布式架构可观测能力建设全攻略

嘉为蓝鲸

可观测产品剖析:调用链追踪

嘉为蓝鲸

IT外包在不同行业的应用案例

Ogcloud

IT外包 IT外包公司 IT外包服务 IT外包企业 IT外包服务商

三大硬核方式揭秘:Java如何与底层硬件和工业设备轻松通信!

不在线第一只蜗牛

Java Python

为什么说3-8岁的行为塑造奠定孩子的一生?

心大陆多智能体

AI大模型 心理健康 数字心理

一文掌握DevOps落地的终极实践,8大关键路径揭秘!

嘉为蓝鲸

观测云链路追踪分析最佳实践

观测云

链路追踪

如何评估和观测 IoTDB 所需的网络带宽?

Apache IoTDB

Cisco ASA 9.22.1 发布下载,新增功能概览

sysin

防火墙 Cisco ASA

Cisco Catalyst 9800 系列无线控制器 IOS XE 17.15.1 发布下载,新增功能概览

sysin

Cisco 9800 WLC 无线控制器

可观测产品剖析:业务监控

嘉为蓝鲸

技术分享丨实现跨区域虚拟专用网络互联

伊克罗德信息科技

虚拟专用网络

嘉为蓝鲸日志中心助力某省城商行,运维效率提升60%

嘉为蓝鲸

低代码开发平台:未来五大发展趋势预测

不在线第一只蜗牛

低代码

如何创建一个Java游戏客户端

快乐非自愿限量之名

Java Python 游戏

挖掘汽车论坛数据,发现行业新商机

八爪鱼采集器︱RPA机器人

爬虫 采集

望繁信科技携手甫瀚咨询共建流程挖掘产业生态

望繁信科技

数字化转型 业务流程管理 流程挖掘 流程资产 流程智能

Golang优雅关闭gRPC实践

俞凡

golang

山丹县综能智慧新能源:“智能二维码”,推动班组管理信息化

草料二维码

草料二维码

七猫如何用 StarRocks 打造用户增长新引擎?

StarRocks

Nuxt Apps中的领域驱动设计实践_文化 & 方法_Filip Rakowski_InfoQ精选文章