Class 图 UML

Class diagram UML

我正在为房间预订系统创建一个 class 图。可以选择创建定期预订(例如 3 月的每个星期二)。我想知道我是否应该像这样设计一个特定的 class:

尝试在这种情况下使用单个 Reservation 抽象 class,并从中创建两个子 classes,SingleReservationRecurringReservation as shown in this diagram:

这将帮助您的业务逻辑确定如何处理每个预订,并防止在您的数据库中使用可为空的列。

我绝对不会将集合建模为单例的子类。如果有的话,继承关系是相反的:Reservation 是一种特殊的 Regular Reservation,其中 startDate == endDatefrequency == 1.

但为什么还要模型两个 类?考虑到所有的预订都是有规律的。从概念上讲,Reservation 是一个仅包含一项的集合。 Regular Reservation 是一个包含多个项目的集合。

  • 我应该设计一个特定的class吗? 可能
  • 像这样? 没有

恕我直言,是否使用继承是一个 cost/benefit 问题。

实施继承时,通常需要在决定使用继承后创建额外的 classes、表格、文档和其他结果方面的成本。

继承是关于特殊和一般情况的。首先,您可能想问一下案例之间的区别是什么——(称为鉴别器)。在您的情况下,它是预订类型,您可以通过对此类预订建模并根据预订类型实现不同的行为来避免继承。这将导致这样的设计:

避免继承

如果继承有很高的收益,因为每个特殊情况都有很多额外的属性、关系或操作,那么您可以应用它。

在这种情况下有

  • 常规预订和预订之间的额外 1:n 关系(这在您的设计中不可见,但由属性常规预订暗示)

还有一些额外的字段

  • 开始日期
  • 结束日期
  • 频率

目前缺少的是使应用继承变得明智的常见行为。尽管如此,在下图中我还是添加了概括。目前不需要它,但只要有一般操作,您就想将其应用于任何类型的预订:

应用继承

这个设计是不是有严重的缺陷?

继承不应仅用作重用某些 class 成员的技巧。如果 RegularReservation 继承自 Reservation,则意味着常规预留是某种简单的预留。真的是这样吗?例如 Reservation 的单个 Date :有日期。定期预订有什么意义吗?

所以这里有一些瑕疵:

  • 它将(私有)接口(date 成员)的无用部分强加给所有类型的预订,即使它毫无意义。这是违反 Interface Segregation Principle
  • 基础 class 必须知道继承 classes(regular_reservation 成员)。因此,如果明天您想创建一个 MultipleReservation(几个不相关的日期),则需要再次修改基础 class。这是违背 Open Close Principle
  • 使用 Reservation
  • classes 需要了解有关不同类型预留的详细信息以处理其特定能力。这是反对Principle of the least knowledge的。

您想解决什么问题?

客房预订系统的挑战不仅在于登记预订,还在于了解每个给定时间段内房间是否空闲或是否已有预订。

后果:

  • 您必须能够获取给定时间间隔内所有出现的定期预订。
  • 您应该决定常规预留的出现是否是单个预留,或者单个预留和常规预留是否都应具有某种出现对象。

提议的设计

摘要 Reservation 总是关于 Client 预订 Room,价格为一个或几个 TimeSlotsTimeSlots 仅与日期、时间、持续时间有关。这有助于确保关注点分离:

插槽的数量以及它们的创建方式将取决于 Reservation 的类型。但一般原则是删除预订会删除其所有时间段(好吧:如果过去有时间段怎么办?)。

你可能还有一些通用的方法:

  • getAllSlots() 将 return 时隙的完整集合
  • getSlotsInInterval(startDate, endDate) 只会 return 间隔
  • 中的那些时隙