国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

CQRS框架(nodejs的DDD開(kāi)發(fā)落地框架)初識(shí)感想

zhoutk / 763人閱讀

摘要:中的事件的一個(gè),我暫且理解為一個(gè)中的和這兩個(gè)屬性已經(jīng)在框架中直接掛載在了對(duì)象上,歸功于曾老師。

CQRS是啥?DDD又是啥?

這兩個(gè)概念其實(shí)沒(méi)什么神秘的,當(dāng)然此文章中的這兩個(gè)概念以曾老師的課程為準(zhǔn)(關(guān)于CQRS和DDD的標(biāo)準(zhǔn)概念,google上已經(jīng)很多了,不再贅述。)

DDD(Domain Driven Design),領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)開(kāi)發(fā)。

DDD和OOP有什么同嗎?其實(shí)就我個(gè)人經(jīng)驗(yàn)來(lái)說(shuō),沒(méi)有任何不同(當(dāng)然你可以反駁我),DDD就是OOP。這里以曾老師課上的概念為準(zhǔn),domain就是世界,包含了當(dāng)前所有actor的一個(gè)域,這個(gè)域是一個(gè)上帝視角,可以監(jiān)聽(tīng)每一個(gè)域中發(fā)生的事件,并且記錄。

CQRS,既命令和查詢職責(zé)分離(Command Query Responsibility Segregation)。

在普通mvc架構(gòu)中,對(duì)于數(shù)據(jù)庫(kù)的CRUD基本都是寫(xiě)在controller層,這樣一來(lái)路由非常臃腫,而且維護(hù)起來(lái)簡(jiǎn)直是噩夢(mèng)。

CQRS將查詢與職責(zé)分離。簡(jiǎn)單說(shuō)來(lái),就是寫(xiě)操作和讀操作分離,讀操作寫(xiě)在路由中,寫(xiě)操作通過(guò)面向?qū)ο髮?xiě)入類的業(yè)務(wù)方法中,這樣路由中的查詢部分薄了,而且對(duì)于寫(xiě)操作的可讀性,重用性和維護(hù)性大大提高。

相比較于普通mvc,cqrs分為核心層Core(及核心層擴(kuò)展Core Extension)應(yīng)用層(Application),UI層,看起來(lái)3層,其實(shí)是四層,但是由于核心層與核心層擴(kuò)展的伸縮性很強(qiáng),并且針對(duì)項(xiàng)目的大小來(lái)決定,所以就我覺(jué)得用3.5層來(lái)描述比較合適。

取cqrs文檔中的例子
const {Actor} = require("cqrs");

module.exports = class User extends Actor{
  constructor(data){
     const {name} = data;
     super({
       name,
       createTime: Date.now(),
       stars:[], // 被關(guān)注明星的 ids
       watchers:[] //  關(guān)注者的 ids
     });
  }

  // 關(guān)注某位明星
  async follow(starId){
    const service = this.service;
    const star = await service.get("User",starId);
    if(starId !== this.id && star){
      await star.addWatcher(this.id);
      this.$(starId)
    }
  }

  // 取消關(guān)注某位明星
  async unFollow(starId){
    const star = await this.service.get("User",starId);
    if(star){
      await star.deleteWatcher(this.id);
      this.$(starId);
    }
  }

  // 加入關(guān)注者 watcher
  addWatcher(watcherId){
    if(watcherId !== this.id)
    this.$(watcherId);
  }

  // 取消被關(guān)
  deleteWatcher(watcherId){
    this.$(watcherId);
  }

  get updater(){
    return {
      follow(json, event){
        const stars = json.stars;
        stars.push(event.data);
        return {
          stars
        }
      },
      unFollow(json, event){
        const stars = json.stars;

        var set = new Set(stars);
        set.delete(event.data);

        return {
          stars:[...set]
        }
      },
      addWatcher(json,event){
        const watchers = json.watchers;
        watchers.push(event.data);
        return {
          watchers
        }
      },
      deleteWatcher(json,event){
        const watchers = json.watchers;
        const set = new Set(watchers);
        set.delete(event.data);
        return {
          watchers:[...set]
        }
      }
    }
  }
}

以上例子是一個(gè)cqrs (傳送門(mén))Actor的實(shí)現(xiàn),通過(guò)this.$產(chǎn)生一個(gè)事件,事件由updater接收,進(jìn)行數(shù)據(jù)的真正修改。

const {Domain} = require("cqrs");
const User = require("./User");
const domain = new Domain();

// 注冊(cè) User Actor 類
domain.register(User);

// 即時(shí)異步執(zhí)行函數(shù)
(async function () {

  // 創(chuàng)建用戶1
  let user1 = await domain.create("User",{
    name:"leo"
  });

  // 創(chuàng)建用戶2
  let user2 = await domain.create("User",{
    name:"zengliang"
  })

  // user1 關(guān)注 user2
  await user1.follow(user2.id);

  console.log(user1.json.stars); // 打印一下 user1 監(jiān)聽(tīng)所有 ids
  console.log(user2.json.watchers);  // 打印一下 user2 追隨者的所有 ids

  user1.unFollow(user2.id);  // user1 取消關(guān)注 user2

  // 重新加載 user1 和 user2
  user1 = await domain.get("User",user1.id);
  user2 = await domain.get("User",user2.id);

  console.log(user1.json.stars); // 打印一下 user1 監(jiān)聽(tīng)所有 ids
  console.log(user2.json.watchers);  // 打印一下 user2 追隨者的所有 ids

})();

以上是在運(yùn)行中對(duì)User實(shí)例對(duì)象的操作,關(guān)注與取關(guān)的操作。

Any fool can write code that a computer can understand. Good programmers write code that humans can understand. -- 某位大牛

以上的例子很好的詮釋了可讀性還有重用性。對(duì)于寫(xiě)操作來(lái)說(shuō),完全用業(yè)務(wù)方法來(lái)實(shí)現(xiàn),那么路由中可以僅包含cqrs中Q的部分,這樣做到了業(yè)務(wù)和查詢分離,那么迷惑也開(kāi)始解開(kāi)了。

寫(xiě)操作,用業(yè)務(wù)方法來(lái)完成,屬于核心層

query,既查詢操作,寫(xiě)在router中,是應(yīng)用層變薄

在使用普通mvc的時(shí)候,邏輯和查詢通常都會(huì)放在路由當(dāng)中,這樣造成的高耦合性(coupling)讓代碼的重用性,可讀性,可伸縮性很差。維護(hù)起來(lái)簡(jiǎn)直噩夢(mèng)連連。我的第一個(gè)項(xiàng)目是用標(biāo)準(zhǔn)mvc完成,后期加新需求的時(shí)候基本山就是牽一發(fā)動(dòng)全身,也是我的經(jīng)驗(yàn)確實(shí)不夠?qū)τ诤芏嗟胤經(jīng)]有對(duì)代碼進(jìn)行可重用的封裝。

現(xiàn)在淺談一下 Auxo(傳送門(mén))

Auxo框架集成了Nuxt(Vue),Vuex,Express,cqrs四個(gè)重要框架。這樣在開(kāi)發(fā)時(shí)就不用再辛苦搭建開(kāi)發(fā)環(huán)境了,直截了當(dāng)。Auxo是約定式的框架,關(guān)于文件結(jié)構(gòu)是根據(jù)Nuxt(傳送門(mén))的,所以有必要讀一讀Nuxt的文檔,對(duì)Nuxt有一定了解之后就可以用了而且上手很快,因?yàn)榛旧喜恍枰渲檬裁礀|西。

在Auxo框架中,數(shù)據(jù)遵循Event Sourcing原則,分兩個(gè)collection。

一個(gè)是事件數(shù)據(jù)庫(kù)記錄在domain中發(fā)生的所有事件,讓事件回溯、長(zhǎng)故事(saga)和事件鎖(lock)成為可能;

另外一個(gè)是查詢數(shù)據(jù)庫(kù),記錄普通數(shù)據(jù),我自己的理解就是面向數(shù)據(jù)庫(kù)開(kāi)發(fā)的那種最基本的數(shù)據(jù)庫(kù)。

eventstore

記錄事件對(duì)象的數(shù)據(jù)庫(kù),可以通過(guò)該數(shù)據(jù)庫(kù)的數(shù)據(jù)進(jìn)行數(shù)據(jù)回溯。

snap

事件快照。domain中的事件的一個(gè)snapshot,我暫且理解為一個(gè)log

server/index.js 中的 req.dbs req.$domain

這兩個(gè)屬性已經(jīng)在框架中直接掛載在了req對(duì)象上,歸功于曾老師。在server/index.js中,已經(jīng)定義好了,這個(gè)文件相當(dāng)于express的app.js,只是文件名不一樣。
req.dbs就是上述的查詢數(shù)據(jù)庫(kù),可以使用mongojs來(lái)query。
req.$domain就是domain,即上帝視角,可以用以下語(yǔ)句

req.$domain.get("User", uid); // 獲取User對(duì)象
req.$domain.create("User", {username: "ephraimguo", password:"*******"}); // 創(chuàng)建user對(duì)象

等domain對(duì)象的方法進(jìn)行數(shù)據(jù)操作。

在Vue組件中的axiosdomain

這兩個(gè)對(duì)象已經(jīng)寫(xiě)在plugins/文件夾里面,可以直接在Vue組件中引用如下



Listener 核心層擴(kuò)展 (有個(gè)小坑)

起初看到曾老師用listener但是不明白怎么監(jiān)聽(tīng),而且去看epxress-cqrs的源碼的時(shí)候,看到listener的路徑是作參數(shù)與傳入了的。

截取一段express-cqrs的源碼
// Register Actors Class from actors folder
ActorList.filter(Actor => /.*.js$/.test(Actor)).
    forEach(Actor => domain.register(require(path.join(actorPath, Actor))));
    
// Get Listener from listener folder
listeners.filter(listener => /.*.js$/.test(listener)).
    forEach(listener => require(path.join(listenerPath, listener))(domain));

第一步,在根目錄下添加listener文件夾

第二部,創(chuàng)建新的監(jiān)聽(tīng)js文件,

Listener 內(nèi)部寫(xiě)法,如下(個(gè)人經(jīng)驗(yàn))
module.exports = function(domain){ 
    // Utilise domain.on(...) to make onAction listening
}

這次先暫時(shí)聊這么多,cqrs還有很多好用的方法和思想可以慢慢琢磨,而且這種編程思想易實(shí)踐,并且對(duì)全局的把控更精準(zhǔn),心有猛虎細(xì)嗅薔薇,當(dāng)然這篇文章也是針對(duì)上過(guò)曾老師課的童鞋們,不算是掃盲,過(guò)后會(huì)繼續(xù)寫(xiě)一些關(guān)于cqrs框架應(yīng)用的文章,也歡迎大家提問(wèn),并且一起討論。如果有錯(cuò)誤,也請(qǐng)大家指正,我會(huì)馬上修改。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/98611.html

相關(guān)文章

  • 那些年初識(shí)Angular(1)

    摘要:它包含多個(gè)屬性,這些屬性值叫做元數(shù)據(jù)。會(huì)根據(jù)元數(shù)據(jù)渲染組件,并執(zhí)行組件邏輯。元數(shù)據(jù)會(huì)告訴圖和將這個(gè)類處理成一個(gè)組件。元數(shù)據(jù)這段代碼表示這個(gè)組件可以通過(guò)這個(gè)標(biāo)簽來(lái)調(diào)用。 那些年初識(shí)Angular 由于工作需要初識(shí)了Angular,由于個(gè)人在學(xué)習(xí)一門(mén)新語(yǔ)言的時(shí)候喜歡買(mǎi)一本相關(guān)的書(shū)籍自己鉆研,還記得自己的第一本Angular書(shū)籍是關(guān)于Angular2的學(xué)習(xí),自此正式踏入Angular的學(xué)習(xí)。...

    Flink_China 評(píng)論0 收藏0
  • 落地DDD(1)-目標(biāo)討論

    摘要:最近發(fā)現(xiàn)文章老是被竊取,有些平臺(tái)舉報(bào)了還沒(méi)有用。最后不了了之,產(chǎn)品很配合,但是內(nèi)驅(qū)力不強(qiáng)。為什么內(nèi)驅(qū)力不強(qiáng),因?yàn)榻o他帶來(lái)的收益不夠。所以在千個(gè)團(tuán)隊(duì)中實(shí)行可能有千套不同的方案。最近發(fā)現(xiàn)文章老是被竊取,有些平臺(tái)舉報(bào)了還沒(méi)有用。請(qǐng)識(shí)別我的id方丈的寺院。 摘要 DDD領(lǐng)域驅(qū)動(dòng)設(shè)計(jì),起源于2004年著名建模專家Eric Evans發(fā)表的他最具影響力的著名書(shū)籍:Domain-Driven Design...

    fox_soyoung 評(píng)論0 收藏0
  • #yyds干貨盤(pán)點(diǎn)# 常用軟件框架,總有一個(gè)用

    摘要:一界面框架是微軟在其最新桌面操作系統(tǒng)中使用的圖形用戶界面。干貨盤(pán)點(diǎn)二服務(wù)在寫(xiě)后臺(tái)代碼的過(guò)程中,經(jīng)常會(huì)遇到要寫(xiě)一些多帶帶的服務(wù)。這個(gè)傳統(tǒng)的控件開(kāi)發(fā)起來(lái)很不方面,使用也不友好。發(fā)現(xiàn)有用的,這個(gè)第三方的框架,集成的很好,用起來(lái)也方便。一、Fluent Ribbon界面框架Fluent/Ribbon是微軟在其最新桌面操作系統(tǒng)Windows 7中使用的圖形用戶界面。 Windows平臺(tái)的進(jìn)化,伴隨著系...

    番茄西紅柿 評(píng)論0 收藏2637
  • 微服務(wù)框架lagom

    摘要:在這種情況下,每一個(gè)微服務(wù)定義一個(gè)限界上下文,類似于領(lǐng)域驅(qū)動(dòng)的限界上下文。設(shè)計(jì)你的微服務(wù)系統(tǒng)的響應(yīng)式微服務(wù)架構(gòu)這本書(shū)對(duì)于微服務(wù)系統(tǒng)架構(gòu)很有幫助。 1.Lagom概念介紹 lagom框架包含一系列的可以支持我們從開(kāi)發(fā)到部署的庫(kù)以及開(kāi)發(fā)環(huán)境: >在開(kāi)發(fā)階段,可以通過(guò)一個(gè)簡(jiǎn)單的命令構(gòu)建我們的項(xiàng)目,啟動(dòng)所有你的服務(wù),并且可以支持所有的lagom基礎(chǔ)設(shè)置層。當(dāng)你修改了代碼,logom是有熱加載的...

    Michael_Lin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<