O_o,PO , BO , DTO , DAO , POJO 到底什么O是什么什么O?o_O(Java中这些对象的设计思想)
首先O_o和o_O是大眼瞪小眼的意思用来皮一下的嘿嘿o_O。好了现在正儿八经的说了。先来一个笼统的概念这些 O 都是 object 的意思也就是对象是用来承担Java项目当中不同的作用和功能的以此来降低程序的耦合性没有很大必要的重复部分和安全性实现各司其职的效果。就好比在社会当中不同的人会扮演不同的角色实现不同的作用。概念拆解POPersistent Object也就是持久化对象的意思持久化一般都是跟数据库对接相关的。这里的PO就是一个对象其中包含了与数据库相对应的结构一般就是由MyBatis这类的框架来进行驱动。这里来举一个例子就比如说我们的数据库里面有一张表 user ,里面的字段有 id , username , password , email , age ,create_time。然后这个时候我们要设计一个PO对象就应该是这样的//PO对象用于与数据中的表对应 public class UserPO { private Long id; private String username; private String password; private String email; private Integer age; private LocalDateTime createTime; //后面就是对应的get方法和set方法了 }可以看到PO对象里面的元素跟数据库表中的字段是一一对应的只是一个用的驼峰命名法另一个用的是下划线命名法。其实简单点来说PO也就是数据库某张表的一个代码上的复制品方便我们跟数据库对应上然后使用是数据库表的一种体现所以不要在这个里面写业务逻辑比如说去判断这个人成年了没有万一啥时候修改了成年的定义又得回来动这个表就没有办法保证他的纯净需要保证他的干净。DAOData Access Object也就是数据访问对象的意思我们主要在里面写一些对于数据库增删改查的逻辑一些业务逻辑也不在这里进行书写。这里我们还是基于刚刚举的那张表为例子。public interface UserDAO { //插入一个持久化对象 int insert(UserPO userPO); //根据id来进行查询 /*在这些方法的上面可以使用Select,Delete等注解来在声明函数的性质 比如是查询操作还是删除操作然后在注解当中书写SQL语句到时候 程序就可以通过执行里面的SQL语句来对数据库进行操作并且返回结果。 */ UserPO selectById(Long id) }我们可以使用传统的MyBatis方法通过在这个 selectById 的函数上面使用Select注解的方式来对这个函数进行实现也可以通过 xml 文件来映射这个对象然后在里面书写这个对象里面方 法的具体实现。同时我们也可以使用 MyBatis-Plus 来进行更快捷的处理方式只需要让这个对象继承 BaseMapper UserPO 来自动拥有 selectById , insert , update等十余种方法但是需要对PO对象先进行注解之后才能够让MyBatis-Plus发挥这个作用这里我们避免显得文章复杂冗长我想就把它再另写一篇小的文章吧DTOData Transfer Object也就是数据传输对象用于在不同的层级之间进行数据的传输通常来说会把如密码或者一些隐私信息给过滤掉相当于是一个尽职尽责的保安只给需要的东西。这里我们还是基于前面说的那张表来作为例子。// 用户注册时前端传来的数据 public class UserRegisterDTO { private String username; private String password; private String email; // 注册时不需要传 ID 和 createTime所以 DTO 不包含它们 } // Service层返给Controller的信息 public class UserDTO { private Long id; private String username; private String email; // 过滤掉了 password保证了安全 }可以看到DTO就是非常的抠搜要啥就只给啥不会多给这样也能确保我们数据的安全性。BOBusiness Object也就是业务对象我们在这里来封装我们的业务逻辑一个业务逻辑里面可能包含多个PO持久化对象算是起到一个零件组装的作用通过一些逻辑对一个或者多个PO进行操作实现我们想要的功能。public class UserBO { private UserPO userPO; // 业务逻辑判断用户是否成年 public boolean isAdult() { return userPO.getAge() 18; } // 业务逻辑计算用户账号等级 public String getRank() { // 根据 createTime 计算它是“老玩家”还是“新萌” return 黄金会员; } }VOView Object也就是试图对象。我们通过这个试图对象来让前端展示我们的一些数据同时可以在里面进行一些对前端友好化的操作比如说把日期给格式化public class UserVO { private String name; // 对应 username private String email; private String userRank; // 这是从 BO 计算出来的数据库里没有这个字段 private String joinDate; // 将 LocalDateTime 格式化为 2023年5月 这种字符串 }这样数据传输到前端的时候通过前端界面看起来就舒服多了所以VO也可以说就是拿来讨好前端的。POJOPlain Old Java Object这个也就是一个简单的Java对象有点像老农民的的感觉就很淳朴很干净。跟前面的PO有点像但是PO是对数据库上面的数据层面的这个POJO就是对于Java对象层面的。其实上面举的例子当中的 UserPO ,UserDTO ,UserVO, 也都可以算是POJO只要他们不去继承一些特殊的框架( 比如Hibernate的专用基类 )那也是一个干净的POJO了。小总结其实如果是一个很小的项目倒是没有必要去划分的那么细这样子搞这么多种对象反而是浪费时间精力一个 User 类就可以一直从头用到尾了当然一般是指的就是之间搓着玩的小玩意儿。但是如果是一个正儿八经的项目的话确实还挺有这个必要的我们可以从下面这些角度来看一下。从安全性来说咱们数据库当中还有password的字段这总不能就库库的也给前端都发过去了吧那还要那密码干啥捏而且这玩意儿你哪怕是加密了再发出来瞅着也不好看呐所以这就有扯到下一个问题了从网络和性能开销上面来说数据库里面那么多字段咱也总不能全给人家不管三七二十一的就一股脑全怼屏幕上了吧要人本来就只需要显示3个就够了你猛猛的把几十上百个全干出去了那也是不是不太中而且这多费劲儿呐。从耦合性角度上面来说要万一哪天突然灵光一现想着把数据库里面的哪个字段名改了那前端不得崩溃但是咱分层之后只要把PO到DTO上面的映射修改一些就完事儿了这不快活多了。从美观角度上面来说像咱后端存时间基本就是一个 Long 的一大长串也就咱自己看看还好这要放前端那不难为人家吗是吧那这个时候我们分出来的 VO 也就派上用场了人瞅感觉还整挺好不光咱能看明白让别人也能看明白。好了以上就是我个人的一些理解也就把概念稍微捋了一捋当然可能还是会存在言辞表达的可能不是很好的地方请各位大佬们多多包涵如果有更好的理解的话也可以分享出来我们一起学习哈o_O