Skip to main content

Ch24: 部分邊界

搭建全面性的架構邊界是昂貴的,包含 Input & Output 資料結構、元件部署、依賴管理,維護起來也要花費不少心力 ⇒ 搭建的邊界需要雙方都能夠受惠

即使達到上述的成果過於昂貴,但考量到日後需要,還是得替邊界保留一個位置,透過實作 部分邊界(Partial Boundary) 的方式達成 ⇒ 預想的設計

軟體設計原則 YAGNI (You aren't gonna need it!)

一維的邊界

要能維持完整的架構邊界,需要採用雙方都能互惠的「邊界介面」來維護雙向隔離 ⇒ 在兩個方向(初始設定、進行中的維護)上保持分離是昂貴的

範例:策略模式 (Strategy Pattern) strategyPattern Service Boundary 介面提供給 Client 使用,由 ServiceImpl 進行實作,透過依賴反轉原則(DIP)的方式達到 Client 與 ServiceImpl 的隔離 ⇒ 替未來的架構邊界奠定基礎

Facade (外觀)模式

為多個子系統提供一個統一的高層級接口,使得子系統更容易使用。

圖示 Facade 模式 facade(book)

生活案例

facade(sample)

Source: https://refactoring.guru/design-patterns/facade

邊界由「Facade」的類別來定義。

""" An example of Facade pattern"""

class Subsystem1:

def start(self):
print("Subsystem1 is operating...")

class Subsystem2:

def start(self):
print("Subsystem2 is operating...")

class Subsystem3:

def start(self):
print("Subsystem3 is operating...")

class CommissionerFacade:

'''Facade'''
def __init__(self) -> None:
self._subsystem1 = Subsystem1()
self._subsystem2 = Subsystem2()
self._subsystem3 = Subsystem3()

def operate(self):
self._subsystem1.start()
self._subsystem2.start()
self._subsystem3.start()

def client(facade: CommissionerFacade) -> None:

print("Calling from client")
facade.operate()
print("Done.")

if __name__ == "__main__":
commissionerFacade = CommissionerFacade()
client(commissionerFacade)

# Output
"""
Calling from client
Subsystem1 is operating...
Subsystem2 is operating...
Subsystem3 is operating...
Done.
"""

結論

每種方式都有屬於它自己的成本 & 效益,某些情況下,每個都適合先行佔用這個位置,能讓這個位置最終成為完整的邊界。

架構師的職責:在何處界定架構邊界以及完全 or 只部分實作邊界