工单编号
让我们再次思考一下我们的工单管理系统。目前,我们的工单模型是这样的:
#![allow(unused)] fn main() { pub struct Ticket { pub title: TicketTitle, pub description: TicketDescription, pub status: Status } }
这里缺少了一样东西:一个用来唯一标识工单的编号。这个编号对每个工单都应该是唯一的。我们可以在创建新工单时自动生成编号来保证这一点。
优化模型
编号应该存储在哪里呢?我们可以在 Ticket
结构体中添加一个新的字段:
#![allow(unused)] fn main() { pub struct Ticket { pub id: TicketId, pub title: TicketTitle, pub description: TicketDescription, pub status: Status } }
但我们在创建工单之前是不知道这个编号的。因此,一开始它不能存在。它必须是可选的:
#![allow(unused)] fn main() { pub struct Ticket { pub id: Option<TicketId>, pub title: TicketTitle, pub description: TicketDescription, pub status: Status } }
这也不是理想的情况——每次我们从存储中检索工单时,都不得不处理 None
的情况,尽管我们知道一旦工单被创建,编号就应该始终存在。
最佳的解决方案是设置工单的两种状态,由两个不同的类型表示:TicketDraft
(工单草稿)和 Ticket
(正式工单):
#![allow(unused)] fn main() { pub struct TicketDraft { pub title: TicketTitle, pub description: TicketDescription } pub struct Ticket { pub id: TicketId, pub title: TicketTitle, pub description: TicketDescription, pub status: Status } }
TicketDraft
是尚未创建的工单,它没有编号,也没有状态。而 Ticket
是已经创建的工单,它既有编号也有状态。由于 TicketDraft
和 Ticket
中的每个字段都嵌入了自己的约束,我们不需要在两个类型之间重复逻辑。