反腐層ACL - 一個有效的盾牌 - Manuel López Torrent
我第一次聽說反腐敗層(ACL)一詞是在Eric Evans的書“領域驅動設計”中。那些日子,DDD是我正在探索的一個新領域,我對所有這些新概念感到非常興奮,但我沒有實現大部分概念。
近年來,在我所做的幾乎所有開發中,我不得不處理遺留程式碼,資料儲存庫或“第三方”子系統,並且ACL已經“形成”,當我們處理其他子系統時必須特別注意它。
在wiki.c2.com(http://wiki.c2.com/?AnticorruptionLayer)中,我們可以找到ACL的定義:
“如果您的應用程式需要處理資料庫或其他應用程式,這些應用程式的模型不合適或不適用於您自己的應用程式中所需的模型,請使用反腐敗層轉換為該模型或從您的模型轉換為您的模型”
在Eric Evans的書中,他寫了兩句相信非常有趣的句子:
“但是當邊界的另一邊開始洩漏時,轉換層可能會採取更加防禦的語氣。”
“當基於不同模型的系統結合在一起時,新系統適應其他系統語義的需求可能導致新系統自身的損壞”
基本概念非常清楚。當我們需要與其他系統,資料儲存庫或遺留程式碼(甚至是“我們的”遺留程式碼)“交談”時,我們應該阻止我們的模型與其他“外面模型”混合。
我們必須將這些外部系統或資料儲存庫視為不同的有界上下文,當然,它將擁有自己的模型,它將與我們的模型建立關係。
大多數情況下,這種對映將是customer/supplier(釋出訂閱)型別,我們通常將是消費訂閱一方。
即使您沒有在您的開發中實施DDD,ACL也是一個非常好的“工具”。
如您所見,ACL不僅是一個簡單的翻譯層。如果我們開發ACL,我們應該設計:
- 翻譯模型
- 防止失敗
- 監控
- 改進我們的整合測試
一個例子
想象一下,我們正在開發一個銀行相關的應用程式。我們需要處理附加到帳戶的信用卡。
要獲取此資訊,我們需要與舊的且不太可靠的SOAP伺服器通訊,以檢索附加到帳戶的信用卡資訊。
實現ACl層的方法有很多種,但我們總是使用外觀設計模式,如外觀,介面卡和翻譯器。
翻譯模型
這是我們的模型。我們有一個基本的信用卡資訊,我們可以用一些眾所周知的演算法驗證它。
class CreditCard attr_accessor :card_number, :card_holder, :expiration_year, :expirartion_month, :type def initialize(args) @card_number = args[:card_number] @card_holder = args[:card_holder] @expiration_year = args[:expiration_year] @expirartion_month = args[:expirartion_month] @type = args[:type] validate_card_number end private def validate_card_number CreaditCardValidator::validate(self) end end class CreaditCardValidator def self.validate(credid_card) # Validate or raise CreditCardInvalidNumber end end class CreditCardInvalidNumber < StandardError; end |
這裡我們有一個服務,可以從SOAP伺服器中恢復信用卡:
class SoapClientWrapper def get_card_data(account_number) foreign_cards = get_fixtures(account_number) foreign_cards.map { |c| yield c } end Customer = Struct.new(:name, :surname, :number, :date, :type) def get_fixtures(card_number) [ Customer.new("Dave", "Foo", "371449635398431", "02/20", "American Express"), Customer.new("Jane", "Bar", "5555555555554444", "10/21", "MasterCard"), Customer.new("Micha", "Jar", "4111111111111111", "14/23", "visa" ) ] end end class CreaditCardService attr_reader :cards def initialize(soap_client) @soap_client = soap_client end def get_card_from_account(account_number) begin @cards = @soap_client.get_card_data(account_number) do |card| CreditCard.new( :card_holder => card.name + card.surname, :card_number => card.number, :expiration_year => card.date.split('/')[1], :expirartion_month => card.date.split('/')[0] ) end rescue Exception => e raise CreaditCardServiceError end end end class CreaditCardServiceError < StandardError; end |
正如您在程式碼中看到的,我們會恢復信用卡資訊並轉換為我們的模型。
這裡的要點是,我們總是會提供一個帳號,我們會恢復附加到此帳戶的信用卡列表,如果出現問題我們會捕獲異常。
如果第三方系統發生變化,我們只需要更改我們的翻譯器,或者即使服務協議發生變化,我們也只需要修改一個類來保持模型的完整性。
準備好失敗
如果信用卡伺服器掉落,我們的申請會怎樣?我們的應用程式會看到錯誤500嗎?也許警告頁面對我們的使用者來說更加容易,或者隱藏這部分頁面資訊並顯示其餘部分,或者我們可以使用“cirtuit破壞者”並提供快取響應。
也許你需要不止一個例外之王來為故障新增更多粒度(即CardServiceConnectionError,CardServiceTranslationError)
改善我們的服務
這個抽象層的存在允許我們裝飾它並新增更多功能,以增加我們系統的防禦。可能我們需要記錄所有交易以進行一些審計。也許,我們可以測量時間響應或響應程式碼並將所有遙測傳送到ELK堆疊。
我們來裝飾我們的服務:
class TimeCreaditCardService def initialize(credit_card_service) @credit_card_service = credit_card_service end def get_card_from_account(account_number) measure { @credit_card_service.get_card_from_account(account_number) } end def measure start = Time.now result = yield finish = Time.now @delta = finish - start # in seconds return result end def get_time puts "Time elapsed #{(@delta)*1000} milliseconds" end end |
根據我的經驗,當我們開發一個“前端”時,這可能是一個很好的實踐,因為我們是冰山的可見部分。大多數時候,監控子系統將幫助我們檢測應用程式中的錯誤原因。
整合測試
當我們建立整合測試時,我們需要從眾所周知的系統狀態開始。例如,如果我們想測試儲存庫和資料庫之間的整合,我們需要建立表,填充一些具體資料,執行測試並檢查資料庫狀態是否按照我們預期的方式更改。
如今,使用虛擬化(如Docker)複製資料庫非常容易,我們可以在CI管道中的整合測試中執行它。
如果系統不在我們的控制之下,這可能會更復雜甚至不可能,並且我們無法確保在執行測試時我們始終具有相同的狀態。
ACL允許我們模擬這個系統,這樣,我們可以測試我們的程式碼在失敗前做出反應。
我們可以模擬子系統響應並測試如何使用這個新夥伴來執行我們的有界上下文。
結論
使用ACL,我們將獲得:
- 翻譯資訊
- 防止其他子系統故障
- 記錄和監視關係
- 良好的整合測試
相關文章
- 有效提升Python程式碼效能的三個層面Python
- AiTracker.art:一個基於Torrent的AI模型分發器AI模型
- torrent cache websiteWeb
- 根據Taipei-Torrent修改出的三個bt工具AI
- 如何完成一個有效的面試面試
- 如何制定一個有效的測試策略
- Taipei-Torrent使用AI
- Torrent檔案的解析與轉換
- win10桌面圖示有個盾牌怎麼去掉_windows10圖示有個小盾牌如何取消Win10Windows
- win10圖示有個盾牌怎麼取消掉_win10如何關閉桌面圖示盾牌Win10
- 一個快速切換一個底層實現的思路分享
- ACL
- ACL主席:ACL不是AI會議AI
- win10如何去除小盾牌_w10小盾牌怎麼去除Win10
- win10 盾牌有個紅叉怎麼辦_win10右下角盾牌紅色X怎麼關掉Win10
- win10怎麼去除圖示盾牌_win10去除圖示盾牌的操作步驟Win10
- win10怎麼關閉軟體上的盾牌_怎麼取消win10軟體的盾牌Win10
- SD & ACL
- 商業智慧的三個層次,你在哪個層次?
- Python入門必學,用Python練習畫個美隊盾牌Python
- ui設計怎樣做出有效果的視覺層級?UI視覺
- 用一個專案把控制層、業務層、持久層說明白了,每一句話都講的很清楚
- L2_006樹的遍歷(後序+中序->前序/層序)
- Windows10系統開啟torrent檔案的方法Windows
- win10有些軟體有盾牌怎麼辦_win10裝完軟體後有個小盾牌圖示如何解決Win10
- WinIO:一個底層的鍵盤事件模擬工具事件
- ACL實驗
- acl 編譯編譯
- 如何免費做一個屬於自己穩定有效的圖床圖床
- 自己動手寫一個持久層框架框架
- 有效採購流程的7個步驟
- 有效尋源的4個最佳實踐
- 有效的微服務:10 個最佳實踐微服務
- 5個步驟實現有效的DevSecOpsdev
- win10圖示盾牌怎麼去掉_win10如何關閉桌面圖示盾牌Win10
- 【知識圖譜】 一個有效的知識圖譜是如何構建的?
- Win10系統消除程式上的小盾牌操作方法 Win10程式上的盾牌圖示怎麼去掉Win10
- L1-030 一幫一