ddd 的一大好處就是並不需要使用特定的架構,經典分層架構只是一種,由於核心域位於限界上下文中,我們可以使用多種風格的架構,既然如此,我們應該把眼界看的更寬廣些,有意思的東西多著呢。
soa 和 rest 這兩個貨,我們都比較熟悉,他倆並不是由 ddd 引入,但卻可以適用於 ddd。我個人覺得,要想把他倆發揮好,最好結合六邊形架構(也可以稱之為埠和介面卡),請接著往下看:
1. soa-面向服務架構
soa(service-oriented architecture),我沒用過這貨,下面說一下自己對於它的認識,可能不是很準確。
service 意為服務,面向服務,也就是在 soa 架構中,服務是核心。業務系統中分布著大量的業務模組,這些業務模組進一步提煉就是服務,然後通過規定的服務契約發布出來,這些服務集合起來就是 soa 的核心,服務呼叫者可以是多樣的,web 端、移動端、桌面端都可以,也就是說它是分布式的架構,這些服務呼叫者呼叫的時候,要遵守發布者規定的一些契約和協議,而在服務本身或者之間也需要一定的契約和協議用來約束,要不然整個服務集合就會亂套,比如服務發布協議要有統一的規範,不能說乙個服務是乙個規範,服務之間也需要進行抽象抽離,盡可能的做到重用性等等。
回到 soa 上面,你會發現,他們的概念其實是共通的,夏天到了,出去遊玩,走著走著口渴了,我們就在路邊買乙個巨大的椰子,然後蜂擁而至一大堆**,他們人手拿著乙個吸管,而且種類和顏色各不相同,然後你的椰子上插滿了各種習慣,看起來就像乙個刺蝟一樣,你最後的下場可能就只有用刀劃開個口子喝了,不管是用吸管,還是用到劃開個口子,我們最後的目的都是喝椰子汁,只是使用的工具不同,乙個椰子可能裡面的汁更好喝,外面的更難喝。在這個日常生活示例中,乙個椰子可以看作是乙個 soa 架構,內部就是各種小的服務(可以看作是一塊一塊的椰子肉,裡面的更好吃),各種各樣的吸管和刀子可以看作是服務呼叫者,而椰子皮也可以看作是服務協議,因為椰子汁需要椰子皮的包裹才不會灑出來。
soa 架構原則:
服務封裝
服務松耦合(loosely coupled)- 服務之間的關係最小化,只是互相知道。
服務契約 – 服務按照服務描述文件所定義的服務契約行事。
服務抽象 – 除了服務契約中所描述的內容,服務將對外部隱藏邏輯。
服務的重用性 – 將邏輯分布在不同的服務中,以提高服務的重用性。
服務的可組合性 – 一組服務可以協調工作並組合起來形成乙個組合服務。
服務自治 – 服務對所封裝的邏輯具有控制權
服務無狀態 – 服務將乙個活動所需儲存的資訊最小化。
服務的可被發現性 – 服務需要對外部提供描述資訊,這樣可以通過現有的發現機制發現並訪問這些服務。
soa 相關資料:
深入淺出soa
面向服務的架構
2. rest 與 restful
restful 架構概念,是 fielding 提出的,fielding 這號人物就是 http 協議的主要設計者之一。我們先看下 restful 這個詞,ful 是跟在名詞之後,表示程度,什麼什麼的,例如 helpful 樂於助人的,因此我們可以看出符合 rest 的架構就可以稱為 restful,接著我們看下 rest,全稱為「representational state transfer」,意為「表現層狀態轉化」。
在符合架構原理的前提下,理解和評估以網路為基礎的應用軟體的架構設計,得到乙個功能強、效能好、適宜通訊的架構。 -fielding
這是 fielding 在**中所提到的,對於 rest 雖說是架構,但如果深入一點,就像是 http 協議一樣,可以看成一種規則或是協議。我們從乙個地點到另乙個地點,可以坐汽車、高鐵、飛機等,對於 rest 就像是其中的一種交通方式,但 rest 的根本是 http 協議,也就是說 rest 是基於 http 協議的,這點就像坐汽車必須要有公路,坐高鐵必須要有鐵路是一樣的道理,有時候為什麼選用 rest,就像我們從南京到徐州,選擇坐高鐵而不選擇坐飛機一樣。
「representational state transfer」我們分解下:
representational 表現層:表現層表現什麼,應該呈現資源(resources),乙個、一段文字、乙個檔案都成為資源,每個資源都用乙個 uri(統一資源定位符)指向它,表現層就是呼叫 uri 把資源呈現出來,而且只是呈現,不做其他操作。舉個例子:有些**最後的".html"字尾名是不必要的,因為這個字尾名表示格式,屬於"表現層"範疇,而 uri 應該只代表"資源"的位置。它的具體表現形式,應該在 http 請求的頭資訊中用 accept 和 content-type 字段指定,這兩個欄位才是對"表現層"的描述。
state transfer 狀態轉化:訪問乙個**,就表示客戶端和伺服器發生一次互動行為,在這個過程中,就不發生資料和狀態的轉化,上面說到 http 協議具有無狀態性,如果客戶端操作伺服器,必須要狀態轉化,這個體現在表現層上,所以叫「表現層狀態轉化」。
通過上面的理解,可以總結下什麼是 restful 架構:
每乙個 uri 代表一種資源。
客戶端和伺服器之間,傳遞這種資源的某種表現層。
客戶端通過四個 http 動詞(put、get、post 和 delete),對伺服器端資源進行操作,實現"表現層狀態轉化"。
上面 rest 和 restful 的概念,摘自很久之前的一篇博文:初試asp.net web api/mvc api(附demo),並做了部分修改。
我再來說一下自己現在的理解,首先,rest 是一種架構風格,而不是一種架構,一種架構風格可以用多種架構進行實現,乙個架構中也可能包含多種架構風格,這兩者的關係,你可以理解為抽象和實現的區別,另外,rest 嚴格來說,應該屬於 web 架構的一種架構風格,因為它離不開 http 協議。
rest 架構風格的兩個關鍵:
2.1 資源(resources)
web 資源的表述是 uri,乙個規範的 uri 就是開放出來的乙個資源,它是唯一並具有一定的規範,對資源的操作方式就是 http 提供的方法(put、get、post 和 delete),資源的表現形式是多樣的,比如:json、xml、yaml 等。
我們看一下常用的 uri:
很顯然,這種 uri 不符合 rest 對資源的定義,我們嘗試修改一下:
cnblogs.com/user/1,這個 uri 一般表述的含義是:id 為 1 的 user 資源,這個僅僅是表述,uri 並不包含對這個資源的任何操作,所以,像 getuser、createuser 這類操作就不合適,資源的操作是通過 http 提供的方法,還有一點是,比如 post 中的cnblogs.com/user 和 cnblogs.com/user/1 有什麼不同?第一種 post,一般是建立乙個新的 user 資源,建立完成後,一般會返回這樣的乙個 uri:cnblogs.com/user/1,第二種 post,不是說建立乙個 id 為 1 的 user 資源,而是在 id 為 1 的 user 資源下建立某種資源,你會發現,好的 uri 設計應該不包含動詞。
2.2 狀態(state)
首先,rest 是無狀態的(statelessness),我之前是一直不理解狀態的含義,好像還把狀態和資源格式(xml、json)混為一談,現在想想確實太荒謬了,關於狀態的幾個要點:
在 asp.net 應用程式中,我們都知道 session 的概念,意為會話,也就是有關使用者請求的會話,應該劃分為應用狀態,這個會話狀態是儲存在服務端的,從這一點上來說,這種設計就是 unrestful 風格,rest 中的無狀態,是客戶端和服務端互動中所表達的一種概念,有時候,雖然應用狀態可能不儲存在服務端,但客戶端發起的某些請求所表達的含義不恰當,也可以認為是不符合 restful 風格,比如客戶端發起的請求中包含 session id,在服務端看來,客戶端發起的這個請求,所表達的含義是要獲取某個 session,具體來說就是會話狀態儲存在服務端,這個雖然只是乙個客戶端請求的概念,但也可以認為這種設計是 unrestful 風格。
總的來說,架構風格不是某一種具體架構,它是一種風格。
六邊形平面
現在有乙個n n的六邊形網格平面 這種平面類似蜂窩形狀 下圖是n 1,2,3,4條件下的具體形狀,根據它們可以依次類推n 5,6,現在你需要對n n網格中一些格仔進行上色,在給定的輸入中這些格仔被標記上字元 x 而不用上色的網格被標記為 上色時需要注意,如果兩個被上色的格仔有公共邊,那麼這兩個格仔需...
2701 六邊形點陣
題目描述 description 輸入六邊形的邊長n,請你畫出這個六邊形點陣。輸入描述 input description 僅一行,乙個整數n 輸出描述 output description 六邊形點陣 有兩條邊水平 樣例輸入 sample input 6 樣例輸出 sample output 資料...
未知 六邊形 題解
接上題,反正是一起做的那麼故事情節也接上吧嘻嘻嘻 正好,帶我去一趟天線崖。你確定?你都說了都要暴雨了,前幾天的暴雨 是啊,你還抱怨整天悶在家裡啥事也沒幹呢,結果就剩下我在刷題而你整天再睡覺。因為山脈的阻隔,所以他們只能乘坐小船到達那裡。而給他們租小船的人,開出了很高的價錢,但是。你們幫我解決乙個問題...