純虛構 介紹篇| Pure Fabrication

2025-07-22
GRASP

純虛構與工具人的對比圖

同病相憐...圖片來源

情境

有一天,設計一套線上學習平台的你,發現 User 類別越長越胖。不只要記錄使用者名稱、帳號、訂閱狀態,還要能註冊、登入、上傳作業、發送 email 驗證信,甚至還負責把作業存進資料庫。

你看著那 400 行的 class,只覺得:這真的像一個使用者會做的事嗎?

同時你也開始擔心——哪天換了 SMTP server 或換了資料庫,整個 User 類別又要大修了。

在物件導向設計裡,常會遇到這些問題:

  • 邏輯難以重複使用
  • 依賴外部變化的元件(像是資料庫)侵入核心邏輯
  • 類別臃腫,做太多事

GRASP 原則提供了一個概念,純虛構。


多態

“ 這種類別是憑空虛構的。理想情況下,分配給這種虛構物的職責要支持高內聚與低耦合,使得這種虛構物清晰或純粹 - 因此稱為純虛構 ”

― Craig Larman, Applying UML and Patterns 3rd, ch25.2

純虛構(Pure Fabrication)是 GRASP(General Responsibility Assignment Software Patterns)裡的一個設計原則。它主張:

“ 當你找不到合適的領域物件可以負責某件事時,不妨虛構一個專門處理這件事的物件。 ”

這個物件本身不是領域概念(它不是老師、學生、訂單或報名表),但它有一個很明確的任務,常見如:

  • 存取資料庫的 Repository
  • 發送 email 的 Mailer
  • 負責加密的 Encryptor
  • 管理排程的 Scheduler

這些物件的目的不是反映真實世界,而是讓程式碼更有結構、更好維護。


舉個例子

純虛構其實已經被廣泛應用在開發的各個角落,像各種工具類,看看下面的舉例就知道了。

發信的例子

你希望使用者註冊帳號時能收到驗證信。你第一版寫的:

csharp
📝copy
                                
public class User
{
    public string Email { get; set; }

    public void SendVerificationEmail()
    {
        // 簡化了設定
        var smtp = new SmtpClient("smtp.mailtrap.io");
        smtp.Send("noreply@example.com", Email, "請點擊驗證信", "這是一封驗證信。");
    }
}                    
                                
                            

但如果信件要能支援寄出表格,那勢必要修改 User 類別,因此可以把第一版改成

csharp
📝copy
                                
public class EmailSender
{
    public void Send(string to, string content)
    {
        var smtp = new SmtpClient("smtp.mailtrap.io");
        smtp.Send("noreply@example.com", to, "驗證信", content);
    }
}                  
                                
                            

並在 User 進行調用,這樣 User 只要負責調用,不用管理寄信的具體設定

csharp
📝copy
                                
public class User
{
    private readonly EmailSender _emailSender;

    public User(EmailSender emailSender)
    {
        _emailSender = emailSender;
    }

    public void SendVerificationEmail(string to, string content)
    {
        _emailSender.Send(to, "請點擊驗證信");
    }
}
                 
                                
                            

作者心得

歷經了一年沒發,甚是懷念。


參考資料

也可以看看以下文章