日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

作為一個后端程序員,MVC三層架構(gòu)的模式相信大家都不會陌生,三層分別從上而下排布,只能由上層調(diào)用下層。一般越往下層越通用,越上層越細節(jié)。

六邊形架構(gòu)和分層架構(gòu)的區(qū)別

 

隨著某些核心業(yè)務(wù)的訪問量發(fā)展,通常我們需要去進行優(yōu)化的措施,比如加緩存,加MQ,換數(shù)據(jù)源

1.緩存可選redis,memcache
2.MQ可選kafka,rocketmq,rabbitmq
3.數(shù)據(jù)源可選:MySQL,mongodb,elasticsearch
復(fù)制代碼

當(dāng)然,我們在做這些優(yōu)化的時候,會將mq,mongodb等看成基礎(chǔ)設(shè)施層。 由此衍生出四層的架構(gòu),infrastructure里封裝redis和mq的通用調(diào)用邏輯

六邊形架構(gòu)和分層架構(gòu)的區(qū)別

 

這些優(yōu)化的動作,通常不會改變原有的業(yè)務(wù)邏輯。但是為了做優(yōu)化,我們會將它寫在service層,比如:

1.執(zhí)行成功就發(fā)個MQ
2.執(zhí)行某個事件的時候,同步一下緩存
3.依賴關(guān)系為,domain依賴infrastructure

問題點:

按道理來說,domain層是寫業(yè)務(wù)邏輯的,優(yōu)化不會涉及到業(yè)務(wù)邏輯的改動,但是卻改動了domain層。由于domain層依賴了infrastucture的原因,導(dǎo)致業(yè)務(wù)依賴于具體的實現(xiàn)技術(shù)。所以,為了將業(yè)務(wù)與具體實現(xiàn)做分離,我們采用依賴倒置的手段去重構(gòu)

依賴倒置原則的包含如下的三層含義:
1.高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴其抽象
2.抽象不應(yīng)該依賴細節(jié)
3.細節(jié)應(yīng)該依賴抽象

高層模塊不依賴低層模塊:那就可以在domain層定義存儲的接口,如AARepository,但是不寫具體的技術(shù)實現(xiàn)

抽象不依賴細節(jié):在domain層里,不依賴其他包的類,如用到數(shù)據(jù)存儲時,直接調(diào)用domain的抽象接口即可

高層通過依賴注入的方式,將基礎(chǔ)設(shè)施的實現(xiàn)傳到domain層中

如此一來,我們的架構(gòu)就不再是分層的結(jié)構(gòu)(從上往下調(diào)用)。而是將抽象全部堆在domain層,將細節(jié)全部往Application和infrastructure去推。而越抽象越穩(wěn)定,所以通過這種做法能夠有效減少業(yè)務(wù)的變更。

六邊形架構(gòu)和分層架構(gòu)的區(qū)別

 

架構(gòu)變成了一種從內(nèi)而外的邏輯,越往內(nèi)越抽象,越往外越細節(jié)。在北向網(wǎng)關(guān),可以使用rest和dubbo去調(diào)用業(yè)務(wù)邏輯,南向網(wǎng)關(guān)可以將數(shù)據(jù)寫到redis或mq。具體代碼實現(xiàn)

如下業(yè)務(wù):發(fā)送課程成功了,要發(fā)送消息給設(shè)備IOT,發(fā)送MQ,更新緩存

傳統(tǒng)做法:

void sendCourse(){
	//執(zhí)行業(yè)務(wù)邏輯
 //發(fā)送消息給設(shè)備IOT
 //發(fā)送MQ
 //更新緩存
}

隨著優(yōu)化方案的不斷增加,業(yè)務(wù)邏輯會越堆越多 六邊形架構(gòu)+EDA做法

public SendCourseService sendCourseService{
 void sendCourse(SendCourseCommand command){
	 //執(zhí)行業(yè)務(wù)邏輯并發(fā)布發(fā)布課程事件
 eventBus.push(SendCourseEvent())
 } 
}

當(dāng)我們要做更新緩存操作的時候,實際上與業(yè)務(wù)邏輯沒有什么關(guān)系,可以定義一個監(jiān)聽者去監(jiān)聽發(fā)布課程事件。這個SendCourseCacheHandler類要寫到哪里呢?

public class SendCourseCacheHandler{
 
 private Jedis jedis;
 public void deleteCache(SendCourseEvent event){
 //刪除緩存
 }
}
  1. 按照抽象往domain寫,細節(jié)往外寫的劃分,寫到基礎(chǔ)設(shè)施層不合適,因為與業(yè)務(wù)強相關(guān)。
  2. 寫到domain不合適,因為與redis這些具體實現(xiàn)強相關(guān)。

所以這個類應(yīng)該寫在application層,其實是domain去調(diào)用application,所以說。。。這并不是分層架構(gòu)。我們思考的時候是按抽象程度去判斷應(yīng)該寫在哪里,而不是從上往下調(diào)用。

那這個監(jiān)聽者如何與業(yè)務(wù)結(jié)合起來呢?這時就發(fā)揮了application層的作用了,我們可以將application作為業(yè)務(wù)組裝的邏輯。

如我們在業(yè)務(wù)開始之前,將監(jiān)聽者注冊上去,這樣在業(yè)務(wù)執(zhí)行的時候,就可以回調(diào)這些監(jiān)聽者了

public class CourseAppService{
 
 private SendCourseCacheHandler sendCourseCacheHandler;
 private SendCourseMQHandler sendCourseMQHandler;
 private SendCourseService sendCourseService;
 private EventBus eventBus;
 public void sendCourse(SendCourseCommand command){
 //刪除緩存
 eventBus.register(sendCourseCacheHandler);
 //發(fā)MQ
 eventBus.register(sendCourseMQHandler);
 sendCourseService.sendCourse(command);
 }
}

適合場景:

1.讀/寫比較大的場景
2.對查詢實時性要求不高的場景
3.內(nèi)部狀態(tài)改變會觸發(fā)各種數(shù)據(jù)的同步,如課程完成,課程發(fā)布等等等等。。。
4.外部實現(xiàn)可替換,如mq可以隨意替換實現(xiàn)

不適合場景:

只有簡單CRUD的業(yè)務(wù),沒有重的業(yè)務(wù)邏輯,不適合搞那么復(fù)雜,因為沒必要抽出domain層

分享到:
標簽:架構(gòu)
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定