简体   繁体   English

类图UML

[英]Class diagram UML

I'm creating a class diagram for a room reservation system. 我正在为房间预订系统创建一个类图。 There is an option of creating a regular reservation (for example every Tuesday in March). 可以选择创建常规预订(例如,3月的每个星期二)。 I´m wondering whether I should design a specific class like this: 我想知道是否应该设计一个这样的特定类:

在此输入图像描述

  • Should I design a specific class? 我应该设计一个特定的课程吗? Maybe 也许
  • Like this? 像这样? No 没有

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 在这种情况下有

  • an extra 1:n relation between regular reservation and reservation (which was not visible in your design but implied by the attribute regular Reservation) 常规预订和预订之间的额外1:n关系(在您的设计中不可见,但属性常规预约隐含)

and there are some extra fields 并且还有一些额外的字段

  • start date 开始日期
  • end date 结束日期
  • frequency 频率

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 == endDatefrequency == 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抽象类,并从中创建两个子类, SingleReservationRecurringReservation ,如下图所示

在此输入图像描述

This will help your business logic determine how to handle each reservation, and prevent the use of null-able columns in your database. 这将有助于您的业务逻辑确定如何处理每个预留,并防止在数据库中使用无空列。

Isn't this design seriously flawed ? 这种设计不是严重缺陷吗?

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: 所以这里有一些缺陷:

  • it imposes a useless part of the (private) interface ( date member) to all kind of reservations, even when it makes no sense. 它将(私有)接口( date成员)的无用部分强加给所有类型的预留,即使它没有任何意义。 This is against the Interface Segregation Principle 这违反了接口隔离原则
  • the base class must know about the inheriting classes ( 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 这违反了开放式原则
  • classes using 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 . 这违背了最不了解原则

What problem do you want to solve ? 你想解决什么问题?

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: 后果:

  • You must be able to get all the occurrences of a regular reservation in a given time interval. 您必须能够在给定的时间间隔内获得所有定期预订。
  • You should decide whether occurrences of a regular reservation are single reservations, or whether single and regular reservation should both have some kind of occurence objects. 您应该确定定期预订的发生是单一预订,还是单一和常规预订都应该具有某种发生对象。

Proposed design 拟议的设计

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM