我正在设计一个系统,我还没有先实现,我只是在编写它然后编写它,我想问一个简单的问题:
当我们同时使用继承和组合时该怎么办?
例如,在酒店,有2种房间标准间和双床间让我们说。为此我可以使用继承概念,这两种房间将派生类,但我也可以使用组合,将标准和双人房间分开,然后将使用这是我的酒店类。
我该怎么办?
答案 0 :(得分:3)
这个问题有点模糊,有很多细节缺失,但我会分享一些想法......
首先:在设计应用程序时,最重要的是要求。
您需要先尝试识别系统中具有某些含义的实体。假设您知道会有 Hotel 和 Room 。注意,这种关系已经是一个组合,主要是因为:
在C ++中,组合通常意味着“按值”,即class Hotel
可能具有Room room;
,它将是具有自动存储持续时间的对象,其生命周期与{{1}的实例的生命周期相关联},有多个房间,你可以把它们放到矢量,产生相同的关系:
Hotel
(顺便说一句,聚合很可能由指针或引用表示)。这是另一个很好的组成例子:
如果您知道会有不同类型的房间,首先应该问题是:这些对象会有不同的行为吗?我的系统会以不同的方式对待它们吗? ...也许你不需要比 Room 更精细的粒度,具体房间将具体的一切都将用它的属性表示 - 大小,床的数量,可能是几十个布尔值“has”标志(“有空调”,“有电视”,“有微波”,......),也许它的所有属性都可以用简单的“类型”来表达,你将把它放入{{1 }}
答案 1 :(得分:1)
我是你的网站,我会在房间类上有一个room_type属性,我会将room_type属性的类型设置为枚举类型,可能的值为STANDARD和TWIN。
只要根据此类型字段没有显着的行为差异,我会保持简单。
如果有复杂的行为,比如根据床位预测清理,改变定价等等,我会使用抽象基类CRoom,并从中继承CStdRoom和CTwinRoom,可能会设置一个常量的num_of_beds属性类构造函数。
答案 2 :(得分:1)
您不应该使用语言继承来建模业务需求继承。它只是让修改或扩展业务模型变得太难了。语言继承用于实现模型的功能,而不是模型本身。
相反,从“业务对象”或类似对象派生所有对象,以封装常见的内部行为,例如序列化。您的类可以有类型,您可以使用typeinfo,也可以使用显式类型字段。无论哪种方式,对象之间的链接,无论是类似继承还是类似组合,都应该是指针(或索引id字段)和集合(指针或索引id)。 [你的代码片段很好,但是指针会使整数id避免的内存管理变得复杂。]
复杂的行为应该属于其他类,例如定价,清理等。在设置业务对象和业务操作之间的关系时还可以使用其他模式,但同样要避免使用语言功能来明确它们。如果系统增长或改变一点,你会后悔的。