自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

新項(xiàng)目模塊不能拆拆拆,但怎么應(yīng)對大型項(xiàng)目?

開發(fā) 項(xiàng)目管理
很多同學(xué)創(chuàng)建一個(gè)項(xiàng)目之后,就迫不及待的上手開寫了。項(xiàng)目代碼不像一些框架代碼一樣可以隨意的去寫,但一般都是采用MVC的模式進(jìn)行開發(fā)。很悲催的是,Java中Web開發(fā)的這些目錄名稱,到現(xiàn)在還是一團(tuán)亂麻,你需要自己去規(guī)劃。

[[378316]]


很多同學(xué)創(chuàng)建一個(gè)項(xiàng)目之后,就迫不及待的上手開寫了。項(xiàng)目代碼不像一些框架代碼一樣可以隨意的去寫,但一般都是采用MVC的模式進(jìn)行開發(fā)。很悲催的是,Java中Web開發(fā)的這些目錄名稱,到現(xiàn)在還是一團(tuán)亂麻,你需要自己去規(guī)劃。

什么Controller、Service、Dao等,但其實(shí)這種劃分方式弊端很多! 本文將先介紹兩種典型的分層結(jié)構(gòu),然后稍微借鑒一下DDD的思想,談一下我在項(xiàng)目中常用的目錄結(jié)構(gòu)。本篇文章非常的實(shí)用,將探討怎樣做一個(gè)應(yīng)對大型項(xiàng)目的目錄劃分。

清晰的目錄結(jié)構(gòu),能夠輔助其他同學(xué)輕而易舉的了解項(xiàng)目的功能模塊,在項(xiàng)目中保持整體一致的約定也是一個(gè)非常好的習(xí)慣。如果再加上一個(gè)擴(kuò)展性,那目錄劃分就是重中之重。

有兩種典型的分類方式,但也有很多細(xì)節(jié)。

1. 最簡單的MVC

我們平常最熟悉的,就是MVC結(jié)構(gòu)。這種結(jié)構(gòu)很流行,寫簡單項(xiàng)目很方便,但是會(huì)產(chǎn)生嚴(yán)重的耦合問題、Service爆炸問題,數(shù)千、上萬行的代碼是家常便飯。

  1. Model(模型)表示應(yīng)用程序核心(比如數(shù)據(jù)庫記錄字段)。
  2. View(視圖)顯示數(shù)據(jù)(數(shù)據(jù)庫記錄)。
  3. Controller(控制器)處理輸入(寫入數(shù)據(jù)庫記錄)。

在項(xiàng)目劃分上,就類似下面的目錄結(jié)構(gòu)。

1.1 模型

domain是DDD中一個(gè)非常寬泛的概念。不過,我們平常就當(dāng)作數(shù)據(jù)庫對應(yīng)的Java 類使用了(沒什么錯(cuò))。在實(shí)際操作中,它還可能有下面幾種名字,在普通項(xiàng)目中區(qū)別不大,你最好在項(xiàng)目中保持相同的意義來避免歧義。

  • entity 這個(gè)意義比較明顯,就是實(shí)體的意思,最常用。比如JPA的Entity注解
  • model模型的意思,一般用來在不同系統(tǒng)之間交互。但如果你的模型非常簡單,直接用entity來表示也是可以的
  • domain 這個(gè)范圍有點(diǎn)大,甚至?xí)I(lǐng)域內(nèi)service。如果你對DDD的概念不是很熟悉,那就玩上面幾種

對于簡單的項(xiàng)目,我通常在項(xiàng)目中使用entity來表示和數(shù)據(jù)庫的交互。在JPA之類的ORM中,也是做相關(guān)處理的。比如javax.persistence.Entity注解。你要明白的是,Spring Data其實(shí)取了一個(gè)比較折衷的點(diǎn),把很多東西揉在一起了。

1.2 Dao

dao層叫數(shù)據(jù)訪問層,全稱為data access object,屬于一種比較底層,比較基礎(chǔ)的操作。在一些其他框架中,還會(huì)叫別的名字。

  • mapper 這個(gè)一般是Mybaits之類的框架所生成的目錄,通常是一些接口。
  • repository 倉庫的意思,在jpa中經(jīng)常用。

Dao應(yīng)該滿足最小封裝原則,理論上只涉及一句SQL的執(zhí)行。如果有多個(gè)數(shù)據(jù)的存取動(dòng)作,需要封裝在Service中,并用事務(wù)進(jìn)行管理(雖然這么說,但repository在DDD中,是不和具體的數(shù)據(jù)庫打交道的)。

1.3 service和controller

這個(gè)沒什么好說的,基本上所有重要的邏輯都在這里完成。service用于邏輯處理,controller用于接口暴露。

2. 根據(jù)功能組織

大多數(shù)情況下,我們使用上面的這種劃分模式,能夠很好的完成工作。比如,所有的數(shù)據(jù)處理,都放在Dao層,所有的邏輯處理,都放在Service層。

這在小項(xiàng)目中相安無事,但如果項(xiàng)目中,有成百上千個(gè)Entity,這些目錄中的文件就會(huì)爆炸,以至于最后無法維護(hù)。

另外一個(gè)問題就是,僅僅一個(gè)簡單的功能,就可能分散在多個(gè)package下的多個(gè)文件中,大型項(xiàng)目維護(hù)變得困難。

我們有另外一個(gè)思路,就是根據(jù)功能進(jìn)行分組。比如下面的截圖。

我們把相似功能,放在modules下的單個(gè)文件夾中。如果這個(gè)功能模塊比較大,我么可以在功能模塊下,再進(jìn)行分層設(shè)計(jì)。

比如上圖,有一個(gè)商品服務(wù),我們單獨(dú)給它分配了一個(gè)目錄空間goods,然后在里面又劃分了dao、entity等目錄;但對于Service和Controller,我們簡單的放在了外層,可以看到在模塊內(nèi)的分配是比較靈活的。

這么做的好處是顯而易見的。功能變的非常的集中,各個(gè)package之間的內(nèi)容互不影響。

3. 還是不夠優(yōu)雅

其實(shí),即使我們這樣劃分了,項(xiàng)目仍然會(huì)面臨很大的挑戰(zhàn)(很多DDD的書籍,會(huì)大量討論各層的交互)。

下面分享一個(gè)我在平常使用的分層模式,兼顧高內(nèi)聚和低耦合,有著良好的擴(kuò)展性。

  1. config,最外層的一些全局配置,比如web配置,消息隊(duì)列配置等
  2. system,全局的工具和依賴功能,在DDD中叫做基礎(chǔ)設(shè)施(但在非DDD實(shí)踐的項(xiàng)目中名稱太怪異了)
  3. auth,權(quán)限認(rèn)證模塊,比如JWT或者Spring Sercurity,這部分的設(shè)計(jì)要獨(dú)立,以便后續(xù)抽離到Zuul之類的網(wǎng)關(guān)
  4. bc,在DDD中是限界上下文的意思(Bounded Context),我們也可以直接叫模塊,這些模塊有著嚴(yán)格的界限,可以根據(jù)請求量,拆分成相應(yīng)的微服務(wù)。在上圖,crm、images、order等等,都可以抽離成獨(dú)立的微服務(wù)

我們再來看一下每個(gè)模塊之內(nèi)的結(jié)構(gòu)。

  1. 和傳統(tǒng)的MVC類似。不過,為了屏蔽變化,兼顧擴(kuò)展性,我們增加了更多的內(nèi)容。
  2. persitence,持久層,具體使用JPA還是Mybatis,這個(gè)是無關(guān)緊要的。我們的目標(biāo),就是盡量的弱化持久層的實(shí)現(xiàn),將變化封裝在Domain層中
  3. persitence/dao,具體的持久層接口,比如MyBatis的Mapper文件,或者JPA的Repository
  4. domain層,具體的業(yè)務(wù)層,你可以認(rèn)為是一堆Getter、Setter的Bean。我們盡量會(huì)把大多數(shù)驗(yàn)證類和變化封裝在這里(可以大體認(rèn)為是DDD中的充血模型)
  5. controller,具體的Rest接口層。但不同的是,有很多不同的請求和返回,我們封裝成了Request和Response,用來接受提交的數(shù)據(jù),對返回?cái)?shù)據(jù)進(jìn)行瘦身等
  6. application,應(yīng)對傳統(tǒng)的service層,除了在application能夠調(diào)用Dao,其他層是沒有權(quán)利調(diào)用Dao的
  7. api,和application的功能是相同的。只不過,api的接口,指的是模塊之間可以相互調(diào)用的接口。除了api暴露的這些接口,bc之間的類和接口,默認(rèn)彼此是不可見的
  8. util,不通用的util,會(huì)放在模塊內(nèi)部,而不是抽離出公共的util

除了要解決目錄方面的問題,我們還要把數(shù)據(jù)的流向給規(guī)劃清楚。

一個(gè)上層的應(yīng)用,是可以通過API接口直接調(diào)用下層服務(wù)的。比如,訂單系統(tǒng)訪問商品基礎(chǔ)信息的數(shù)據(jù);反之卻不可以,比如商品基礎(chǔ)信息模塊訪問訂單系統(tǒng)的接口。

低層想要對高層的數(shù)據(jù)產(chǎn)生變化,就只能通過消息模塊,將變更發(fā)布出去,其他的模塊就可以訂閱這些變化。

小結(jié)

綜上所述,xjjdog認(rèn)為,如果你的項(xiàng)目,可能會(huì)比較大,單純的使用分層的package,并不是一個(gè)好的習(xí)慣。

你可能對這種后臺(tái)管理類的項(xiàng)目駕輕就熟,有很多有用的模版,它們都是簡單的MVC分層。這應(yīng)付一些外包項(xiàng)目,干一些一錘子買賣的時(shí)活,或許沒什么問題,但一旦是比較大的長期項(xiàng)目,這種分層的目錄接口就顯現(xiàn)出它的弊端。

這是因?yàn)椋喉?xiàng)目的短期風(fēng)險(xiǎn),是工期問題;而長期風(fēng)險(xiǎn),是擴(kuò)展問題。隨著訪問量的增加,還有低耦合高內(nèi)聚的需求增加,如何快速的應(yīng)對需求,減少BUG,將會(huì)是制約項(xiàng)目發(fā)展的最主要因素。

作者簡介:小姐姐味道 (xjjdog),一個(gè)不允許程序員走彎路的公眾號。聚焦基礎(chǔ)架構(gòu)和Linux。十年架構(gòu),日百億流量,與你探討高并發(fā)世界,給你不一樣的味道。我的個(gè)人微信xjjdog0,歡迎添加好友,進(jìn)一步交流。

 

責(zé)任編輯:武曉燕 來源: 小姐姐味道
相關(guān)推薦

2015-04-15 09:29:18

UltimateAndroied

2012-06-26 10:34:28

RIM

2021-07-08 07:52:48

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

2010-11-11 11:19:19

騰訊

2021-01-13 08:41:08

整數(shù)動(dòng)態(tài)規(guī)劃

2010-05-28 10:44:50

李彥宏百度

2009-08-26 03:39:00

C#裝箱和拆箱

2015-08-26 10:36:32

ios開發(fā)漫談

2015-08-31 10:11:43

iOS大項(xiàng)目開發(fā)

2021-05-12 08:54:56

FastAP web 框架數(shù)據(jù)庫操作

2009-01-23 20:02:30

金山分拆WPS

2023-02-13 08:21:25

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

2010-11-22 14:47:22

MySQL存儲(chǔ)過程

2009-03-03 08:45:41

AMD分拆制造工廠

2023-03-02 20:41:12

特斯拉比亞迪

2010-03-25 21:49:44

2012-03-26 11:32:45

Java

2015-07-27 10:43:26

2024-12-19 11:00:00

TCP網(wǎng)絡(luò)通信粘包

2009-08-28 11:22:11

C#裝箱和拆箱
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號