總覽
六角體系結構是一種軟體體系結構,它使應用程式可以由用戶,程式,自動測驗或批處理腳本平等驅動,并且可以獨立于其運行時目標系統進行開發,目的是創建一個無需用戶界面或資料庫即可運行的應用程式,以便我們可以對該應用程式運行自動回歸測驗,在運行時系統(例如資料庫)不可用時使用該應用程式,或無需用戶界面即可集成應用程式,
動機
許多應用程式有兩個目的:用戶端和服務器端,通常以兩層,三層或n層體系結構設計,n層體系結構的主要問題是沒有認真對待層線,從而導致應用程式邏輯越過邊界泄漏,業務邏輯和互動之間的這種糾纏使不可能或很難擴展或維護應用程式,
例如,當應用程式業務邏輯未完全隔離在其自身邊界內時,添加新的有吸引力的UI以支持新設備可能是一項艱巨的任務,此外,應用程式可以有兩個以上的方面,這使得很難更好地適應一維圖層體系結構,
六角形或埠和配接器或洋蔥結構解決了這些問題,在這種體系結構中,內部應用程式通過一定數量的埠與外部系統進行通信,在這里,術語“六角形”本身并不重要,而是表明了在應用程式中以均勻和對稱的方式插入埠和配接器的效果,主要思想是通過使用埠和配接器隔離應用程式域,
在埠和配接器周圍組織代碼
讓我們構建一個小型的anagram應用程式,以展示如何在埠和配接器周圍組織代碼以表示應用程式內部和外部之間的互動,在左側,我們有一個應用程式,例如控制臺或REST,而內部則是核心業務邏輯或域,anagram服務采用兩個字串,并回傳一個布林值,該布林值對應于兩個String引數是否彼此為字母,在右側,我們有服務器端或基礎結構,例如,一個用于記錄有關服務使用情況的度量標準的資料庫,
下面的Anagram應用程式源代碼顯示了如何在內部隔離核心域以及如何提供埠和配接器以與其進行互動,
域層
域層代表應用程式的內部,并提供與應用程式用例進行互動的埠,
- IAnagramServicePort 介面定義了一個方法,該方法接受兩個String字并回傳一個布林值,
- AnagramService 實作該IAnagramServicePort介面并提供業務邏輯以確定兩個String引數是否為anagram,它還使用IAnagramMetricPort來將服務使用度量輸出到服務器端運行時外部物體(例如資料庫),
應用層
應用程式層為外部物體與域互動提供了不同的配接器,互動依賴項進入內部,
-
ConsoleAnagramAdaptor 使用IAnagramServicePort來與應用程式內的域進行互動,
-
AnagramsController 還使用IAnagramServicePort與域進行互動,同樣,我們可以撰寫更多的配接器,以允許各種外部物體與應用程式域進行互動,
基礎設施層
提供配接器和服務器端邏輯,以從右側與應用程式進行互動,服務器端物體(例如資料庫或其他運行時設備)使用這些配接器與域進行互動,請注意,互動依賴項位于內部,
外部物體與應用程式互動
以下兩個外部物體使用配接器與應用程式域進行互動,如我們所見,應用程式域是完全隔離的,并且由它們平等地驅動,而不管外部技術如何,
這是一個使用配接器與應用程式域互動的簡單控制臺應用程式:
@Configuration
public class AnagramConsoleApplication {
@Autowired
private ConsoleAnagramAdapter anagramAdapter;
public static void main(String[] args) {
Scanner scanner = new Scanner([http://System.in](https://link.zhihu.com/?target=http%3A//System.in));
String word1 = scanner.next();
String word2 = scanner.next();
boolean isAnagram = anagramAdapter.isAnagram(word1, word2);
if (isAnagram) {
System.out.println("Words are anagram.");
} else {
System.out.println("Words are not anagram.");
}
}
}
這是一個簡單的測驗腳本示例,該腳本使用REST配接器模擬用戶與應用程式域的互動,
@SpringBootTest
@AutoConfigureMockMvc
public class AnagramsControllerTest {
private static final String URL_PREFIX = "/anagrams/";
@Autowired
private MockMvc mockMvc;
@Test
public void whenWordsAreAnagrams_thenIsOK() throws Exception {
String url = URL_PREFIX + "/Hello/hello";
this.mockMvc.perform(get(url)).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("{\"areAnagrams\":true}")));
}
@Test
public void whenWordsAreNotAnagrams_thenIsOK() throws Exception {
19
String url = URL_PREFIX + "/HelloDAD/HelloMOM";
this.mockMvc.perform(get(url)).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("{\"areAnagrams\":false}")));
}
@Test
public void whenFirstPathVariableConstraintViolation_thenBadRequest() throws Exception {
String url = URL_PREFIX + "/11/string";
this.mockMvc.perform(get(url)).andDo(print()).andExpect(status().isBadRequest()).andExpect(
content().string(containsString("string1")));
}
@Test
public void whenSecondPathVariableConstraintViolation_thenBadRequest() throws Exception {
String url = URL_PREFIX + "/string/11";
this.mockMvc.perform(get(url)).andDo(print()).andExpect(status().isBadRequest()).andExpect(
content().string(containsString("string2")));
}
}
結論
使用埠和配接器,應用程式域在內部六邊形處被隔離,并且無論外部系統或技術如何,它都可以由用戶或自動測驗腳本同樣驅動,
點我更多-》》》》》
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/230767.html
標籤:其他
下一篇:作業211:新的封裝組件 秒呀
