日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

POJO分层领域模型

發(fā)布時(shí)間:2024/1/1 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJO分层领域模型 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

POJO分層領(lǐng)域模型

前言

當(dāng)你百度一下 po,jo,dto,vo,bo,entity,model,于是,網(wǎng)上出現(xiàn)這樣,啊,呸!臘雞,沒一個(gè)說的明白的,要么就是拉一個(gè)阿里巴巴的規(guī)范,要么就是光有概念,沒有實(shí)際,或者說得云里霧里,對(duì)于看到本文的各位 極客,不妨來跟我一探究竟吧!

首先,像阿里巴巴這種級(jí)別的公司,和其他的中小型公司,不可相提并論,所謂最好的架構(gòu),不是什么 消息隊(duì)列,緩存都往上堆的,要適合當(dāng)前項(xiàng)目的才是最好的架構(gòu),是吧。所以本文為了能夠給各位同學(xué)講解清晰,先從簡(jiǎn)單的,常見的開始吧!

本文是按照,前后端分離,講解,不提供類似 JSP,Thymeleaf 模板引擎 這種不分離的講解。

會(huì)設(shè)計(jì)到 SOA 面向服務(wù)架構(gòu),SpringCloud 微服務(wù)架構(gòu),最好有一定的開發(fā)經(jīng)驗(yàn)

阿里巴巴規(guī)約

由于阿里巴巴的規(guī)范被廣泛流傳,顯然,很多人被規(guī)范中的 manger,vo,query 搞得暈頭轉(zhuǎn)向

之前咱不是說了嗎,最適用的才是最好的架構(gòu),我也想住大別墅啊,可以工資不允許啊。我有裝修別墅的圖紙,你有別墅嗎?

別急,后面會(huì)帶你慢慢看懂這幾層架構(gòu),和上面分層規(guī)約的。看的時(shí)候最好把這玩意畫在紙上,或者截圖哦。

常見的 O

當(dāng)然,這里不僅僅是收集了 阿里巴巴規(guī)約上的 Do,Dto ,Bo,Query,Vo,還有其他地方的規(guī)范,以及各種 DAO,PO,POJO,Model,Entity,啊啊啊,我要崩潰了,怎么這么多啊,亂七八糟的。

O 指的是 Object,也就是對(duì)象,面向?qū)ο蟮耐瑢W(xué)應(yīng)該都不陌生。

名稱英文中文說明
POJOPlan Ordinary Java Object普通的 Java 對(duì)象瞧瞧這名字,多普通啊
DaoData Access Object數(shù)據(jù)訪問對(duì)象這其實(shí)特別容易區(qū)別,下面的文章待會(huì)講
DtoData Transfer Object數(shù)據(jù)傳輸對(duì)象有點(diǎn)繞了,啥玩意叫 Transfer 傳輸啊,這有歷史錯(cuò)誤
PoPersistant Object持久化對(duì)象哦豁,阿里巴巴規(guī)范可沒這玩意啊
DoData Object數(shù)據(jù)對(duì)象
BoBusiness Object業(yè)務(wù)隊(duì)對(duì)象嗐,業(yè)務(wù)掛鉤的唄
AoApplication Object應(yīng)用對(duì)象應(yīng)用?怎么感覺和 業(yè)務(wù) Bo 差不多呢
VoValue Object / View Object值對(duì)象 / 視圖對(duì)象啥,還有2種解釋?
QueryQuery查詢咋混個(gè)這玩意進(jìn)來?
ModelModel模型啥玩意是模型,
EntityEntity實(shí)體啥玩意是實(shí)體,
BeanBeanbean 對(duì)象啥玩意是bean,

如何使用

點(diǎn)我查看在線POJO 分層模型

三層架構(gòu)

那么先從最簡(jiǎn)單的 Controller,Service,Dao 入手。這是最經(jīng)典的三層架構(gòu)。

這里的前端,不一定是指瀏覽器,也有可能是 app,小程序,不管是 B/S 架構(gòu),還是 C/S 架構(gòu),我們后端如果使用 Spring,還是 SpringBoot,還是 SpringCloud,下面的這張圖,應(yīng)當(dāng)是很熟悉的。

Controller

以用戶的增刪改查為例

  • 新增
    • 這種情況一般是會(huì)攜帶表單數(shù)據(jù)提交上來的,比如 用戶昵稱,手機(jī)號(hào),性別等。那我們用什么 O 呢?,別急,先看看哪里會(huì)用到對(duì)象
  • 查詢
    • 批量查詢
      • 在批量查詢列表的時(shí)候,查詢也是攜帶一些查詢條件,比如性別,姓名模糊查詢,分頁(yè)的page 和 rows 等
      • 額外吐槽一句,為啥分頁(yè)會(huì)有人用 pageSize 和 pageNum 啊????強(qiáng)烈推薦用 page 和 rows 啊!!!!
      • 那么用什么 O 來封裝這些 姓名,模糊查詢,日期呢?
    • 單條查詢
      • 一般單條信息的查詢會(huì)使用 主鍵id,可能會(huì)寫在 請(qǐng)求路徑中
  • 修改
    • 修改的時(shí)候一般會(huì)根據(jù)主鍵去修改,然后攜帶最新的表單數(shù)據(jù),新的昵稱,新的家庭住址,用什么 O 呢?
  • 刪除
    • 單條刪除的話,一般使用主鍵id 就可以了,當(dāng)然很多情況下是邏輯刪除,并不是真刪
    • 批量刪除的話,就需要一個(gè)列表來接收了。用什么 O 呢?,這種情況一般只需要這個(gè)樣子就可以了,并不需要額外的對(duì)象封裝

來看看 阿里巴巴規(guī)約

  • 從網(wǎng)頁(yè),APP 前端傳輸過來,進(jìn)入到 Controller 層,用什么接收

    • 新增和修改,使用 DTO

    • 查詢使用 Query

    • 理由

      • DTO 被翻譯成 Data Transfer Object 數(shù)據(jù)傳輸對(duì)象本身就是錯(cuò)誤的transfer 應(yīng)當(dāng)被翻譯成 轉(zhuǎn)移transport 才是真正的 傳輸HTTPS 超文本傳輸協(xié)議,這本身就是歷史理由問題,可以參考 https://baike.baidu.com/item/超文本轉(zhuǎn)移協(xié)議/1675080?fr=aladdin在 ISO 七層網(wǎng)絡(luò)模型中應(yīng)用層 HTTPS 應(yīng)當(dāng)是轉(zhuǎn)移,但是由于歷史翻譯原因表示層會(huì)話層傳輸層 TCP/UDP 指 端到端 (ip:port 到 ip:port) 傳輸比特網(wǎng)絡(luò)層數(shù)字鏈路層物理層
      • 由于歷史悠久,錯(cuò)誤的就當(dāng)成正確的吧,你總不能天天喊著,中國(guó)的國(guó)寶是 貓熊 吧!那么我們就把 DTO 當(dāng)成 數(shù)據(jù)傳輸對(duì)象

      • 前端 到 后端符合傳輸?shù)恼Z義,而且新增和修改的數(shù)據(jù)模型一般是一致的,新增的用戶信息有多少,修改的字段一般也是大致相同的

    • 爭(zhēng)議

      • 查詢使用 Query 還是 Dto,博主本人更傾向 查詢使用 Query
      • 因?yàn)椴樵?和 新增修改本身字段就不同,而且 Query 更符合查詢的語義,分頁(yè)查詢一般提取父類 page 和 rows
      • 如果使用 Dto 來接收數(shù)據(jù),新增用戶是 UserDto,查詢用戶的查詢字段也是 UserDto,命名容易沖突。
  • 從到 Controller 層返回給前端,用什么

    • 返回使用 Vo
    • 理由
      • VO 有的地方當(dāng)做 Value Object,有的地方規(guī)范當(dāng)做 View Object,博主更傾向于 View Object
      • 根據(jù)上述傳輸使用 DTO,如果從后端向前端也使用 DTO,那么會(huì)造成 DTO 命名沖突,傳進(jìn)來是 UserDto,傳出去也是 UserDto
      • 那么兩個(gè) Dto 能夠復(fù)用嗎?不行,因?yàn)閭鬟M(jìn)來的可能有很多字段,而返回出去的可能并不需要那么多字段,部分敏感信息不應(yīng)當(dāng)返回。
      • DTO,Query,Vo,一看就知道,哪個(gè)是干嘛的?

Dao

Dao Data Access Object 數(shù)據(jù)訪問對(duì)象 ,這個(gè)一般情況是 Mybatis 的接口層,比如 UserDao。UserMapper 等

如果使用像 SpringDataJPA 這種,這一層的命名可能是 UserReposritory,

Dao 其實(shí)就不應(yīng)該拿到 pojo 分層領(lǐng)域模型來講,因?yàn)橹v的根本不是一個(gè)東西。

眾所周知,在國(guó)內(nèi)是以 Mybatis 占主流,而全局開發(fā)者調(diào)查中,SpringDataJPA 的市場(chǎng)占有份額也極高,這就是 ORM 的區(qū)別

以 Mybaits 為首的半自動(dòng)映射,和 hibernate,SpringDataJPA 全自動(dòng)映射,的兩種策略來說明

Po Persistant Object 持久化對(duì)象,這個(gè)說法常常見于 Mybatis,SpringDatJPA,MybatisPlus 這些持久層框架的文檔中,就是 Java 對(duì)象與數(shù)據(jù)庫(kù)表的對(duì)應(yīng)

Do Data Object 數(shù)據(jù)對(duì)象,阿里巴巴開發(fā)規(guī)范,此對(duì)象與數(shù)據(jù)庫(kù)表結(jié)構(gòu)一一對(duì)象

這2個(gè)也是爭(zhēng)議極大的。

博主根據(jù)使用 Mybatis 和 SpringDataJPA 操作 MySQL 的經(jīng)驗(yàn)來看,更傾向于 全自動(dòng)映射使用 PO,半自動(dòng)映射使用 DO,包括像 MongoDB 類似的非關(guān)系型數(shù)據(jù)庫(kù)也是如此。

Java 中一個(gè) User 對(duì)象有 10 個(gè)屬性,數(shù)據(jù)庫(kù)表中 sys_user 有10個(gè)字段,這種完全一一對(duì)應(yīng)的。下文稱為“完全映射”

以 Mybatis 舉例,在多表關(guān)聯(lián)查詢的時(shí)候,從3張表中分別抽取2個(gè)字段,組合成新的一個(gè)對(duì)象,這種對(duì)象是無法 完全映射的。屬于臨時(shí)組合出來的對(duì)象。

以 SpringDataJPA 舉例,使用 @OneToMany @ManyToMany 仍然可以通過對(duì)象的完全映射到數(shù)據(jù)庫(kù)表

Do 還可以用作領(lǐng)域驅(qū)動(dòng)的對(duì)象。后文再講。這里略過。

Service

以增刪改為例

從 Controller 層,傳給 Service 層,仍然是 UserDto,UserQuery。但是這一層是需要進(jìn)行處理的。不可以直接與數(shù)據(jù)庫(kù)交互

比如 Dto 傳過來的時(shí)候,沒有 狀態(tài),沒有創(chuàng)建時(shí)間,沒有創(chuàng)建人,而且如果有設(shè)計(jì)不規(guī)范的時(shí)候,比如 Dto 里是一個(gè)列表,但是數(shù)據(jù)庫(kù)是一個(gè)字符串

需要將 將 dto 里的 carIds 轉(zhuǎn)成 字符串,再塞入到 po 里,所以 service 里可能像下面這樣寫。

比如 Query 里的查詢條件是字典值,傳過來的是男,我們要轉(zhuǎn)成 1,再去 數(shù)據(jù)庫(kù)查詢

service 中的查詢,從數(shù)據(jù)庫(kù)查詢出來的 Po,或者 Do,也是不可以直接返回出去的,需要將一些數(shù)據(jù)進(jìn)行處理,比如將密碼置為 * 號(hào),比如文件大小 10240 轉(zhuǎn)成 10MB,圖中的創(chuàng)建時(shí)間其實(shí)可以在 vo 里用@JsonFormat 設(shè)置,或者框架統(tǒng)一設(shè)置,這里用的老圖,

Bo 里可以隨便添加字段,可以當(dāng)成一個(gè)中間處理的對(duì)象,比如 原本文件大小的字段叫 fileSize 是數(shù)值型的,可以在 bo 里加一個(gè) fileSizeHuman ,字符串類型的,然后 vo 里使用 fileSizeHuman來接收,一般都使用統(tǒng)一的 bean 轉(zhuǎn)換工具類。

這就是 service 層

SOA 架構(gòu)

SOA 架構(gòu),以 dubbo + zookeeper 為代表的 SOA 面向服務(wù)的架構(gòu)風(fēng)格,controller 和 service 部署在不同的機(jī)器上,這時(shí)候需要注冊(cè)到 注冊(cè)中心上去,

就會(huì)需要對(duì)象序列化,就會(huì)有 對(duì)象傳輸 的場(chǎng)景,

那么在這種情況之下,對(duì)象傳輸就不是直接返回給 controller,而是有一個(gè)網(wǎng)絡(luò)傳輸?shù)倪^程,可以使用 Dto 來命名。

微服務(wù)架構(gòu)

不過現(xiàn)在都是微服務(wù)架構(gòu),SOA 架構(gòu)的風(fēng)格的系統(tǒng) 沒那么多,所以上面 service 或 manager 向外傳輸 Dto 的情況也就沒那么多

因?yàn)镾OA架構(gòu)風(fēng)格,需要對(duì)外暴露統(tǒng)一接口,所以很多框架還會(huì)有 Service 層的接口,然后再有一個(gè)實(shí)現(xiàn)類,

但是在微服務(wù)盛行的今天,仍然有很多項(xiàng)目在 service 層分出一層接口層,雖然是有好處,博主個(gè)人認(rèn)為完全沒有必要。在比較特定的場(chǎng)景,可以單獨(dú)加,而且這些特定的場(chǎng)景是可以通過其他手段規(guī)避的。

DDD 領(lǐng)域驅(qū)動(dòng)

領(lǐng)域驅(qū)動(dòng),先簡(jiǎn)單的科普下,建議先網(wǎng)上搜一搜領(lǐng)域驅(qū)動(dòng)的概念,再結(jié)合一起看,以之前的 三層架構(gòu)來舉例,

一個(gè) UserPo 只對(duì)應(yīng)一張 sys_user 表,一個(gè) User 有 3 個(gè)訂單,訂單對(duì)應(yīng) 訂單表 sys_order 表,想要查詢用戶和訂單,或者一個(gè)用戶下3個(gè)訂單

寫個(gè)偽代碼

public class UserService{@Resourceprivate UserDao userDao;@Resourceprivate OrderDao orderDao;public void insertUser(UserDto userDto){//插入用戶信息//插入訂單信息}public UserInfo select(UserQuery userQuery){//查詢用戶信息//查詢訂單信息//訂單信息列表 set 到 userInfo 的字段里去}}

以上的代碼都是在 service 業(yè)務(wù)邏輯層進(jìn)行操作。

而領(lǐng)域驅(qū)動(dòng)的代碼可能是下面

public class UserService{public void insertUser(UserDto userDto){// UserDto 轉(zhuǎn)成 UserDouserDo.insert();}public UserInfo select(UserQuery userQuery){//UserQuery 轉(zhuǎn)成 UserDoUserInfo userInfo = userDo.info();}} public class UserDo{@Resourceprivate UserDao userDao;@Resourceprivate OrderDao orderDao;public void insert(UserDto userDto){//插入用戶信息//插入訂單信息}public UserInfo info(UserQuery userQuery){//查詢用戶信息//查詢訂單信息//訂單信息列表 set 到 userInfo 的字段里去}}

將緊密的業(yè)務(wù)邏輯,放到業(yè)務(wù)模型中去,讓模型成為一個(gè)充血模型,

有人可能感覺到,這有啥區(qū)別,不就是從一個(gè)類,移動(dòng)到例外一個(gè)類里去寫嘛,一是我上面的例子的確不是非常好,二,我舉的例子是和交通方面相關(guān),各位可能也聽不明白細(xì)節(jié)。

一般的領(lǐng)域驅(qū)動(dòng),都是用于專業(yè)性更強(qiáng)的,更加緊密的業(yè)務(wù)模型。

比如一個(gè)電腦,你可能拆成 n 多張表。顯示器表,電源表,網(wǎng)卡表,,,,, 30 張表,之前的是將業(yè)務(wù)邏輯放到 service 層去寫,相當(dāng)于我們程序員知道如何拆卸,組裝電腦,需要哪些顯示器,電源,但是如果這個(gè)程序員并不是非常熟悉電腦呢?

我們現(xiàn)在用一個(gè)類,Computer 類,這個(gè)領(lǐng)域模型里,就直接包含了,組裝方法,拆卸方法,用領(lǐng)域模型來驅(qū)動(dòng) 整個(gè)項(xiàng)目的 CRUD。

再以保險(xiǎn)距離,保險(xiǎn)案例摘抄網(wǎng)上 DDD 驅(qū)動(dòng)講解。

以保險(xiǎn)業(yè)務(wù)為例來進(jìn)行編程實(shí)踐,一個(gè)高度抽象的保險(xiǎn)領(lǐng)域劃分如圖所示。通過用例分析,我們把整個(gè)業(yè)務(wù)劃分成產(chǎn)品域、承保、核保、理賠等多個(gè)領(lǐng)域(Bounded-Context),每個(gè)領(lǐng)域又可以根據(jù)業(yè)務(wù)發(fā)展情況拆分子域。當(dāng)然,完備保險(xiǎn)業(yè)務(wù)要比圖中展現(xiàn)的復(fù)雜太多。

領(lǐng)域驅(qū)動(dòng),需要一個(gè)專業(yè)性比較強(qiáng)的專家,結(jié)合程序員,才能比較好的切實(shí)落地,博主曾經(jīng)在智慧交通系統(tǒng)上應(yīng)用該思想,組內(nèi)開發(fā)人員不太了解該理念,另外和交通的專家溝通也有缺陷,并不是很成功,效果也并不好,直到項(xiàng)目中期才逐漸好起來,由于整體架構(gòu)和存量代碼的問題,并不能完全的稱為 領(lǐng)域驅(qū)動(dòng)。

不過可以將該領(lǐng)域驅(qū)動(dòng)的思想,應(yīng)用于其他地方。而這個(gè)領(lǐng)域?qū)ο?#xff0c;博主更傾向于 DO 來命名。當(dāng)然,這里也設(shè)計(jì) 應(yīng)用層領(lǐng)域 AO,和 數(shù)據(jù)模型 Model 等

小結(jié)

鑒于領(lǐng)域驅(qū)動(dòng),博主只在兩個(gè)系統(tǒng)上應(yīng)用,并不能深切的進(jìn)行體會(huì),希望能夠和各位同學(xué)交流,共同進(jìn)步。

圖中根據(jù)博主的個(gè)人理解,描述了 DTO,Query,Vo,Bo,Po,Do 等,還有其他的一些

以 SpringBoot 的 配置文件參數(shù)注入為例,常見2種方式注入,1是如下的 @Value

2是 @ConfigurationProperties(“alioss”) 對(duì)象注入。

兩種方式雖然都可以進(jìn)行注入,但是博主更喜歡第二種,因?yàn)榭梢栽陬惱镞M(jìn)行 bean 的引用,如下圖,

如果是配置文件中的 字符串還是經(jīng)過 base64 加密的,也可以在 @ConfigurationProperties(“alioss”) 這種方式的 get 方法里,進(jìn)行轉(zhuǎn)化,

如果配置文件中的 名稱 accessKey 改變成 accessKeyName,我們也可以在第二種方式中,提供另外一個(gè)字段 accessKeyName,但是不提供 set get,然后對(duì) accessKey 的 get 方法進(jìn)行修改,也不會(huì)改變項(xiàng)目里已經(jīng)調(diào)用的字段。相當(dāng)于中間加了一層緩沖層

那么這種緩沖層其實(shí)也并不好歸屬 DTO,Query,Vo,Bo,Po,Do,博主常用 Model,或者 Entity 描述該配置類,

如果我們網(wǎng)站上,有一個(gè)查詢手機(jī)號(hào)歸屬地的功能,用戶從網(wǎng)頁(yè)請(qǐng)求,但是我們系統(tǒng)后臺(tái)是請(qǐng)求第三方接口的, 那么我們?cè)跇I(yè)務(wù) service 層之后還可以加一層 通用處理層,這時(shí)候可能就涉及到網(wǎng)絡(luò)請(qǐng)求,又可能涉及到 請(qǐng)求的數(shù)據(jù),和響應(yīng)的數(shù)據(jù),我們也會(huì)使用一個(gè)對(duì)象來封裝,

那么這種請(qǐng)求對(duì)象或者響應(yīng)對(duì)象,其實(shí)也并不好歸屬 DTO,Query,Vo,Bo,Po,Do。 當(dāng)然也可以使用 Dto 來命名,但是這就比較容易混淆了嘛。

博主也常用 Model,Entity,來命名,比如 xxxReqModel,xxxRespModel。

而對(duì)于這些所有的,pojo 是一個(gè)很好的概述,不是嗎?Plan Ordinary Java Object POJO

名稱英文中文說明
POJOPlan Ordinary Java Object普通的 Java 對(duì)象瞧瞧這名字,多普通啊
DaoData Access Object數(shù)據(jù)訪問對(duì)象這其實(shí)特別容易區(qū)別,下面的文章待會(huì)講
DtoData Transfer Object數(shù)據(jù)傳輸對(duì)象有點(diǎn)繞了,啥玩意叫 Transfer 傳輸啊,這有歷史錯(cuò)誤
PoPersistant Object持久化對(duì)象哦豁,阿里巴巴規(guī)范可沒這玩意啊
DoData Object數(shù)據(jù)對(duì)象
BoBusiness Object業(yè)務(wù)隊(duì)對(duì)象嗐,業(yè)務(wù)掛鉤的唄
AoApplication Object應(yīng)用對(duì)象應(yīng)用?怎么感覺和 業(yè)務(wù) Bo 差不多呢
VoValue Object / View Object值對(duì)象 / 視圖對(duì)象啥,還有2種解釋?
QueryQuery查詢咋混個(gè)這玩意進(jìn)來?
ModelModel模型啥玩意是模型,
EntityEntity實(shí)體啥玩意是實(shí)體,
BeanBeanbean 對(duì)象啥玩意是bean,

Bean 的話,博主更傾向于, JavaBean,不要比 Bean 來命名。

碼字不易,點(diǎn)點(diǎn)小手。

總結(jié)

以上是生活随笔為你收集整理的POJO分层领域模型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。