」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 什麼是尖叫建築?

什麼是尖叫建築?

發佈於2024-11-09
瀏覽:739

What is Screaming Architecture?

Screaming Architecture 是由著名软件开发人员和思想领袖 Robert C. Martin(通常被称为“Bob 叔叔”)提出的概念。这个术语可能听起来非常规,但它代表了软件设计中的一个强大原则,专注于使系统架构反映应用程序的主要关注点和用例。简而言之,您的软件架构应该“尖叫”其意图和目的。

在这份综合指南中,我们将探讨 Screaming Architecture 的基础知识、它与传统软件架构的对比、它在领域驱动设计中的重要性,以及如何在项目中实现此架构。我们还将介绍 Screaming Architecture 可以提高代码可读性、可维护性和长期可扩展性的实际示例和场景。

为什么要“尖叫”建筑?

尖叫架构背后的想法是代码库的主要结构应该立即传达其业务目的。这与传统架构形成鲜明对比,传统架构可能强调技术框架、工具或其他次要问题。在尖叫架构中,领域关注优先于实现细节。

鲍勃·马丁叔叔用一个类比来说明这一点:想象一下走到一座建筑物前,看看它的建筑。无需标志,您通常就能辨别出这是图书馆、学校还是办公室。这同样适用于软件架构。当您查看应用程序的文件夹结构和设计时,您应该立即了解它的用途。如果你正在构建一个会计系统,那么架构应该大喊“会计”,而不是“Django”、“Spring Boot”或“React”。

以框架为中心的架构的问题

在许多项目中,对技术框架的关注掩盖了业务或领域逻辑。您会发现如下文件结构:

controllers/

services/

repositories/

models/

虽然这些目录很有用,但它们描述了技术角色,而不是反映软件解决的核心问题。例如,此结构告诉您系统使用 MVC(模型-视图-控制器),但没有深入了解系统是否处理财务数据、用户管理或内容创建。

框架陷阱

过分强调框架会导致代码库中的业务逻辑被技术样板所掩盖。围绕框架约定构建的系统与这些框架紧密耦合。如果你想改变框架或技术栈,重构就成为一项主要工作。尖叫架构提倡保持领域逻辑干净且独立,因此框架的选择成为实现细节,而不是代码库的核心结构。

领域驱动设计 (DDD) 中的尖叫架构

领域驱动设计(DDD)和尖叫架构经常齐头并进。 DDD 是一种强调技术和领域专家之间协作的软件开发方法,它侧重于以与实际操作紧密结合的方式对核心业务逻辑进行建模。

在 Screaming Architecture 中,领域模型和业务逻辑位于应用程序的中心,而其他所有内容(框架、数据库、UI 和服务)都变得次要。关键思想是代码结构应该反映领域模型而不是技术实现细节。

以下是如何使用领域驱动原则以“尖叫”其意图的方式构建项目:

/src
    /accounting
        Ledger.cs
        Transaction.cs
        Account.cs
        TaxService.cs
    /sales
        Order.cs
        Invoice.cs
        Customer.cs
        DiscountPolicy.cs

在此示例中,文件夹名称直接反映了业务问题:会计和销售。每个特定于域的类,如 Ledger、Transaction 和 Order,都放置在其相关的域上下文中。这种结构使系统的用途以及每个组件适合的位置立即清晰可见。

代码示例 1:简单的以领域为中心的结构

考虑一个处理订单和库存的电子商务应用程序。使用 Screaming Architecture,文件夹结构应该反映业务逻辑而不是技术角色:

/src
    /orders
        Order.cs
        OrderService.cs
        OrderRepository.cs
    /inventory
        InventoryItem.cs
        InventoryService.cs
        InventoryRepository.cs

这是订单上下文中的基本代码示例:

public class Order
{
    public Guid Id { get; set; }
    public DateTime OrderDate { get; set; }
    public List Items { get; set; }
    public decimal TotalAmount { get; set; }

    public Order(List items)
    {
        Id = Guid.NewGuid();
        OrderDate = DateTime.Now;
        Items = items;
        TotalAmount = CalculateTotal(items);
    }

    private decimal CalculateTotal(List items)
    {
        return items.Sum(item => item.Price * item.Quantity);
    }
}

public class OrderItem
{
    public string ProductName { get; set; }
    public decimal Price { get; set; }
    public int Quantity { get; set; }
}

在此代码中,域概念(Order)位于前端和中心,OrderService 和 OrderRepository 等支持逻辑保存在单独的文件中。业务逻辑 (CalculateTotal) 是 Order 实体的一部分,而不是隐藏在服务或控制器中。

避免技术干扰

框架和库对于软件开发至关重要,但它们不应该决定您的业务逻辑的结构。 Screaming Architecture 提倡将 HTTP 控制器、持久层和数据库框架等技术细节推向外围。

这是一个对比传统架构和尖叫架构的例子:

传统建筑:

/src
    /controllers
        OrderController.cs
    /services
        OrderService.cs
    /repositories
        OrderRepository.cs
    /models
        Order.cs
        OrderItem.cs

虽然这在技术上是正确的,但它并没有告诉您该系统的用途。文件夹结构没有透露任何有关域的信息。这是一个电子商务系统吗?金融应用程序?如果不深入代码,就不可能知道。

尖叫建筑:

/src
    /orders
        OrderController.cs
        OrderService.cs
        OrderRepository.cs
        Order.cs
        OrderItem.cs
    /inventory
        InventoryController.cs
        InventoryService.cs
        InventoryRepository.cs
        InventoryItem.cs

此结构立即阐明了系统处理订单和库存。如果您将来添加更多域(例如客户、付款),它们将在架构中拥有专用位置。

清洁架构的作用

尖叫架构通常与鲍勃叔叔更广泛的清洁架构原则保持一致。清洁架构提倡关注点分离,重点关注确保业务规则独立于框架、UI 和数据库。尖叫架构更进一步,建议项目的结构应该揭示核心业务逻辑。

以下是清洁架构的快速回顾:

实体:核心业务对象和逻辑。

用例:特定于应用程序的业务规则。

接口:框架和外部系统的网关。

框架和驱动程序:UI、数据库和其他外部组件。

在清洁架构项目中,订单、客户和发票等领域概念是中心层的一部分。 ASP.NET Core、Django 或 Rails 等框架被归入外层,充当提供核心功能的机制。

代码示例 2:在 Screaming Architecture 中应用清洁架构

在尖叫架构中,您将以反映业务领域的方式构建用例和实体。让我们扩展我们的电子商务示例:

/src
    /orders
        CreateOrderUseCase.cs
        OrderRepository.cs
        Order.cs
        OrderItem.cs
    /inventory
        AddInventoryItemUseCase.cs
        InventoryRepository.cs
        InventoryItem.cs

这是创建订单的示例用例:

public class CreateOrderUseCase
{
    private readonly IOrderRepository _orderRepository;
    private readonly IInventoryService _inventoryService;

    public CreateOrderUseCase(IOrderRepository orderRepository, IInventoryService inventoryService)
    {
        _orderRepository = orderRepository;
        _inventoryService = inventoryService;
    }

    public Order Execute(List items)
    {
        // Ensure all items are available in inventory
        foreach (var item in items)
        {
            _inventoryService.CheckInventory(item.ProductName, item.Quantity);
        }

        var order = new Order(items);
        _orderRepository.Save(order);
        return order;
    }
}

在此示例中,CreateOrderUseCase 是域逻辑的一部分,并与 OrderRepository 和 InventoryService 交互,以满足创建订单的业务需求。

尖叫架构的好处

提高可读性:任何打开代码库的人都会立即了解系统的功能。

关注点分离:业务逻辑与技术细节保持隔离,使得以后更容易更改框架或技术。

可扩展性:随着系统的增长,域结构保持一致,允许轻松添加新功能和模块。

可维护性:当领域逻辑与外部依赖项和框架完全分离时,它更容易维护。

与框架无关:Screaming 架构允许业务逻辑在不同的技术堆栈之间保持可移植性,避免与任何特定框架的紧密耦合。

对尖叫建筑的批评

虽然尖叫建筑有很多好处,但它也并非没有批评:

感知复杂性:不熟悉领域驱动设计的开发人员可能会发现,对于小型应用程序来说,领域逻辑与技术细节的分离是不必要的或过于复杂。
2

。开销:在小型项目或简单的 CRUD 应用程序中,实现 Screaming Architecture 可能看起来有点矫枉过正。

学习曲线:对于习惯框架优先方法的团队来说,采用 Screaming 架构需要转变思维,这可能需要时间来内化。

何时使用尖叫架构

Screaming Architecture 在以下场景中特别有用:

领域驱动系统:具有复杂业务规则和领域逻辑的应用程序。

长期项目:系统预计会随着时间的推移而发展,其中可扩展性和可维护性至关重要。

跨平台开发:可以切换框架或平台的系统,使得业务逻辑的清晰分离至关重要。

结论

尖叫建筑不仅仅是一个朗朗上口的名字;这是一种主张使核心业务逻辑成为代码库中最突出的部分的哲学。通过关注领域概念而不是技术框架,开发人员可以构建从长远来看更具可读性、可维护性和可扩展性的系统。无论您是在开发简单的 Web 应用程序还是复杂的企业系统,采用 Screaming Architecture 都可以生成更清晰、更集中的代码,清楚地表达其目的。

要了解有关 Screaming Architecture 的更多信息,您可以查看一些参考资料和附加读物:

罗伯特·C·马丁的清洁架构

Eric Evans 的领域驱动设计

鲍勃叔叔关于整洁代码的博客

通过采用尖叫架构的原则,您可以创建不仅可以工作而且可以“尖叫”其意图的代码库。

版本聲明 本文轉載於:https://dev.to/nilebits/what-is-screaming-architecture-442o?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 大批
    大批
    方法是可以在物件上呼叫的 fns 數組是對象,因此它們在 JS 中也有方法。 slice(begin):將陣列的一部分提取到新數組中,而不改變原始數組。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index ...
    程式設計 發佈於2024-11-17
  • 在 Go 中使用 WebSocket 進行即時通信
    在 Go 中使用 WebSocket 進行即時通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    程式設計 發佈於2024-11-17
  • Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta:列偏移的刪除和恢復Bootstrap 4 在其Beta 1 版本中引入了重大更改柱子偏移了。然而,隨著 Beta 2 的後續發布,這些變化已經逆轉。 從 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    程式設計 發佈於2024-11-17
  • Numpy 備忘單
    Numpy 備忘單
    Comprehensive Guide to NumPy: The Ultimate Cheat Sheet NumPy (Numerical Python) is a fundamental library for scientific computing in Python. ...
    程式設計 發佈於2024-11-17
  • 你需要像專業人士一樣閱讀科技文章
    你需要像專業人士一樣閱讀科技文章
    在快节奏的技术世界中,并非您阅读的所有内容都是准确或公正的。并非您读到的所有内容都是由人类编写的! 细节可能存在微妙的错误,或者文章可能故意误导。让我们来看看一些可以帮助您阅读科技文章或任何媒体内容的技能。 1. 培养健康的怀疑态度 培养健康的怀疑态度至关重要。质疑大胆的主张,寻找...
    程式設計 發佈於2024-11-17
  • 如何找到一個多維數組中存在但另一個多維數組中不存在的行?
    如何找到一個多維數組中存在但另一個多維數組中不存在的行?
    比較多維數組的關聯行您有兩個多維數組,$pageids 和$parentpage,其中每行代表一個包含列的記錄“id”、“連結標籤”和“url”。您想要尋找 $pageids 中存在但不在 $parentpage 中的行,從而有效地建立一個包含缺少行的陣列 ($pageWithNoChildren)...
    程式設計 發佈於2024-11-17
  • 為什麼 Windows 中會出現「Java 無法辨識」錯誤以及如何修復它?
    為什麼 Windows 中會出現「Java 無法辨識」錯誤以及如何修復它?
    解決Windows 中的「Java 無法識別」錯誤嘗試在Windows 7 上檢查Java 版本時,使用者可能會遇到錯誤「'Java' 無法識別”作為內部或外部命令。 」此問題通常是由於缺少Java 安裝或環境變數不正確而引起的。要解決此問題,您需要驗證Java 安裝並配置必要的環境...
    程式設計 發佈於2024-11-17
  • 儘管檔案存在且有權限,為什麼 File.delete() 會回傳 False?
    儘管檔案存在且有權限,為什麼 File.delete() 會回傳 False?
    儘管存在並進行權限檢查,File.delete() 返回False使用FileOutputStream 寫入檔案後嘗試刪除檔案時,某些使用者遇到意外問題: file.delete() 傳回false。儘管檔案存在且所有權限檢查(.exists()、.canRead()、.canWrite()、.ca...
    程式設計 發佈於2024-11-17
  • 如何有效地從 Go 中的切片中刪除重複的對等點?
    如何有效地從 Go 中的切片中刪除重複的對等點?
    從切片中刪除重複項給定一個文字文件,其中包含表示為具有“Address”和“PeerID”的對象的對等點清單屬性,任務是根據程式碼配置中「Bootstrap」切片中匹配的「Address」和「PeerID」刪除所有重複的對等點。 為了實現此目的,我們迭代切片中的每個對等點物件多次。在每次迭代期間,我...
    程式設計 發佈於2024-11-17
  • 如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
    如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
    在 PHP 中組合關聯數組在 PHP 中,將兩個關聯數組組合成一個數組是常見任務。考慮以下請求:問題描述:提供的代碼定義了兩個關聯數組,$array1和$array2。目標是建立一個新陣列 $array3,它合併兩個陣列中的所有鍵值對。 此外,提供的陣列具有唯一的 ID,而名稱可能重疊。要求是建構一...
    程式設計 發佈於2024-11-17
  • 如何自訂Bootstrap 4的檔案輸入元件?
    如何自訂Bootstrap 4的檔案輸入元件?
    繞過 Bootstrap 4 檔案輸入的限制Bootstrap 4 提供了自訂檔案輸入元件來簡化使用者的檔案選擇。但是,如果您希望自訂「選擇檔案...」佔位符文字或顯示所選檔案的名稱,您可能會遇到一些挑戰。 更改 Bootstrap 4.1 及更高版本中的佔位符自 Bootstrap 4.1 起,佔...
    程式設計 發佈於2024-11-17
  • 如何在 CSS 盒子上創建斜角?
    如何在 CSS 盒子上創建斜角?
    在 CSS 框上建立斜角可以使用多種方法在 CSS 框上實現斜角。一種方法描述如下:使用邊框的方法此技術依賴於沿容器左側建立透明邊框和沿底部建立傾斜邊框。以下程式碼示範如何實現:<div class="cornered"></div> <div cl...
    程式設計 發佈於2024-11-17
  • 如何在 Pandas DataFrame 中的字串中新增前導零?
    如何在 Pandas DataFrame 中的字串中新增前導零?
    在 Pandas Dataframe 中的字串中加入前導零在 Pandas 中,處理字串有時需要修改其格式。一項常見任務是向資料幀中的字串新增前導零。這在處理需要轉換為字串格式的數值資料(例如 ID 或日期)時特別有用。 要實現此目的,您可以利用 Pandas Series 的 str 屬性。此屬性...
    程式設計 發佈於2024-11-17
  • 您是否應該異步加載腳本以提高網站效能?
    您是否應該異步加載腳本以提高網站效能?
    非同步腳本載入以提高網站效能在現今的Web 開發領域,優化頁面載入速度對於使用者體驗和搜尋引擎優化至關重要。提高效能的有效技術之一是非同步載入腳本,使瀏覽器能夠與其他頁面元素並行下載腳本。 傳統方法是將腳本標籤直接放置在 HTML 文件中,但這種方法常常會造成瓶頸因為瀏覽器必須等待每個腳本完成載入才...
    程式設計 發佈於2024-11-17
  • 如何將 Python 日期時間物件轉換為自紀元以來的毫秒數?
    如何將 Python 日期時間物件轉換為自紀元以來的毫秒數?
    在Python 中將日期時間物件轉換為自紀元以來的毫秒數Python 的datetime 物件提供了一種穩健的方式來表示日期和時間。但是,某些情況可能需要將 datetime 物件轉換為自 UNIX 紀元以來的毫秒數,表示自 1970 年 1 月 1 日協調世界時 (UTC) 午夜以來經過的毫秒數。...
    程式設計 發佈於2024-11-17

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3