隨著業務規模擴大,軟體架構的複雜度也隨之提升。如何調整架構以適應不斷變化的業務需求,同時保持系統的穩定性和可擴充套件性,是許多企業面臨的挑戰。本文以 YourFinFreedom 公司的 Travel Insurance 領域為例,展示瞭如何透過定義 KPI Value Tree,並據此調整軟體架構,以支援業務的快速增長。過程中,軟體架構師 Anna 協助產品工程團隊重新定義領域邊界,減少服務耦合,並引入新的服務以提升效率,最終達成業務目標。同時也需要考量軟體架構與領域邊界的一致性,避免產品工程團隊的認知負擔過重,才能有效提升團隊效率。

軟體架構在組織擴張中的核心角色

軟體架構在組織擴張過程中扮演著至關重要的角色。隨著業務需求的變化,軟體架構必須相應調整,以確保系統的穩定性和可擴充套件性。本文將透過案例分析,探討軟體架構如何支援組織擴張,並實作業務目標。

案例分析:YourFinFreedom 的 Travel Insurance 領域

YourFinFreedom 是一家金融服務公司,其 Travel Insurance 領域負責處理旅行保險相關業務。該領域的軟體架構最初存在一些問題,例如邊界不清晰、服務之間耦合度高。為瞭解決這些問題,Anna,一位軟體架構師,與產品工程團隊合作,進行了一系列實驗,以重新定義 Travel Insurance 領域的軟體架構。

實驗過程

  1. 定義 KPI Value Tree:Anna 與產品工程團隊共同定義了 KPI Value Tree,以衡量 Travel Insurance 領域的業務表現。KPI Value Tree 是一種用於衡量業務表現的指標體系,它將業務目標與軟體架構緊密結合。

  2. 進行實驗:Anna 與產品工程團隊進行了一系列實驗,以測試新的軟體架構。實驗的目的是驗證新的軟體架構是否能夠提高業務表現,並降低系統的複雜度。

  3. 評估結果:實驗結果表明,新的軟體架構成功地提高了業務表現,降低了系統的複雜度。Travel Insurance 領域的 KPI 得到了顯著改善,例如「減少找到保險報價請求匹配所需的時間」。

軟體架構的調整

隨著 YourFinFreedom 的業務增長,Travel Insurance 領域的 KPI 也需要相應調整。Anna 與產品工程團隊合作,更新了軟體架構,以減少手動工作量,提高業務效率。他們引入了一個新的服務,用於處理客戶資訊、查詢保險合作夥伴並生成報價選項。這個決策支援系統幫助保險分析師節省了瀏覽保險合作夥伴系統的時間。

KPI Value Tree 的維護

KPI Value Tree 需要定期維護,以確保其與業務目標保持一致。隨著業務環境的變化,軟體架構也需要相應調整。Anna 的經驗表明,KPI Value Tree 的維護是一個持續的過程,需要軟體架構師與產品工程團隊共同合作。

軟體架構的演進

軟體架構的演進是一個持續的過程,需要根據業務需求的變化進行調整。Anna 在與其他領域合作的過程中,發現了三個不同的模式:

  1. 軟體架構與領域邊界不符:軟體架構需要與領域邊界保持一致,以確保系統的穩定性和可擴充套件性。

  2. 領域邊界不正確:領域邊界不正確會導致軟體架構的複雜度增加,從而影響系統的效能。

  3. 產品工程團隊的認知負擔過重:產品工程團隊需要專注於特定的問題空間,以提高工作效率。

解決方案

Anna 提出了以下解決方案:

  1. 重新定義軟體架構:重新定義軟體架構,以確保其與領域邊界保持一致。

  2. 簡化領域邊界:簡化領域邊界,以降低軟體架構的複雜度。

  3. 最佳化產品工程團隊的工作流程:最佳化產品工程團隊的工作流程,以降低認知負擔,提高工作效率。

程式碼範例:KPI Value Tree 的實作

class KPIValueTree:
    def __init__(self, domain):
        self.domain = domain
        self.metrics = []

    def add_metric(self, metric):
        self.metrics.append(metric)

    def evaluate(self):
        # 評估 KPI Value Tree 的表現
        results = []
        for metric in self.metrics:
            results.append(metric.evaluate())
        return results

class Metric:
    def __init__(self, name, target):
        self.name = name
        self.target = target

    def evaluate(self):
        # 評估指標的表現
        # 這裡需要根據實際情況實作評估邏輯
        pass

# 使用範例
travel_insurance_domain = KPIValueTree("Travel Insurance")
metric1 = Metric("減少找到保險報價請求匹配所需的時間", 0.5)
travel_insurance_domain.add_metric(metric1)
results = travel_insurance_domain.evaluate()
print(results)

內容解密:

此程式碼範例展示瞭如何實作 KPI Value Tree。KPIValueTree 類別代表了一個 KPI Value Tree,它包含了一個領域(domain)和多個指標(metrics)。add_metric 方法用於新增新的指標到 KPI Value Tree 中。evaluate 方法用於評估 KPI Value Tree 的表現,它會呼叫每個指標的 evaluate 方法來取得評估結果。

Metric 類別代表了一個指標,它包含了指標的名稱(name)和目標值(target)。evaluate 方法用於評估指標的表現,這裡需要根據實際情況實作評估邏輯。

在實際應用中,可以根據業務需求定義不同的指標,並將其新增到 KPI Value Tree 中。透過評估 KPI Value Tree 的表現,可以瞭解業務的整體狀況,並根據需要進行調整。

KPI Value Tree 的結構

圖表翻譯:
此圖表展示了 KPI Value Tree 的結構。KPI Value Tree 包含了一個領域和多個指標。每個指標都有其對應的評估邏輯,用於評估指標的表現。透過這種結構,可以清晰地瞭解業務目標和評估指標之間的關係。

隨著業務的持續增長,軟體架構需要不斷演進,以支援新的業務需求。未來,可以考慮引入更多的自動化工具和技術,以提高軟體架構的靈活性和可擴充套件性。同時,需要繼續關注業務需求的變化,並根據需要調整軟體架構,以確保系統的穩定性和效能。

軟體架構與度量:超越技術的社會技術架構

軟體架構在現代企業中扮演著至關重要的角色。它不僅僅是技術實作的產物,更是企業戰略得以執行的關鍵。然而,軟體架構並非靜態不變,而是隨著企業的發展和變化而不斷演進。在這個過程中,如何選擇合適的度量指標(metrics)以及關鍵績效指標(KPIs),並使其與軟體架構和企業目標保持一致,成為了企業長官者和軟體架構師面臨的重要挑戰。

度量的重要性與選擇

在軟體架構的設計和實施過程中,度量指標的選擇至關重要。這些指標不僅能夠幫助企業評估軟體架構的表現,還能夠為未來的技術決策提供依據。然而,不同的企業面臨著不同的挑戰和環境,因此,並不存在一套放之四海而皆準的度量標準。企業需要根據自身的需求和特點,選擇最合適的度量指標。

度量指標的例子

例如,「平均發現時間」(mean time to discover)可以作為評估團隊學習和改進能力的指標。如果這個指標隨著時間的推移而增加,可能意味著軟體架構的複雜度在增加,或者團隊的認知負擔過重,從而對員工的參與度和工作效率產生負面影響。將這個指標與「變更失敗率」(change fail rate)結合起來,可以幫助企業發現軟體架構中的薄弱環節。同時,將「變更失敗率」與員工的「淨推薦值」(Net Promoter Score®)結合,可以進一步幫助管理階層瞭解技術決策對員工和團隊的影響。

import matplotlib.pyplot as plt

# 模擬資料:平均發現時間和變更失敗率
mean_time_to_discover = [1, 2, 3, 4, 5]
change_fail_rate = [0.1, 0.2, 0.15, 0.25, 0.3]

# 繪製趨勢圖
plt.plot(mean_time_to_discover, label='平均發現時間')
plt.plot(change_fail_rate, label='變更失敗率')
plt.xlabel('時間')
plt.ylabel('指標值')
plt.title('軟體架構度量指標趨勢')
plt.legend()
plt.show()

內容解密:

這段程式碼展示瞭如何使用Python的matplotlib函式庫來繪製軟體架構度量指標的趨勢圖。首先,我們定義了兩組模擬資料:mean_time_to_discover(平均發現時間)和change_fail_rate(變更失敗率)。然後,我們使用plt.plot()函式將這兩組資料繪製成趨勢圖,並增加了標籤、標題和圖例,以便更好地理解圖表的含義。

軟體架構的演進與社會技術架構

軟體架構不是一個靜態的概念,而是一個隨著企業發展而不斷演進的過程。當企業的業務需求和目標發生變化時,軟體架構也需要相應地調整。在這個過程中,軟體架構師需要具備不僅僅是技術能力,還需要能夠促進跨團隊協作、理解群體動態以及為業務戰略做出貢獻的能力。

未來的軟體架構師需要具備社會技術架構的思維,不僅僅關注技術元件之間的模式,還需要了解技術決策對企業社會結構的影響。這種全新的軟體架構思維能夠幫助企業創造出更加健全的架構,讓員工願意參與並貢獻其中。

管理期望與跨團隊協作

當軟體架構發生重大變化時,管理階層需要明確地與所有相關人員溝通這些變化的影響和預期結果。這包括技術上的變化,也包括對團隊和員工的影響。否則,員工可能會感到困惑、沮喪,甚至離職。

在軟體架構的演進過程中,跨團隊協作至關重要。透過使用視覺協作技術,企業可以讓不同部門和團隊保持一致,共同為企業的目標努力。例如,Anna在YourFinFreedom公司中使用視覺協作技術,讓產品工程團隊與其他部門保持一致,共同制定戰略計劃,並根據軟體架構的變化不斷調整和改進。

圖表翻譯: 這張圖展示了軟體架構演進過程中的關鍵步驟。首先,從開始階段(A)出發,透過視覺協作(B)促進跨團隊協作(C),進而制定出戰略計劃(D)。根據戰略計劃,對軟體架構進行調整(E),並在之後持續進行改進(F)。這個過程體現了軟體架構演進的動態性和持續性。

軟體架構中的測量角色

軟體架構有許多不同的定義,但在實踐中,大多數架構上重要的決策都與實作系統中的品質屬性相關,這些屬性需要滿足利害關係人的需求,包括效能、彈性及安全性。架構師通常將這些稱為品質屬性或非功能性品質。

這些重要且複雜的決策往往難以做出,因為牽涉到不同品質屬性之間的重大取捨。例如,優先考慮彈性可能會降低效能。利害關係人往往難以確定他們需要的品質屬性。

過去,架構師處理這些複雜問題的方式是進行大量的「前期」設計和思考,試圖找出需求、考慮不同的取捨、做出關鍵的架構決策並驗證它們。然而,如今我們需要更快地行動,更有效地適應變化,而這種方式無法滿足需求。

一些方法,如持續交付[^1]、風險驅動架構(RCDA)[^2]和持續架構[^3],嘗試使架構活動在整個交付生命週期中持續進行,而非僅在前期完成。這使得團隊能夠在擁有更多資訊時做出重要的決策,並支援系統建立過程中出現的變更。

測量的重要性

持續架構及相關方法的困難在於,如何知道是否已經做了足夠的架構工作,以及是否將時間花在最重要的事情上,以最大化工作的效益。總是有比時間允許的還要做的事情,因此需要明智地選擇任務,並知道何時停止並繼續下一個問題。

測量是解決方案所在。透過測量系統在特定時間點的品質屬性,而不是憑藉直覺或遵循僵化的架構「方法」,可以瞭解目前的狀況。並且,透過隨著時間的推移進行測量,可以觀察到趨勢,並根據這些品質屬性的演變推斷未來的走向。以這種方式使用測量可以指導架構活動並最大化其價值。

在接下來的章節中,將討論如何將測量整合到軟體架構中,並介紹測量和估計品質屬性的通用方法,以及針對關鍵品質屬性的一些特定方法。然後,將展示如何開始使用測量,並討論一些常見的陷阱。

將測量新增到軟體架構

軟體架構的歷史發展過程通常是:定義需要構建的內容、設計、構建,然後開始測量。這聽起來像是「瀑布式」交付,但即使是採用非常迭代式交付方法(使用敏捷或其他方法)的團隊,也經常將測量推遲到交付生命週期的晚期,遠在軟體進入營運環境之後。

如今,我們知道需要一個持續的定義-設計-構建-佈署過程,並且需要儘早開始測量並持續進行。測量和軟體架構之間的關係如圖7-1所示。

圖示翻譯: 此圖示展示了軟體架構中的持續測量迴圈,從定義到測量的反饋過程。

測量在架構週期中的角色

從交付流程和軟體佈署的任何環境中提取測量資料應該是一個持續且頻繁的過程。這些測量資料能夠為工作提供資訊、幫助優先排序,並最終影響架構決策。根據這些決策對系統進行更改,然後透過更多的測量來驗證這些決策是否有效。如此迴圈。

圖7-1提到了構件測量(artifact measurements)和營運測量(operational measurements)。構件測量是從交付過程生成的構件(如檔案和程式碼)中獲得的測量資料。營運測量則是系統在營運環境中運作時的測量資料,例如回應時間和磁碟使用率。瞭解何時可以進行這些測量以及它們能夠提供哪些洞察是非常有用的。圖7-2展示了一些測量範例,按照構件/營運和內部/外部測量兩個軸進行分類別。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 軟體架構與組織擴張策略案例

package "圖論網路分析" {
    package "節點層" {
        component [節點 A] as nodeA
        component [節點 B] as nodeB
        component [節點 C] as nodeC
        component [節點 D] as nodeD
    }

    package "中心性指標" {
        component [度中心性
Degree Centrality] as degree
        component [特徵向量中心性
Eigenvector Centrality] as eigen
        component [介數中心性
Betweenness Centrality] as between
        component [接近中心性
Closeness Centrality] as close
    }
}

nodeA -- nodeB
nodeA -- nodeC
nodeB -- nodeD
nodeC -- nodeD

nodeA --> degree : 計算連接數
nodeA --> eigen : 計算影響力
nodeB --> between : 計算橋接度
nodeC --> close : 計算距離

note right of degree
  直接連接數量
  衡量局部影響力
end note

note right of eigen
  考慮鄰居重要性
  衡量全局影響力
end note

@enduml

圖表翻譯: 此圖表展示了測量型別的分類別,包括構件測量和營運測量,以及它們的內外部差異。

外部構件測量

透過設計檔案檢查是否符合某個標準或是一種較弱的測量方式,因為它根據判斷。然而,它的優勢在於可以在交付週期的早期進行,即設計思路正在形成時。外部構件測量有助於建立利害關係人對系統將展現某種特性的信心,例如符合GDPR規範,或符合某些最佳實踐標準。

進一步的測量方法

內部構件測量,例如程式碼複雜度或單元測試覆寫率,可以提供有關系統內部健康狀況的資訊。內部營運測量,如記憶體使用率或執行緒數量,可以幫助瞭解系統的內部運作狀況。外部營運測量,如使用者回饋或系統效能,可以直接反映系統對使用者的影響。

def calculate_system_health(code_complexity, test_coverage, response_time):
    """
    計算系統健康度指標的範例函式。
    
    :param code_complexity: 程式碼複雜度
    :param test_coverage: 測試覆寫率
    :param response_time: 系統回應時間
    :return: 系統健康度評分
    """
    health_score = (test_coverage * 0.4) + ((1 - code_complexity) * 0.3) + ((1 - response_time/1000) * 0.3)
    return health_score

# 範例用法
complexity = 0.6  # 程式碼複雜度
coverage = 0.8    # 測試覆寫率
response = 200   # 回應時間(毫秒)

health = calculate_system_health(complexity, coverage, response)
print(f"系統健康度評分: {health}")

內容解密:

此範例程式碼展示了一個計算系統健康度的函式。它綜合考慮了程式碼複雜度、測試覆寫率和系統回應時間三個指標。函式首先根據這些輸入引數計算一個綜合的健康度評分,其中測試覆寫率佔40%,程式碼複雜度和回應時間各佔30%。最後傳回這個健康度評分。