《企業應用架構模式》學習指南

導讀:企業應用包括哪些?它們又分別有哪些架構模式?
世界著名軟件開發大師Martin Fowler給你答案

01什么是企業應用

我的職業生涯專注于企業應用,因此,這里所談及的模式也都是關于企業應用的。(企業應用還有一些其他的說法,如“信息系統”或更早期的“數據處理”。)那么,這里的“企業應用”具體指的是什么呢?我無法給出一個精確的定義,但是我可以羅列一些個人的理解。

先舉幾個例子。企業應用包括工資單、患者記錄、發貨跟蹤、成本分析、信用評分、保險、供應鏈、會計、客戶服務以及外匯交易等。企業應用不包括汽車燃油噴射、文字處理、電梯控制、化工廠控制器、電話交換機、操作系統、編譯器以及電子游戲等。

企業應用一般都涉及持久化數據。數據必須持久化是因為程序的多次運行都需要用到它們——實際上,有些數據需要持久化若干年。在此期間,操作這些數據的程序往往會有很多變化。這些數據的生命周期往往比最初生成它們的那些硬件、操作系統和編譯器還要長。在此期間,為了存儲新的信息而不干擾舊的信息,數據的結構經常會發生許多變化。即使是有根本性的變化發生,或公司安裝了一套全新的軟件來處理某項任務,這些數據也必須被“遷移”到新的應用上。

企業應用一般都涉及大量數據,一個中等規模的系統往往都包含1GB以上的數據,這些數據是以數千萬條記錄的方式存在的。巨大的數據量導致數據的管理成為系統的主要工作。早期的系統使用的是索引文件結構,如IBM的VSAM和ISAM。現代的系統往往采用數據庫,絕大多數是關系型數據庫。設計和填充這些數據庫已經成為一個獨立的專業領域。

企業應用一般還涉及很多人并發訪問數據。對于很多系統來說,人數可能在100人以下,但是對于一些通過互聯網進行通信的基于Web的系統,人數則會呈指數級增長。要確保這些人都能夠正確地訪問數據,就一定會存在這樣或那樣的問題。即使人數沒有那么多,要確保兩個人在同時操作同一數據項時不出現錯誤,也是存在問題的。事務管理工具可以處理其中的一些負擔,但是它通常無法做到對應用開發者隱藏。

企業應用還涉及大量操作數據的用戶界面屏幕。有幾百個用戶界面屏幕是不足為奇的。企業應用的用戶從偶爾使用到定期使用都有,他們也經常沒什么技術背景。因此,出于不同的使用目的,數據需要很多種表現形式。系統一般都有很多批處理過程,但當專注于強調用戶交互的用例時,這些批處理過程很容易被忽視。

企業應用很少獨立存在,通常需要與散布在企業周圍的其他企業應用集成。這些各式各樣的系統是在不同時期采用不同技術構建的,甚至連協作機制都不同:COBOL數據文件、CORBA系統或是消息系統。企業經常希望能用一種統一的通信技術來集成所有系統。當然,每次這樣的集成工作幾乎都很難真正實現,所以會有幾個不同的統一集成方案同時存在。當業務組織需要同其業務伙伴進行應用集成時,情況就更糟糕。

即使是某家公司統一了集成技術,它們也還是會遇到業務流程中的差異以及數據中概念的不一致性。一個部門可能認為客戶是當前簽有協議的人,而另外一個部門可能還要將那些以前有合同但現在已經沒有了的人計算在內。再有,一個部門可能只關心產品銷售而不關心服務銷售。粗看起來,這些問題似乎容易解決,但是,一旦幾百條記錄中的每個字段都有可能存在著細微差別,問題的規模就會形成不小的挑戰——就算唯一知道這些字段真正含義的員工還在公司任職(當然,所有這些都會毫無預警地發生變化)。這樣,數據就必須被不停地以各種不同的語法和語義格式讀取、轉換和寫入。

再接下來的問題是由“業務邏輯”帶來的。我認為“業務邏輯”這個詞很滑稽,因為很難再找出什么東西比“業務邏輯”更加沒有邏輯。當我們構建一個操作系統時,總是盡可能地使得系統中的各種事物符合邏輯。而業務規則是人家給你的,沒有相當的行政努力,不要想改變它,當然,它們都有自己的理由。你必須面對很多奇怪的條件,而且這些條件相互作用的方式也非常怪異。比如,某個銷售人員為了簽下其客戶幾百萬美元的一張單,可能會在商務談判中與對方達成協議,將該項目的年度到賬時間推遲兩天,因為這樣才能夠與該客戶的賬務周期相吻合。成千上萬的這類“一次性特殊情況”最終導致了復雜的業務“無邏輯”,使得商業軟件開發那么困難。在這種情況下,必須盡量將這些業務邏輯組織成有效的方式,因為我們可以確定的是,這些“邏輯”一定會隨著時間不斷變化。

圖片

▲對不同的領域邏輯組織方式,領域邏輯的復雜度和工作量之間的關系示意

對于一些人來說,“企業應用”這個術語指的是大型系統。但是記住這一點很重要:并不是所有的企業應用都是大型的,盡管它們可能都為企業提供巨大的價值。很多人認為,由于小型系統的規模不大,所以不值得為之操心,在某種程度上,這是合理的。如果一個小型系統失敗了,它通常不會像大型系統那樣引起廣泛關注。但是,我認為這種思想沒有對小型項目的累積效應給予足夠的重視。試想,如果在小型項目上能夠進行某些改善措施,那么這種累積效應對企業的影響是非常顯著的,特別是因為小型項目通常具有不成比例的價值。實際上,你可以做的最好的事情之一是通過簡化架構和過程,將一個大型項目變成小型項目。

02 企業應用的種類

在我們討論如何設計企業應用以及使用哪些模式之前,認識到這一點很重要:**企業應用是多種多樣的,不同的問題將導致不同的處理方法。**如果有人說,“總是這樣做”的時候,就應當敲響警鐘了。我認為,設計中最具挑戰性(也是我最感興趣)的地方就是了解有哪些候選的設計方案以及各種不同設計方案之間的優劣比較。進行選擇的空間很大,但我在這里只選三個方面。

考慮一個B2C(Business to Customer)的在線零售商:人們瀏覽和——運氣好,還有購物車——購買。這樣一個系統必須能夠應付大量的用戶,因此,其解決方案不但要考慮到資源利用的高效,還要考慮到系統的可伸縮性,以便在用戶規模增大時能夠通過增加硬件的辦法加以解決。這樣的應用的領域邏輯可能非常直接:獲取訂單,進行簡單的價格計算和發貨計算,給出發貨通知。我們希望任何人都能夠輕松訪問該系統,因此用戶界面可以選用通用的Web表現方式,以支持各種不同的瀏覽器。數據源包括用來存放訂單的數據庫,還可能包括某種與庫存系統的通信交流,以便獲得商品的可用性信息和發貨信息。

再考慮一個租約自動處理系統。在某些方面,這樣的系統比起前面介紹的B2C零售商系統要簡單得多,因為它的用戶數很少(在特定時間內不會超過100個),但是它的業務邏輯卻比較復雜。計算每個租約的月供,處理諸如提早解約和逾期付款這樣的事件,簽訂合同時驗證各種數據,這些都是復雜的任務,因為租約行業的許多競爭都是以過去的交易為基礎稍加變化而出現的。正是因為規則的隨意性很大,才使得像這樣一個復雜的業務領域具有挑戰性。

這樣的系統在用戶界面(UI)上也更加復雜。這就要求HTML界面要能提供更豐富的功能和更復雜的屏幕,而這些要求往往是HTML前端目前無法達到的,需要更傳統的富客戶界面。用戶交互的復雜性還會帶來事務行為的復雜性:簽訂租約可能要耗時1~2小時,這期間用戶要處于一個邏輯事務中。一個復雜的數據庫設計方案中可能也會涉及200多個表以及一些有關資產評估和計價的軟件包。

第三個例子是一家小型公司使用的簡單的“開支跟蹤系統”。這個系統的用戶很少,邏輯簡單,并且可以通過HTML表示輕松地在整個公司訪問,唯一的數據源是數據庫中的幾個表。盡管如此,開發這樣的系統也不是沒有挑戰。一方面你必須快速地開發出它,另一方面你又必須為它以后可能的發展考慮:也許以后會為它增加計算報銷支票的功能,也許它會被集成到工資系統中,也許還要增加關于稅務的功能,也許要為公司的CFO生成匯總報表,也許會被集成到一個航空訂票Web Service中,等等。如果在這個系統的開發中,也試圖使用前面兩個例子中的一些架構,可能會影響開發進度。如果一個系統會帶來業務效益(如所有的企業應用應該的那樣),則系統進度延誤同樣也是開銷。你不希望現在做出的決策會阻礙未來的發展。但是,如果現在就考慮了這些靈活性但是考慮不得當,額外的復雜性又可能會讓系統在未來變得更難演化,進一步延誤系統部署,減少系統的效益。雖然這類系統很小,但是一個企業中往往有很多這樣的系統,這些系統的架構不良性累積起來,后果將會非常可怕。

這三個企業應用的例子都有難點,而且難點各不相同。當然,也不可能有一個適合于三者的通用架構。選擇架構時,必須很清楚地理解系統的特定問題,在理解的基礎上再來選擇合適的設計。

03企業架構模式

模式的概念早就有了。我在這里不想把這段歷史重新演繹一遍。只是想簡單談談我對模式和它們為什么是描述設計的重要手段的一些看法。

模式沒有統一的定義,可能最好的起點是Christopher Alexander給出的定義(這也是許多模式狂熱者的靈感來源):

“每一個模式描述了一個在我們周圍不斷重復發生的問題以及該問題解決方案的核心。這樣,你就能一次又一次地使用該方案而不必做重復勞動”[Alexander et al.]。

盡管Alexander是建筑家,他談論的是建筑模式,但其定義也能很好地適用于軟件業。模式的核心就是特定的解決方案,它有效而且有足夠的通用性,能解決重復出現的問題。模式的另一種視角是把它看成一組建議,而創造模式的藝術則是將很多建議分解開來,形成相互獨立的組,在此基礎上可以相對獨立地討論它們。

模式的關鍵點是它們源于實踐。必須觀察人們的工作過程,發現其中好的設計,并找出“這些解決方案的核心”。這并不是一個簡單的過程,但是一旦發現了某個模式,它將是非常有價值的。

一旦需要使用模式,就必須知道如何將它運用于當前的問題。使用模式的關鍵之一是不能盲目使用,這也是模式工具為什么都那么慘。我認為模式是一種“半生不熟品”,為了用好它,還必須在自己的項目中把剩下的那一半“火候”補上。我本人每次在使用模式時,都會東改一點西改一點。因此你會多次看到同一個解決方案,但沒有一次是完全相同的。

每個模式相對獨立,但又不彼此孤立。有時候它們相互影響,如影隨形。

《企業應用架構模式》一書中總結出的51種模式:

圖片

如果你是一個有經驗的企業應用設計師,也許會對大多數模式都很熟悉。模式不是什么新鮮概念。因此,撰寫模式書籍的作者也不會聲稱我們“發明”了某某模式,而是說我們“發現”了某某模式。我們的職責是記錄通用的解決方案,找出其核心,并把最終的模式記錄下來。對于一個高級設計師,模式的價值并不在于它給予你一些新東西,而在于它能幫助你更好地交流。如果你和你的同事都明白什么是遠程外觀,你就可以這樣非常簡捷地交流大量信息:“這個類是一個遠程外觀模式。”也可以對新人說:“用數據傳輸對象模式來解決這個問題。”模式為設計提供了一套詞匯,這也是模式的名字如此重要的原因。

當你使用模式時請記住:它們只是開始,而不是結束。任何作者去囊括項目開發中的所有變化和技術是不可能的。我編寫《企業應用架構模式》一書的目的也只是作為一個開始,希望它能夠把我自己的和我所了解的經驗和教訓傳遞給讀者,你們可以在此基礎上繼續努力。請大家記住:所有模式都是不完備的,你們都有責任在自己的系統中完善它們,你們也會在這個過程中得到樂趣。

圖片

關于作者:
馬丁·福勒(Martin Fowler),世界著名軟件開發大師,Thoughtworks首席科學家,從事軟件開發相關工作30余年,是全球軟件架構、敏捷開發、極限編程、設計模式等多個領域的領袖人物。此外,他在面向對象分析與設計、UML、數據庫、領域特定語言等領域也有深厚的積累和卓越的貢獻。

本文摘編于《企業應用架構模式》(書號:9787111746959),經出版方授權發布,轉載請標明文章出處。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/22226.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/22226.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/22226.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

怎么用NodeJS腳本實現遠程控制空調

怎么用NodeJS腳本實現遠程控制空調呢? 本文描述了使用NodeJS腳本調用HTTP接口,實現控制空調,通過不同規格的通斷器,來控制不同功率的空調的電源。 可選用產品:可根據實際場景需求,選擇對應的規格 序號設備…

MySQL從入門到高級 --- 12.事務 13.鎖機制 14.日志

文章目錄 第十二章 && 第十三章 && 第十四章:12.事務12.1 特性12.2 隔離級別 13.鎖機制13.1 各存儲引擎對鎖的支持狀況:13.2 鎖特性13.3 MyISAM表鎖13.3.1 加表鎖 13.4 InnoDB行鎖13.4.1 行鎖特點13.4.2 行鎖模式 14.日志14.1 錯誤日志1…

深入理解計算機系統 第三版 中文版 圖5-27 p371 錯漏

中文版 英文版 對照 可以看出錯漏 這本書中文版很多錯漏,可以配合英文版查正,不過英文版也很多錯漏,所以不用太相信書本.要根據自己的理解來.

微軟云計算Windows Azure(一)

目錄 一、微軟云計算平臺二、微軟云操作系統Windows Azure(一)Windows Azure概述(二)Windows Azure計算服務(三)Windows Azure存儲服務(四)Windows Azure Connect(五&…

Win 11官宣取消硬件限制,微軟這次徹底服軟了

上市近 3 年,微軟寄予厚望的 Win 11 終究落了個被上代 Win 10 光環狠狠掩埋的結局。 有小伙伴兒認為是 Win 11 本身做的太爛,更新頻繁、BUG 一堆,讓人失去興趣。 也有人認為,系統本身體驗沒啥大毛病,嚴苛的硬件限制才…

數據結構算法-堆排序

堆排序:利用堆的特性進行排序,先將數組轉換為堆對象(最大堆或最小堆),以最大堆為例,每次heapify之后,取出堆頂(索引為0)的元素與最后一個元素交換。以后每次做同樣的事情,只是堆的長…

Golang性能分析工具pprof--遠程分析時無法定位源代碼行數問題解決方案

場景 通過命令行模式的list命令,為了查看指標消耗在具體哪一行,需要源代碼。但實際程序是部署在線上或者程序的源代碼目錄變了,則pprof從默認路徑找不到代碼,無法顯示是哪一行的問題。 通過瀏覽器模式的source頁面,有…

JUC總結3

CAS 簡介 CAS的全稱是“比較并交換”,是一種無鎖的原子操作,其體現了樂觀所的思想,在無鎖的情況下保證線程操作共享數據的原子性。 CAS一共有3個值: 1、V:要更新的值; 2、E:預期值&#xf…

RHCE (Linux進階) Ubuntu 操作系統安裝教程

一、在官網下載iso鏡像文件 下載地址: https://cn.ubuntu.com/download/server/step1#downloads(下載最新的Ubuntu 20.04 LTS服務器版本) 二、VMware安裝配置過程 基本安裝過程 1、新建虛擬機 2、選擇典型即可 3、設置下載好的Ubuntu對應路…

Exception異常機制詳細講解

目錄 一、異常1.1 什么是異常1.2 異常機制的作用1.3 常見的異常2.3 異常的分類1. Error2. Exception① 運行時異常② 編譯期異常總結: 二、異常的處理2.1 拋出異常3.1 拋出異常語法3.2 試圖捕獲異常3.3 捕獲異常與拋出異常的區別1. 拋出異常2.捕獲異常 三、finally四…

Spring Cloud:構建高可用分布式系統的利器

摘要:本文將介紹Spring Cloud,一個基于Spring Boot的開源微服務架構工具集。我們將探討Spring Cloud的核心組件、特性以及如何使用Spring Cloud構建高可用、分布式系統。通過本文,讀者將了解到Spring Cloud在實現微服務架構中的應用和優勢。 …

【Springcloud微服務】MybatisPlus下篇

🔥 本文由 程序喵正在路上 原創,CSDN首發! 💖 系列專欄:Springcloud微服務 🌠 首發時間:2024年6月4日 🦋 歡迎關注🖱點贊👍收藏🌟留言&#x1f43…

24、matlab二維和三維網格(meshgrid函數)以及散點數據插值 griddata()函數

1、二維和三維網格(meshgrid函數) 語法 語法1:[X,Y] = meshgrid(x,y) 基于向量 x 和 y 中包含的坐標返回二維網格坐標。 語法2:[X,Y] = meshgrid(x) 與 [X,Y] = meshgrid(x,x) 相同,并返回網格大小為 length(x)length(x) 的方形網格坐標。 語法3:[X,Y,Z] = meshgrid(x,y,…

汽車銷售門店零售價格違規檢查的實踐經驗方法

隨著汽車市場的蓬勃發展,汽車銷售門店的零售價格合規性日益受到業界和消費者的關注。為確保銷售過程的公平與透明,開展零售價格違規檢查顯得尤為重要。 在這方面,深圳神秘顧客(SMS)公司憑借其深厚的實踐經驗和專業技巧…

弘君資本炒股開戶:如何看待股價波動?

在股票商場上股價的動搖無疑是投資者最為關心的話題之一,面臨股價的起伏不定投資者往往會感到迷茫和焦慮。關于怎么看待股價動搖,弘君資本下面就為大家詳細介紹一下。 股價動搖是股市運行的常態,股市是國民經濟的晴雨表,股票價格…

Flink run 自動化運行任務shell腳本

Linux命令行: sh flink_run.sh test com.dzj.app.base.test.FlinkKafkaOffsetTest /root/soft/test.jar flink_run.sh腳本內容: #!/bin/bash# 檢查參數數量是否正確 if [ "$#" -ne 3 ]; thenecho "錯誤:需要提供 3 個參數&…

SpringBoot+layui實現Excel導入操作

excel導入步驟 第三方插件引入插件 效果圖 (方法1)代碼實現(方法1)Html代碼( 公共)下載導入模板 js實現 (方法1)上傳文件實現 效果圖(方法2)代碼實現&#xf…

多語言大模型 Aya-23 開源!覆蓋23種語言,性能刷新SOTA

文章目錄 1. Aya-23 技術特點1.1 預訓練階段1.2 指令微調階段 2. Aya-23 性能表現3. Aya-23 多語言任務評估4. Aya-23 支持 23 種語言5. Aya-23 應用場景 近年來,多語言大模型(MLLM)發展迅速,但大多數模型的性能依然存在顯著差距&…

“滴滴打車,用友入賬”,YonSuite商旅費控助力企業“降低成本”更進一步

在當今競爭激烈的商業環境中,企業對于成本控制和效率提升的需求日益迫切。特別是在商旅管理方面,如何有效整合資源、優化流程、降低費用,成為了成長型企業關注的焦點。用友YonSuite商旅費控作為用友集團旗下的重要產品,憑借其卓越…

ctfshow pwn17-18

毛坯的人生和精裝的朋友圈 pwn17 while ( 1 ){menu();v4 0;puts("\nEnter the command you want choose:(1.2.3.4 or 5)\n");__isoc99_scanf("%d", &v4);switch ( v4 ){case 1:system("id");break;case 2:puts("Which directory?(/,…