資料跟資訊的差異 - Rails 開發實踐
你有想過資料(Data)和資訊(Information)的差異嗎?在軟體開發的過程中,我們做的通常被叫做「資訊系統」然而大多數情況,我們很可能只是單純的把資料放到一個程序裡面,然後對這些資料做了一些調整,中間並沒有「資訊」的概念在裡面。
脈絡
在英文字典中,資訊的定義是「有脈絡(Context)的資料」而在中文字典,資訊是指「經過處理的資料」也就是說,我們平常在使用的「資料庫」是保存未經處理的部分,那麼脈絡是什麼呢?
舉例來說,假設我們在一個超商買東西的場景,當我拿出鈔票付錢的時候,我們就自然的理解了一些脈絡,在這個時候我們直接用「50」也能馬上被理解為「50 元」這就是所謂的脈絡,在這個過程中「50」是我們的資料,而 「50 元」就是所謂的資訊。
在轉換需求為規格的過程中,我們遭遇到最大的問題其實是日常溝通中需要透過多次的「對話」來補全脈絡,規格和 Key Examples(關件案例)這類資訊,就是從需求中提取出可以代表這個脈絡的關鍵資訊來使用。
模型與實體
在 Rails 中我們會很自然的把資料跟 Model(模型)聯想在一起,這是因為 ORM(Object Relational Mapping,物件關係映射)機制的特性,大多數的 MVC 框架都會提供這樣的機制,因而讓我們忘記了在程式中使用的 Model 應該是一個脈絡下的 Entity(實體)
大多數人接觸到 Entity 的概念應該是因為 Domain-Driven Design(領域驅動開發)的關係,在這個章節我們不會深入討論過多,先以一個 Model 作為例子。
1class Subscription < ApplicationRecord
2 has_many :items, class_name: 'SubscriptionItem'
3
4 attribute :expired_at, :datetime
5
6 def calculate_expired_at
7 self.expired_at = created_at + items.sum(&:extend_amount)
8 end
9end
在上面這個例子中,過期時間是透過 ActiveModel 的 DSL 所定義的,而不是透過 ActiveRecord 自訂映射而來,然而我們仍然可以正常使用這個屬性。
這會影響使用嗎?其實這是一種設計的選擇,我們可以在資料庫建立一個 expired_at
的欄位來儲存這個資訊,也可以改為儲存每一筆紀錄,最後用聚合(Aggregate)的函示 SUM
將所有延展的時間加總,最後跟開始訂閱的時間相加去計算出最後過期的時間點。
也就是說,我們的模型不總是跟資料庫完全對應的,他會取決於我們怎麼使用。
從狀態出發
Entity 在一個系統中扮演的角色是「維護狀態」以前面訂閱的例子來看,每一筆訂閱紀錄都會知道自己在什麼時候開始,但不會特別去儲存「過期時間」當我們需要知道何時過期時,可以透過每一次續訂的紀錄來計算,這是因為受到「規格」的影響。
假設每一次的續訂都是延展 30 天,如果用日期來紀錄,其實會變得有點麻煩,因為我們會需要每次都計算延展 30 天是到哪一天。
然而改為延展天數,那麼就可以直接儲存 30
,未來改變延展的時間,只需要調整 30
這個常數即可。
反過來看,如果訂閱機制是以「月底」為基礎來判定,在這個狀況下,用 30
或 31
來儲存就會變得複雜,正因如此,假設我們還無法確定怎樣儲存資料能更符合需求,不如先避免儲存到資料庫的設計,用不同的方式規劃 Model 來驗證,等到我們找到適合的狀態管理方式後,再進行資料表的設計與建立。
如果對這篇文章有興趣,可以透過以下連結繼續閱讀這系列的其他文章。
- 前言 - Rails 開發實踐
- 將需求實現的準備 - Rails 開發實踐
- 獲取規格的技巧 - Rails 開發實踐
- 可以測試的規格 - Rails 開發實踐
- 快速通過測試的方法 - Rails 開發實踐
- 用測試完善規格 - Rails 開發實踐
- 資料跟資訊的差異 - Rails 開發實踐
- 用測試資料驗證邏輯 - Rails 開發實踐
- 預期外狀況的檢查 - Rails 開發實踐
- 預期外狀況的測試 - Rails 開發實踐
- 聚合多筆資料 - Rails 開發實踐
- 重構與修正邏輯 - Rails 開發實踐
- 加入聚合實體 - Rails 開發實踐
- 持久化資料 - Rails 開發實踐
- 實體與倉庫 - Rails 開發實踐
- 聚合與邊界 - Rails 開發實踐
- 使用案例與服務 - Rails 開發實踐
- 結語 - Rails 開發實踐