[英]Class diagram UML
Whether to use inheritance or not is IMHO a cost/benefit question. 是否使用继承是恕我直言的成本/收益问题。
When implementing inheritance there is usually some cost involved in terms of extra classes, tables, documentation and other results that need to be created after the decision to use inheritance. 在实现继承时,在决定使用继承之后,需要在额外的类,表,文档和其他结果方面涉及一些成本。
Inheritance is about special and general cases. 继承是关于特殊和一般情况的。 First you might want to ask what is the difference between the cases - (called a discriminator).
首先,您可能想问一下案例之间的区别 - (称为鉴别器)。 In your case it is the type of reservation and you could avoid the inheritance by modelling this type of reservation and implementing the different behavior based on the reservation type.
在您的情况下,它是预留类型,您可以通过建模此类预留并基于预留类型实现不同的行为来避免继承。 That would lead to a design like:
这将导致如下设计:
Avoiding inheritance 避免继承
If the inheritance has a high benefit because there are a lot of extra attributes, relation or operations for each special case then you can apply it. 如果继承具有很高的优势,因为每个特殊情况都有许多额外的属性,关系或操作,那么您可以应用它。
In this case there is 在这种情况下有
and there are some extra fields 并且还有一些额外的字段
What is missing at this time is common behavior that would make it sensible to apply inheritance. 目前缺少的是使应用继承变得合理的常见行为。 In the image below I added the generalization nevertheless.
在下图中,我添加了概括。 It would not be needed at this point in time but as soon as there are general operations you would like to apply to any type of reservation:
此时不需要它,但只要有一般操作,您就想申请任何类型的预订:
Applying inheritance 应用继承
I would definitely not model the collection as a subclass of the single. 我肯定不会将该集合建模为单个的子类。 If anything, the inheritance relationship runs the other direction: a
Reservation
is a special kind of Regular Reservation
where startDate == endDate
and frequency == 1
. 如果有的话,继承关系会运行另一个方向:
Reservation
是一种特殊的Regular Reservation
,其中startDate == endDate
和frequency == 1
。
But then why even model two classes? 但那么为什么甚至模拟两个类? Consider that all reservations are regular.
考虑所有预订都是定期的。 Conceptually, a
Reservation
is a collection containing only one item. 从概念上讲,
Reservation
是仅包含一个项目的集合。 A Regular Reservation
is a collection containing multiple items. Regular Reservation
是包含多个项目的集合。
Try utilizing a single Reservation abstract class in this case, and creating two sub classes from that, SingleReservation and RecurringReservation as shown in this diagram : 在这种情况下,尝试使用单个Reservation抽象类,并从中创建两个子类, SingleReservation和RecurringReservation ,如下图所示 :
This will help your business logic determine how to handle each reservation, and prevent the use of null-able columns in your database. 这将有助于您的业务逻辑确定如何处理每个预留,并防止在数据库中使用无空列。
Inheritance should not be used just as a trick for reusing some class members. 继承不应该仅仅用作重用某些类成员的技巧。 If
RegularReservation
would inherit from Reservation
, it would mean that a regular reservation IS SOME KIND OF simple reservation. 如果
RegularReservation
将从Reservation
继承,则意味着常规预订是一些简单的预留。 Is this the really case ? 这是真的吗? For example what about the single
Date
of Reservation
: has a date. 例如,单个
Reservation
Date
:有一个日期。 Does it have any meaning for a regular reservation ? 它对定期预订有什么意义吗?
So there are some flaws here: 所以这里有一些缺陷:
date
member) to all kind of reservations, even when it makes no sense. date
成员)的无用部分强加给所有类型的预留,即使它没有任何意义。 This is against the Interface Segregation Principle regular_reservation
member). regular_reservation
成员)。 So if tomorrow you'd wanted to create a MultipleReservation
(several unrelated dates), you'd need to modify the base class again. MultipleReservation
(几个不相关的日期),你需要再次修改基类。 This is against the Open Close Principle Reservation
would need to know the details about the different kind of reservations to handle their specific abilities. Reservation
课程需要知道有关不同类型预订的详细信息,以便处理他们的特定能力。 This is against the Principle of the least knowledge . The challenge for a room reservation system is not only to register reservations, but also to know for each given time slot if the room is free or if there's already a reservation. 房间预订系统的挑战不仅是登记预订,而且如果房间是免费的或已经预订的话,也知道每个给定的时间段。
Consequences: 后果:
An abstract Reservation
is always about a Client
booking a Room
with a price for one or several TimeSlots
. 抽象
Reservation
始终是关于Client
预订Room
的价格为一个或多个TimeSlots
。 TimeSlots
are only about dates, time, duration. TimeSlots
仅与日期,时间,持续时间有关。 This helps to ensure a separation of concerns: 这有助于确保关注点分离:
The number of slots and how these are created will depend on the kind of Reservation
. 插槽的数量以及这些插槽的创建方式取决于
Reservation
的类型。 But the general principle is that deleting a reservation would delete all its time slots (ok: what if there are slots in the past ?). 但一般原则是删除一个预留会删除所有时间段(好的:如果过去有插槽怎么办?)。
You may also have some general methods: 您可能还有一些通用方法:
getAllSlots()
would return the full collection of time slots getAllSlots()
将返回完整的时隙集合 getSlotsInInterval(startDate, endDate)
would return only those time slots in the interval getSlotsInInterval(startDate, endDate)
将仅返回间隔中的那些时隙
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.