架構(gòu)權(quán)衡評估方法(ATAM):如何評估一個系統(tǒng)的質(zhì)量
JAVA前線?
歡迎大家關(guān)注公眾號「JAVA前線」查看更多精彩分享,主要內(nèi)容包括源碼分析、實際應(yīng)用、架構(gòu)思維、職場分享、產(chǎn)品思考等等,同時也非常歡迎大家加我微信「java_front」一起交流學(xué)習(xí)
1 質(zhì)量屬性
在系統(tǒng)設(shè)計和開發(fā)過程中,我們比較容易關(guān)注系統(tǒng)的功能維度,例如有沒有實現(xiàn)預(yù)期功能,輸入?yún)?shù)和輸出參數(shù)是否匹配等等,這是比較容易測試和衡量的。
但是我們不能就此止步,因為滿足功能是系統(tǒng)的基本要求,還需要關(guān)注系統(tǒng)的非功能維度,例如系統(tǒng)性能是否優(yōu)秀,代碼可擴展性如何,出現(xiàn)異常是否可以自動降級等等,這些指標(biāo)決定了系統(tǒng)能否提供高質(zhì)量的服務(wù)。
在之前文章《結(jié)構(gòu)化思維如何指導(dǎo)技術(shù)系統(tǒng)優(yōu)化》提到了三個質(zhì)量屬性:高性能、高可用、高擴展。本文我們充實為六個質(zhì)量屬性:性能、可用性、可修改性、可靠性、安全性、易用性:

1.1 性能
1.1.1 如何定義
性能有兩個定義維度,第一個維度是單位時間內(nèi)可以做多少事情,第二個維度是做完單位數(shù)量的事情需要多長時間,常用以下參數(shù)進(jìn)行量化:
QPS:每秒處理請求數(shù)
TPS:每秒處理事務(wù)數(shù)
并發(fā)數(shù):同一時刻處理請求數(shù)/事務(wù)數(shù)
響應(yīng)時間:系統(tǒng)對請求做出響應(yīng)的時間
并發(fā)數(shù) = QPS x RT
1.1.2 如何提升
提升性能可以從兩個維度思考,第一個維度是時間維度,從事前、事中、事后三個時間節(jié)點進(jìn)行優(yōu)化。事前是指在訪問最開始就拒絕無效流量。事中可以使用提高并發(fā)度(并發(fā)編程),增加資源(服務(wù)器、分布式緩存、讀寫分離,分庫分表),減少交互(批量請求)等方案。事后是指數(shù)據(jù)分析需求可以放到離線數(shù)據(jù)中心進(jìn)行,不要放在主應(yīng)用和主數(shù)據(jù)庫進(jìn)行。
第二個維度是層次維度,每一層都可以進(jìn)行優(yōu)化。系統(tǒng)架構(gòu)一般分為數(shù)據(jù)層、緩存層、服務(wù)層、網(wǎng)關(guān)層、客戶端、代理層,每一層都可以按照事前、事中、事后進(jìn)行優(yōu)化,而不是一提到優(yōu)化就是加緩存,應(yīng)該更加全面地思考。

1.2 可用性
1.2.1 如何定義
可用性是指系統(tǒng)正常運行時間占總運行時間比例,業(yè)界常用X個9指標(biāo)進(jìn)行量化,例如可用性達(dá)到5個9,那么全年系統(tǒng)不可用時間只有5分鐘:

1.2.2 如何提升
(1) 非線性
我們從另一個概念理解可用性:非線性,這個概念在生活中無處不在。
假設(shè)要趕早上8點鐘的火車,如果6:30出發(fā)可以在7:00到達(dá)車站,所以得到一個結(jié)論:只要30分鐘就可以到達(dá)車站。
如果早上睡晚一點7:15出發(fā),那么按照預(yù)期7:45可以到達(dá)車站。但是最可能的結(jié)果是錯過這趟火車。因為正好遇上早高峰導(dǎo)致至少需要1個小時才能到達(dá)車站。
我們再分析一個互聯(lián)網(wǎng)秒殺場景。假設(shè)秒殺系統(tǒng)當(dāng)每秒30個請求時,響應(yīng)時間是10毫秒。如果按照線性思維可以做出如下設(shè)計:
每秒30個訪問量響應(yīng)時間10毫秒
每秒300個訪問量響應(yīng)時間100毫秒
每秒3000個訪問量響應(yīng)時間1000毫秒
如果按照這個思路做系統(tǒng)設(shè)計可能會發(fā)生重大的錯誤。因為當(dāng)每秒3000個訪問量發(fā)生時,響應(yīng)時間可能不是1000毫秒,而是可能直接導(dǎo)致系統(tǒng)發(fā)生崩潰。
這就是非線性,事物不是簡單線性疊加關(guān)系,當(dāng)達(dá)到某個臨界值時會造成一種截然不同的結(jié)果。
(2) 提升策略
冗余 + 自動故障轉(zhuǎn)移
最基本冗余策略就是主從模式。原理是準(zhǔn)備兩臺機器,部署了同一份代碼,在功能層面是相同的,都可以對外提供相同的服務(wù)。
一臺機器啟動提供服務(wù),這就是主服務(wù)器。另一臺機器啟動在一旁待命,不提供服務(wù),隨時監(jiān)聽主服務(wù)器的狀態(tài),這就是從服務(wù)器。當(dāng)發(fā)現(xiàn)主服務(wù)器出現(xiàn)故障時,從服務(wù)器立刻替換主服務(wù)器,繼續(xù)為用戶提供服務(wù)。
自動故障轉(zhuǎn)移策略是指當(dāng)主系統(tǒng)發(fā)生異常時,應(yīng)該可以自動探測到異常,并自動切換為備用系統(tǒng)。不應(yīng)該只依靠人工去切換成,否則故障處理時間會顯著增加。
降級策略
當(dāng)系統(tǒng)遇到無法承受的壓力時,選擇暫時關(guān)閉一些非關(guān)鍵的功能,或者延時提供一些功能,把此刻所有的資源都提供給現(xiàn)在最關(guān)鍵的服務(wù)。
在秒殺場景中下訂單就是最核心最關(guān)鍵的功能。當(dāng)系統(tǒng)壓力將要到達(dá)臨界值時,可以暫時先關(guān)閉一些非核心功能如查詢功能。
還有一種降級策略,當(dāng)系統(tǒng)依賴的下游服務(wù)出現(xiàn)錯誤,甚至已經(jīng)完全不可用了,那么此時就不能再調(diào)用這個下游服務(wù)了,否則可能導(dǎo)致雪崩。所以直接返回兜底方案,把下游服務(wù)直接降級。
延時策略
用戶下訂單成功后就需要進(jìn)行支付。假設(shè)秒殺系統(tǒng)下訂單每秒訪問量是3000,有沒有必要將每秒3000次訪問量壓力傳遞給支付服務(wù)器?
答案是沒有必要。因為用戶秒殺成功后可以稍晚付款,例如可以跳轉(zhuǎn)到一個支付頁面,提示用戶只要在10分鐘內(nèi)支付完成即可。
這樣流量就被分?jǐn)傊翈追昼姡行ПWo(hù)了系統(tǒng)。技術(shù)架構(gòu)還可以使用消息隊列做緩沖,讓下游系統(tǒng)根據(jù)處理能力拉取消息。
隔離策略
物理隔離:應(yīng)用分別部署在不同物理機、不同機房,資源之間不會互相影響。
線程隔離:不同類型的請求進(jìn)行分類,交給不同的線程池處理,當(dāng)一類請求出現(xiàn)高耗時和異常,不影響另一類請求訪問。
1.3 可修改性
1.3.1 如何定義
可修改性是指是否能夠以較高的性價比對系統(tǒng)進(jìn)行變更的能力,可以分為以下四種類型:
可擴展性:系統(tǒng)擴展新構(gòu)件時對其它構(gòu)件的影響程度
可維護(hù)性:系統(tǒng)修改舊構(gòu)件時對其它構(gòu)件的影響程度
結(jié)構(gòu)重組:重新組織構(gòu)件關(guān)系的難易程度
可移植性:在不同硬件平臺、編程語言、操作系統(tǒng)間移植的難易程度
1.3.2 如何提升
可修改性最終在解決牽一發(fā)而動全身的復(fù)雜性問題,復(fù)雜業(yè)務(wù)之所以復(fù)雜,一個重要原因是涉及角色或者類型較多,如果平鋪直敘地進(jìn)行設(shè)計會出現(xiàn)if-else代碼塊,可讀性和可修改性都很低。
我們分析一個下單場景。當(dāng)前有ABC三種訂單類型:A訂單價格9折,物流最大重量不能超過9公斤,不支持退款。B訂單價格8折,物流最大重量不能超過8公斤,支持退款。C訂單價格7折,物流最大重量不能超過7公斤,支持退款。按照需求字面含義平鋪直敘地寫代碼也并不難:
public?class?OrderServiceImpl?implements?OrderService?{
????@Resource
????private?OrderMapper?orderMapper;
????@Override
????public?void?createOrder(OrderBO?orderBO)?{
????????if?(null?==?orderBO)?{
????????????throw?new?RuntimeException("參數(shù)異常");
????????}
????????if?(OrderTypeEnum.isNotValid(orderBO.getType()))?{
????????????throw?new?RuntimeException("參數(shù)異常");
????????}
????????//?A類型訂單
????????if?(OrderTypeEnum.A_TYPE.getCode().equals(orderBO.getType()))?{
????????????orderBO.setPrice(orderBO.getPrice()?*?0.9);
????????????if?(orderBO.getWeight()?>?9)?{
????????????????throw?new?RuntimeException("超過物流最大重量");
????????????}
????????????orderBO.setRefundSupport(Boolean.FALSE);
????????}
????????//?B類型訂單
????????else?if?(OrderTypeEnum.B_TYPE.getCode().equals(orderBO.getType()))?{
????????????orderBO.setPrice(orderBO.getPrice()?*?0.8);
????????????if?(orderBO.getWeight()?>?8)?{
????????????????throw?new?RuntimeException("超過物流最大重量");
????????????}
????????????orderBO.setRefundSupport(Boolean.TRUE);
????????}
????????//?C類型訂單
????????else?if?(OrderTypeEnum.C_TYPE.getCode().equals(orderBO.getType()))?{
????????????orderBO.setPrice(orderBO.getPrice()?*?0.7);
????????????if?(orderBO.getWeight()?>?7)?{
????????????????throw?new?RuntimeException("超過物流最大重量");
????????????}
????????????orderBO.setRefundSupport(Boolean.TRUE);
????????}
????????//?保存數(shù)據(jù)
????????OrderDO?orderDO?=?new?OrderDO();
????????BeanUtils.copyProperties(orderBO,?orderDO);
????????orderMapper.insert(orderDO);
????}
}
上述代碼從功能上完全可以實現(xiàn)業(yè)務(wù)需求,但是程序員不僅要滿足功能,還需要思考代碼的可維護(hù)性。如果新增一種訂單類型,或者新增一個訂單屬性處理邏輯,那么我們就要在上述邏輯中新增代碼,如果處理不慎就會影響原有邏輯。
為了避免牽一發(fā)而動全身這種情況,設(shè)計模式中的開閉原則要求我們面向新增開放,面向修改關(guān)閉,我認(rèn)為這是設(shè)計模式中最重要的一條原則。
需求變化通過擴展,而不是通過修改已有代碼實現(xiàn),這樣就保證代碼穩(wěn)定性。擴展也不是隨意擴展,因為事先定義了算法,擴展也是根據(jù)算法擴展,用抽象構(gòu)建框架,用實現(xiàn)擴展細(xì)節(jié)。標(biāo)準(zhǔn)意義的二十三種設(shè)計模式說到底最終都是在遵循開閉原則。
如何改變平鋪直敘的思考方式?這就要為問題分析加上縱向和橫向兩個維度,我選擇使用分析矩陣方法,其中縱向表示策略,橫向表示場景:

(1) 縱向做隔離
縱向維度表示策略,不同策略在邏輯上和業(yè)務(wù)上應(yīng)該是隔離的,本實例包括優(yōu)惠策略、物流策略和退款策略,策略作為抽象,不同訂單類型去擴展這個抽象,策略模式非常適合這種場景。本文詳細(xì)分析優(yōu)惠策略,物流策略和退款策略同理。
//?優(yōu)惠策略
public?interface?DiscountStrategy?{
????public?void?discount(OrderBO?orderBO);
}
//?A類型優(yōu)惠策略
@Component
public?class?TypeADiscountStrategy?implements?DiscountStrategy?{
????@Override
????public?void?discount(OrderBO?orderBO)?{
????????orderBO.setPrice(orderBO.getPrice()?*?0.9);
????}
}
//?B類型優(yōu)惠策略
@Component
public?class?TypeBDiscountStrategy?implements?DiscountStrategy?{
????@Override
????public?void?discount(OrderBO?orderBO)?{
????????orderBO.setPrice(orderBO.getPrice()?*?0.8);
????}
}
//?C類型優(yōu)惠策略
@Component
public?class?TypeCDiscountStrategy?implements?DiscountStrategy?{
????@Override
????public?void?discount(OrderBO?orderBO)?{
????????orderBO.setPrice(orderBO.getPrice()?*?0.7);
????}
}
//?優(yōu)惠策略工廠
@Component
public?class?DiscountStrategyFactory?implements?InitializingBean?{
????private?Map?strategyMap?=?new?HashMap<>();
????@Resource
????private?TypeADiscountStrategy?typeADiscountStrategy;
????@Resource
????private?TypeBDiscountStrategy?typeBDiscountStrategy;
????@Resource
????private?TypeCDiscountStrategy?typeCDiscountStrategy;
????public?DiscountStrategy?getStrategy(String?type)?{
????????return?strategyMap.get(type);
????}
????@Override
????public?void?afterPropertiesSet()?throws?Exception?{
????????strategyMap.put(OrderTypeEnum.A_TYPE.getCode(),?typeADiscountStrategy);
????????strategyMap.put(OrderTypeEnum.B_TYPE.getCode(),?typeBDiscountStrategy);
????????strategyMap.put(OrderTypeEnum.C_TYPE.getCode(),?typeCDiscountStrategy);
????}
}
//?優(yōu)惠策略執(zhí)行
@Component
public?class?DiscountStrategyExecutor?{
????private?DiscountStrategyFactory?discountStrategyFactory;
????public?void?discount(OrderBO?orderBO)?{
????????DiscountStrategy?discountStrategy?=?discountStrategyFactory.getStrategy(orderBO.getType());
????????if?(null?==?discountStrategy)?{
????????????throw?new?RuntimeException("無優(yōu)惠策略");
????????}
????????discountStrategy.discount(orderBO);
????}
}
(2) 橫向做編排
橫向維度表示場景,一種訂單類型在廣義上可以認(rèn)為是一種業(yè)務(wù)場景,在場景中將獨立的策略進(jìn)行串聯(lián),模板方法設(shè)計模式適用于這種場景。
模板方法模式一般使用抽象類定義算法骨架,同時定義一些抽象方法,這些抽象方法延遲到子類實現(xiàn),這樣子類不僅遵守了算法骨架約定,也實現(xiàn)了自己的算法。既保證了規(guī)約也兼顧靈活性,這就是用抽象構(gòu)建框架,用實現(xiàn)擴展細(xì)節(jié)。
//?創(chuàng)建訂單服務(wù)
public?interface?CreateOrderService?{
????public?void?createOrder(OrderBO?orderBO);
}
//?抽象創(chuàng)建訂單流程
public?abstract?class?AbstractCreateOrderFlow?{
????@Resource
????private?OrderMapper?orderMapper;
????public?void?createOrder(OrderBO?orderBO)?{
????????//?參數(shù)校驗
????????if?(null?==?orderBO)?{
????????????throw?new?RuntimeException("參數(shù)異常");
????????}
????????if?(OrderTypeEnum.isNotValid(orderBO.getType()))?{
????????????throw?new?RuntimeException("參數(shù)異常");
????????}
????????//?計算優(yōu)惠
????????discount(orderBO);
????????//?計算重量
????????weighing(orderBO);
????????//?退款支持
????????supportRefund(orderBO);
????????//?保存數(shù)據(jù)
????????OrderDO?orderDO?=?new?OrderDO();
????????BeanUtils.copyProperties(orderBO,?orderDO);
????????orderMapper.insert(orderDO);
????}
????public?abstract?void?discount(OrderBO?orderBO);
????public?abstract?void?weighing(OrderBO?orderBO);
????public?abstract?void?supportRefund(OrderBO?orderBO);
}
//?實現(xiàn)創(chuàng)建訂單流程
@Service
public?class?CreateOrderFlow?extends?AbstractCreateOrderFlow?{
????@Resource
????private?DiscountStrategyExecutor?discountStrategyExecutor;
????@Resource
????private?ExpressStrategyExecutor?expressStrategyExecutor;
????@Resource
????private?RefundStrategyExecutor?refundStrategyExecutor;
????@Override
????public?void?discount(OrderBO?orderBO)?{
????????discountStrategyExecutor.discount(orderBO);
????}
????@Override
????public?void?weighing(OrderBO?orderBO)?{
????????expressStrategyExecutor.weighing(orderBO);
????}
????@Override
????public?void?supportRefund(OrderBO?orderBO)?{
????????refundStrategyExecutor.supportRefund(orderBO);
????}
}
1.4 可靠性
1.4.1 如何定義
可靠性包括容錯性和健壯性,系統(tǒng)面對錯誤輸入仍能保證正確輸出的能力,可以分為兩種類型:系統(tǒng)可靠性和業(yè)務(wù)可靠性。
系統(tǒng)可靠性是指面對出現(xiàn)基本錯誤的輸入,系統(tǒng)能夠識別和攔截,而不是任由其在構(gòu)件中傳遞,造成錯誤數(shù)據(jù)或者引發(fā)系統(tǒng)異常。例如空值引發(fā)的空指針異常,不應(yīng)該出現(xiàn)在系統(tǒng)中。
業(yè)務(wù)可靠性是指輸入?yún)?shù)在基本校驗通過的情況下,系統(tǒng)能夠進(jìn)行業(yè)務(wù)校驗,不會引發(fā)超出業(yè)務(wù)預(yù)期的輸出結(jié)果。例如電商系統(tǒng)中的超賣現(xiàn)象,重復(fù)創(chuàng)建訂單現(xiàn)象都是業(yè)務(wù)可靠性較低的表現(xiàn)。
1.4.2 如何提升
(1) 攔截
提升可靠性的關(guān)鍵是應(yīng)該盡早在上層識別并攔截異常數(shù)據(jù),阻止其在構(gòu)件中流動,避免產(chǎn)生系統(tǒng)異常和錯誤數(shù)據(jù),尤其當(dāng)產(chǎn)生錯誤數(shù)據(jù)后,數(shù)據(jù)修復(fù)難度大。
提升系統(tǒng)可靠性可以在服務(wù)入口增加判空校驗、參數(shù)類型校驗、范圍校驗、合法枚舉值校驗等基本校驗,一旦發(fā)現(xiàn)異常直接拒絕。
提升業(yè)務(wù)可靠性可以增強業(yè)務(wù)校驗,例如庫存預(yù)扣減,活動有效期校驗,參與活動次數(shù)校驗,扣減庫存校驗,分布式鎖控制并發(fā)等方案,如果校驗規(guī)則復(fù)雜可以引入規(guī)則引擎進(jìn)行條件組合,不滿足業(yè)務(wù)條件直接拒絕請求。
(2) 告警
如果第一階段沒有將異常輸入攔截成功,那么就要在發(fā)生異常時及時感知,異常分為系統(tǒng)異常和業(yè)務(wù)異常。
系統(tǒng)異常是不允許出現(xiàn)的異常,例如空指針,操作數(shù)據(jù)庫失敗等異常,一旦出現(xiàn)就要立即告警。
業(yè)務(wù)異常可以分為以下類型:
業(yè)務(wù)告警:單位時間出現(xiàn)X次需要告警
延時告警:某指標(biāo)單位時間內(nèi)是否變化
數(shù)據(jù)告警:單位時間數(shù)據(jù)指標(biāo)是否正常
1.5 安全性與易用性
安全性是指系統(tǒng)防止非法用戶訪問的能力,易用性是指系統(tǒng)使用的難易程度,本文不展開論述,下一個章節(jié)會通過實例提到。
2 架構(gòu)評估方法
2.1 三種評估方法
因為涉及到眾多變量和場景,所以評估一個復(fù)雜技術(shù)系統(tǒng)的質(zhì)量并不是一件容易的事情。業(yè)界有以下三種評估方法:
第一是基于問卷的方式,通過問卷調(diào)查對系統(tǒng)比較熟悉的相關(guān)人員,這種方式主觀性很強。
第二是基于度量的方式,對系統(tǒng)指標(biāo)完全量化,基于量化指標(biāo)評價系統(tǒng),這種方式需要評估者對系統(tǒng)非常熟悉。
第三種是基于場景的方式,篩選出系統(tǒng)的關(guān)鍵場景,根據(jù)系統(tǒng)在不同場景中的表現(xiàn)進(jìn)行評估,這種方式具有一定的主觀性,需要評估者對系統(tǒng)比較熟悉,這也是目前較為流行的架構(gòu)評估方法。
架構(gòu)權(quán)衡評估方法(ATAM)的英文全稱是:Architecture Tradeoff Analysis Method,由卡梅隆大學(xué)軟件工程協(xié)會提出,是一種基于場景的架構(gòu)評估方法,核心是結(jié)合質(zhì)量屬性效用樹對系統(tǒng)進(jìn)行評價,確定風(fēng)險點、敏感點、權(quán)衡點,并對系統(tǒng)架構(gòu)做出決策和折中。
ATAM分為以下步驟,其中1、2、3為描述和介紹階段,4、5、6為調(diào)查和分析階段,7、8為測試階段,9為報告階段。

2.2 ATAM
本章節(jié)以之前文章《結(jié)合DDD講清楚編寫技術(shù)方案的七大維度》足球運動員信息管理系統(tǒng)為例看一看ATAM如何實際應(yīng)用。
第一階段是描述和介紹階段,首先由架構(gòu)師向大家介紹什么是ATAM方法,其次由產(chǎn)品經(jīng)理介紹開發(fā)足球運動員信息管理系統(tǒng)商業(yè)動機,最后由架構(gòu)師介紹系統(tǒng)整體架構(gòu),例如怎樣劃分領(lǐng)域,系統(tǒng)分為持久層、緩存層、中間件、業(yè)務(wù)中臺、服務(wù)層、網(wǎng)關(guān)層、客戶端和代理層等等。
第二階段是調(diào)查和分析階段,不同需求方均提出了相關(guān)需求,所涉及質(zhì)量場景如下:
(1) 系統(tǒng)在100毫秒內(nèi)響應(yīng)用戶請求
(2) 當(dāng)主數(shù)據(jù)庫發(fā)生故障后,10秒內(nèi)自動切換至從數(shù)據(jù)庫
(3) 當(dāng)主機房發(fā)生故障后,5分鐘內(nèi)請求重定向至災(zāi)備機房
(4) 新增球員比賽和訓(xùn)練指標(biāo),開發(fā)工作在5人日內(nèi)完成
(5) 使用包含SSL數(shù)字證書的HTTPS訪問協(xié)議
(6) 球員信息管理界面要求簡單易用
(7) 出現(xiàn)異常引導(dǎo)用戶至錯誤頁面,不能展示異常棧信息
(8) 對于球員信息配置功能的靈活度尚未達(dá)成共識,影響了系統(tǒng)可修改性
(9) 對于球員比賽指標(biāo)實時收集響應(yīng)時間的要求,影響了數(shù)據(jù)存儲設(shè)計
(10) 主教練提出了訓(xùn)練指標(biāo)新模式,影響了系統(tǒng)性能和可修改性
根據(jù)上述場景生成質(zhì)量屬性效用樹,(1)屬于性能,(2)(3)屬性可用性,(4)屬于可修改性,(5)屬于安全性,(6)屬于易用性,(7)屬于可靠性:

再根據(jù)這些場景分析系統(tǒng)的風(fēng)險點、敏感點、權(quán)衡點。風(fēng)險點是指某些操作會給系統(tǒng)帶來隱患和風(fēng)險,(8)屬于風(fēng)險點。敏感點是指為了實現(xiàn)某個特定質(zhì)量屬性,一個或多個系統(tǒng)組件所具有的特性,(9)屬于敏感點。權(quán)衡點是指某些操作會影響系統(tǒng)的多個質(zhì)量屬性,(10)屬于權(quán)衡點。
第三個階段是測試階段,根據(jù)足球運動員信息管理系統(tǒng)特性,我們首先確定場景優(yōu)先級,由高到低分別是:性能、可靠性、可用性、可修改性、安全性、易用性。
架構(gòu)權(quán)衡分析方法所謂權(quán)衡在此得到了體現(xiàn),質(zhì)量屬性每個都很重要,但是根據(jù)系統(tǒng)特點需要對質(zhì)量屬性有優(yōu)先級排序,架構(gòu)設(shè)計時需要所有權(quán)衡和折中。
確定了優(yōu)先級之后,我們需要具體闡述針對每個質(zhì)量屬性采取了哪些方案,例如提升性能使用了緩存,提升可修改性使用了策略模式,提升可靠性使用了統(tǒng)一異常處理框架等等,具體方案可以參考本文第一章節(jié)。
第四個階段是報告階段,我們將評估過程和結(jié)果都匯總整理成文檔,其中包括質(zhì)量屬性效用樹、風(fēng)險點、敏感點、權(quán)衡點、每次評估會議紀(jì)要以及最終架構(gòu)決策。
3 文章總結(jié)
第一系統(tǒng)滿足功能性需求是最基本的要求,作為架構(gòu)師不能就此止步,不僅應(yīng)該關(guān)注功能性需求,還應(yīng)該關(guān)注非功能性需求,質(zhì)量屬性就是衡量非功能性需求的重要指標(biāo)。
第二架構(gòu)評估方法分為基于問卷、基于度量、基于場景三種方式,目前業(yè)內(nèi)較為流行的是基于場景的評估方法,ATAM是一種優(yōu)秀的基于場景評估方法。
第三ATAM以質(zhì)量屬性效用樹為核心,幫助架構(gòu)師識別項目風(fēng)險點、敏感點、權(quán)衡點,指導(dǎo)架構(gòu)師做出合理架構(gòu)決策。
4 延伸閱讀
JAVA前線?
歡迎大家關(guān)注公眾號「JAVA前線」查看更多精彩分享,主要內(nèi)容包括源碼分析、實際應(yīng)用、架構(gòu)思維、職場分享、產(chǎn)品思考等等,同時也非常歡迎大家加我微信「java_front」一起交流學(xué)習(xí)
