只提供值且無可見副作用的函式,非常寶貴, 這也是命令查詢分離原則(CQS, Command-Query Separation)的精神。

Separate Query from Modifier
sequenceDiagram
participant Client
participant Service
rect rgb(255, 230, 230)
Note over Client,Service: ❌ 混合查詢與修改
Client->>Service: sendAndConfirmEmail()
Service-->>Client: 回傳已發送清單 + 執行發送
end
rect rgb(230, 255, 230)
Note over Client,Service: ✅ 分離查詢與修改
Client->>Service: sendEmail() [Command]
Service-->>Client: void
Client->>Service: getEmailStatus() [Query]
Service-->>Client: 回傳狀態(無副作用)
end強調「可見」,是因像快取這類雖會改變物件狀態,仍讓查詢都回傳相同結果就是被允許的。
# Before
def send_and_confirm_email(emails, message):
sent_emails = []
for email in emails:
print(f"Sending email to {email}")
sent_emails.append(email)
return sent_emails
emails = ["john@example.com", "jane@example.com"]
sent_emails = send_and_confirm_email(emails, "Hello!")
# After
def send_email(emails, message):
for email in emails:
print(f"Sending email to {email}")
def confirm_sent_emails(emails):
return emails
emails = ["john@example.com", "jane@example.com"]
send_email(emails, "Hello!")
sent_emails = confirm_sent_emails(emails)