Java中各种O(PO,BO,DTO,VO等) 是不是人为增加系统复杂度?

news2024/9/20 18:53:44

Java中各种O(PO,BO,DTO,VO等) 是不是人为增加系统复杂度?

在Java和其他编程语言的开发过程中,经常会用到几个以"O"结尾的缩写,比如PO,BO,DTO,VO等等,O在这里是Object的缩写,不同的O代表了不同的数据类型,很多时候这些O中的属性看起来都是差不多的,干的事情好像也只是一个简单的封装,那么搞出这么多O出来是不是人为增加了系统的复杂度呢?

各种O都是干什么的?

想要搞清楚标题中的问题,我们首先得了解这些O都是什么东西?这里给大家介绍几种常见的O:

  1. PO (Persistent Object) - 持久化对象。持久化对象通常对应数据库中的一个表,主要用于表示数据库中存储的数据。PO中的属性通常和数据表的列一一对应,用于ORM(对象关系映射)框架中,如Hibernate,JPA等。
  2. BO (Business Object) - 业务对象。业务对象主要封装了业务逻辑。它可以包含多个PO,或者是一个PO的扩展,增加了业务处理的逻辑。BO通常在业务层被使用,用于实现业务操作,比如计算、决策等。
  3. VO (Value Object) - 值对象。值对象是一种用于传输数据的简单对象,它通常不包含业务逻辑,只包含数据属性和get/set方法。值对象主要用于业务层与表示层之间的数据传递,它的数据可能是由多个PO组合而成。
  4. DTO (Data Transfer Object) - 数据传输对象。数据传输对象类似于VO,它也是用于层与层之间的数据传递。DTO通常用于远程通信,比如Web服务之间的数据传递。DTO通常不包含任何业务逻辑,只是用于在不同层次或不同系统之间传输数据。

有时候我们还会看到DO、POJO等概念,它们又是什么呢?

  1. DO (Domain Object) - 领域对象。领域对象是指在问题领域内被定义的对象,它可以包含数据和行为,并且通常代表现实世界中的实体。在DDD(领域驱动设计)中,领域对象是核心概念,用于封装业务逻辑和规则。这里需要注意DO和BO的区别,虽然都是搞业务逻辑,DO通常是业务领域中单一实体的抽象,它关注于单个业务实体的属性和行为;而BO则通常涉及到业务流程的实现,可能会协调多个DO来完成一个业务操作。
  2. POJO (Plain Old Java Object) - 简单老式Java对象。POJO是指没有遵循特定Java对象模型、约定或框架(如EJB)的简单Java对象。POJO通常用于表示数据结构,它们的实例化和使用不依赖于特定的容器或框架。

为什么要划分各种O?

在软件开发中划分不同的O主要是为了实现关注点分离(Separation of Concerns,SoC),提高代码的可维护性、可读性和可扩展性。

下面展开列举了一些划分这些对象的原因:

  1. 明确职责:通过将不同的职责分配给不同的对象,可以使每个对象都有明确的职责,这样代码更容易理解和维护。
  2. 减少耦合:不同层次之间通过定义清晰的接口(如特定的对象)交互,减少了直接的依赖关系,降低了耦合度。
  3. 抽象层次:通过定义不同的对象,可以在不同的抽象层次上操作,比如在数据层处理PO,在业务层处理BO,这样可以在合适的层次上做出决策。
    • 灵活性:当系统需要变更时,由于职责和层次的清晰划分,更容易做出局部的修改而不影响到整个系统。不同的对象可能针对性能有不同的优化,例如PO可能被优化以提高数据库操作的性能。
    • 安全性:通过使用不同的对象,可以控制敏感数据的暴露。例如,可以在DTO中排除一些不应该传输到前端的敏感信息。
    • 测试性:分离的对象使得单元测试变得更加容易,因为可以针对每个对象进行独立的测试。
  1. 交互清晰:在不同的系统组件或层次之间传递数据时,清晰的对象定义可以让数据交互更加清晰,减少数据传递中的错误。

总之,通过划分各种“O”对象,开发者可以更好地组织代码,将复杂系统分解为更小、更易于管理的部分,同时也有助于团队成员之间的沟通和协作。这种划分在设计模式和软件工程实践中是一种常见且有效的方法。

OO不分的惨痛经历

说个实际的惨痛经验。

很多时候我会感觉这些O之间存在很多重复的代码,比如重复的属性定义、简单的方法封装,DRY(Don't Repeat Yourself)原则不是说让大家避免重复嘛,所以我也曾经尝试在程序中统一它们。

但是总有一些O之间存在或多或少的差异,比如:

  • 这个O需要一个A属性,仅用于内部状态管理,不会暴露到外部,其它O都不需要。
  • 还有这个接口需要返回一个B属性,其它接口都不需要。

这时候,你怎么办?如果使用同一个类型,那就得加上这些属性,尽管它们在某些时候用不到。根据你的选择,你可能在所有的地方都给这个属性赋值,也可能仅在业务需要的时候给他们赋值。

看个实际的例子:在一个复杂的电商系统中,商品的管理可能涉及到库存管理、价格策略、促销信息等多个方面。

// 商品类
public class Product {
    private Long id; // 来自商品表
    private String name; // 来自商品表
    private double price; // 来自商品表,传输时需要特殊格式
    private int stock; // 来自库存表,仅在下单判断中需要,展示层不需要
    private String promotionInfo; // 来自促销表,展示层需要

    // 构造器、getter和setter方法省略
}

但是这却带来了很大的危害:

  • 调用接口的同学会问,这个属性什么时候会有值,什么时候会没值?
  • 优化的同学会问,计算这个属性的值会影响性能,能删掉吗?
  • 交接的同学会问,这个属性是干什么用的,为什么不给他赋值?

总之会增加了大量的沟通成本与维护难度。一旦这样做了,后边就会特别别扭,改不完,根本改不完。

在软件工程化的今天,各类O的设计看似增加了复杂度,但是实际上是对系统模块化、职责划分以及实际应用场景的合理抽象和封装,有助于提高软件质量和团队协作效率。

老老实实写吧,不同的O就是不同的东西,它们不是重复的,只是在代码上看着像,就像人有四肢,动物也有四肢,但是它们不能共用,否则出来的就是四不像。

图片来源:https://ozhanozturk.com/2018/01/28/chimera-kimera-mitoloji/

当然如果只是一个很简单的程序或者一次性的程序,我们确实没必要划分这么多的O出来,直接在接口方法中访问数据库也不是不可以的。

前端中O的使用

虽然各种O一般活跃在各种后端程序中,但是前端也不乏O的身影,只是没有后端那么形式化。

以下是一些可能在前端开发中遇到的以“O”结尾的数据对象:

  1. VO (View Object) - 视图对象。在前端框架中,VO可以代表专门为视图层定制的数据对象。这些对象通常是从后端接口获取的数据经过加工或格式化后,用于在界面上显示的对象。
  2. DTO (Data Transfer Object) - 数据传输对象。虽然DTO通常用于后端服务间的数据传输,但在前端中也可以用来表示从后端接口获取的数据结构。前端的DTO通常是指通过Ajax或Fetch API从服务器获取的原始数据结构。
  3. VMO (ViewModel Object) - 视图模型对象。在MVVM(Model-View-ViewModel)架构中,VMO可以代表视图模型对象,它是模型和视图之间的连接器。在Vue.js中,Vue实例本身就可以被看作是一个VMO,因为它包含了数据和行为,同时也是视图的反映。
  4. SO (State Object) - 状态对象 尽管不是标准的术语,但在使用如Vuex这样的状态管理库时,SO可以用来指代代表应用状态的对象。这些状态对象通常包含了应用的核心数据,如用户信息、应用设置等。

在实际的Vue开发过程中,开发者可能不会严格区分这些概念,而是更多地关注于组件的状态、属性(props)、事件和生命周期。组件内部的数据通常以数据属性(data)的形式存在,而组件间的数据传递通常使用属性(props)和事件(emits)。在处理与后端的数据交互时,开发者可能会定义一些专门的对象来适应后端的接口,但是这些都不是Vue框架强制的概念或规则。


简单地说,这些“O”其实就是帮我们把代码写得更清晰、更有条理,虽然一开始看着很麻烦,但时间一长,你会发现这样做能省下不少力气。就像我们的衣柜,虽然分类放好衣服需要点时间,但每天早上起来挑衣服的时候,不就轻松多了吗?

所以,别被这些专业术语吓到,它们其实就是帮我们把事情做得更好的小工具。每个“O”都有它的用处和场景,我们要做的,就是搞清楚什么时候戴哪顶帽子,这样生活和编程都能变得轻松愉快。记住,合适的工具用在合适的地方,能让你事半功倍!

关注萤火架构,加速技术提升!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1465347.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

运维SRE-06 阶段性复习软件管理体系

那些年运维必会操作-第一弹 操作 文件:增删改查 增:touch,vim,>,>>,cp删除:rm修改:内容:vi/vim,>,>> 文件名:mv查看:内容:cat/vim/less/more/head/tail/sed/awk/…

紫光同创初使用

芯片PGC2KG-6LPG144 1、安装好软件接,加载license,有两个,与电脑MAC地址绑定的 2、正常使用后,新建个工程,配置管脚Tools→UCE 3、程序中有些信号被软件认为是时钟信号,会报错(时钟输入I0约束在非专用时钟…

Java项目:25 基于JavaWeb的酒店管理系统

作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 基于JavaWeb的酒店管理系统是为酒店打造的管理平台,其主要功能有管理员登陆、客房预订、客房入住、房间管理、数据查询(预订单查询…

The Grapes NFT 概览与数据分析

作者:stellafootprint.network 编译:cicifootprint.network 数据源:The Potatoz NFT Collection Dashboard The Potatoz 是在以太坊链上铸造的 9,999 个 PFP NFT 系列。该系列是 Memeland 的延伸,也是其充满活力、快速发展的社…

9、使用 ChatGPT 的 GPT 制作自己的 GPT!

使用 ChatGPT 的 GPT 制作自己的 GPT! 想用自己的 GPT 超越 GPT ChatGPT 吗?那么让我们 GPT GPT 吧! 山姆 奥特曼利用这个机会在推特上宣传 GPTs 的同时还猛烈抨击了埃隆的格罗克。 GPTs概览 他们来了! 在上周刚刚宣布之后,OpenAI 现在推出了其雄心勃勃的新 ChatGPT…

ISO26262 --- FSC功能安全概念

一、目的 a)按照安全目标,定义相关项功能行为或降级的功能行为 b)按照安全目标,定义用于合理,及时地探测和控制相关故障的约束条件 c)定义相关项层面的策略或者措施,通过相关项自身,驾驶员或外部措施来实现要求的故…

WebService学习,wsdl文件详解

目录 第一章、起因1.1)学习原因1.2)提问的过程(逐步提出问题)1、?wsdl链接的含义,有什么作用?2、什么是wsdl文档?3、如何阅读wsdl文件?4、wsdl文件有什么作用&#xff1f…

掼蛋之还贡技巧

掼蛋游戏的规则之一就是进贡和还贡以及抗贡,只要末游没能抗贡,那么就必须把最大的那张牌贡给头游,头游也要选一张牌还给末游。那么我们该如何还贡呢? 一、忌单张 尽量不要还自己的单张,因为自己的数量少,有…

靡语IT:Vue精讲(一)

Vue简介 发端于2013年的个人项目,已然成为全世界三大前端框架之一,在中国大陆更是前端首选。 它的设计思想、编码技巧也被众多的框架借鉴、模仿。 纪略 2013年,在Google工作的尤雨溪,受到Angular的启发,从中提取自…

如何在Shopee平台上进行杯子选品:策略指南

在当今电商平台激烈竞争的环境下,卖家在Shopee平台上进行杯子选品需要经过深思熟虑的策略。通过市场趋势分析、竞品研究、产品差异化、供应链稳定性、利润分析、季节性和节日考量、客户反馈、营销策略、数据驱动选品以及持续优化,卖家可以提高杯子产品在…

基于全卷积网络的彩色显微图像光照不均匀校正

参考:论文英文题目:Correction of uneven illumination in color microscopic image based on fully convolutional network 参考论文链接:https://opg.optica.org/oe/fulltext.cfm?urioe-29-18-28503&id457387 在做显微图像相关任务是…

离散化学习笔记(超详细)

离散化学习笔记 什么是离散化 对于“什么是离散化”,搜索帖子你会发现有各种说法,比如“排序后处理”、“对坐标的近似处理”等等。哪个是对的呢?哪个都对。关键在于,这需要一些例子和不少的讲解才能完全解释清楚。 离散化是程序…

微服务篇之分布式系统理论

一、CAP定理 1.什么是CAP 1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标: 1. Consistency(一致性)。 2. Availability(可用性)。 3. Partition tolerance &#xff0…

APEX开发过程的一个细节

开发过程中发现有一些特殊代码命名有要求 比如 代码: select "project_id",null LINK_CLASS,apex_page.get_url(p_items > P201_PROJECT_ID, p_values > "project_id") LINK,null ICON_CLASS,null LINK_ATTR,null ICON_COLOR_CLASS,cas…

Sora----打破虚实之间的最后一根枷锁----这扇门的背后是人类文明的晟阳还是最后的余晖

目录 一.Sora出道即巅峰 二.为何说Sora是该领域的巨头 三.Sora无敌的背后究竟有怎样先进的处理技术 1.Spacetime Latent Patches 潜变量时空碎片,建构视觉语言系统 2.扩散模型与Diffusion Transformer,组合成强大的信息提取器 3.DiT应用于潜变量时…

【python 的各种模块】(10) 在python3使用turtle 模块画图

目录 1 在anaconda里用python3安装turtle 1.1 因为turtle 本来是适应python2的,所以直接安装报错 1.2 准备好手动下载,官网下载安装包 1.2.1 去官方手册看了下,其实是支持python3的 1.2.2 官网下载,手动安装 1.3 解决办法&…

【Spring】IoC容器 控制反转 与 DI依赖注入 配置类实现版本 第四期

文章目录 基于 配置类 方式管理 Bean一、 配置类和扫描注解二、Bean定义组件三、高级特性:Bean注解细节四、高级特性:Import扩展五、基于注解配置类方式整合三层架构组件总结 基于 配置类 方式管理 Bean Spring 完全注解配置(Fully Annotatio…

MATLAB环境下基于短时傅里叶变换和Rényi熵的脑电信号和语音信号分析

傅里叶变换是不能很好的反映信号在时域的某一个局部范围的频谱特点的,这一点很可惜。因为在许多实际工程中,人们对信号在局部区域的特征是比较关心的,这些特征包含着十分有用的信息。这类信号因为在时域(或者是空间域)上具有突变的非稳定性和…

切比雪夫(最小区域法)圆拟合算法

欢迎关注更多精彩 关注我,学习常用算法与数据结构,一题多解,降维打击。 本期话题:切比雪夫(最小区域法)直线拟合算法 相关背景和理论 点击前往 主要介绍了应用背景和如何转化成线性规划问题 圆拟合输入和…