繁体   English   中英

组成继承

[英]Inheritance with composition

我正在设计一个系统,但我尚未实现,我只是对其进行图解,然后对其进行编码,我想问一个简单的问题:

当我们同时使用继承和组合时该怎么办?

例如,在旅馆中,有两种房间标准间和双床间。 为此,我可以使用继承概念,这两种房间将是派生类,但是我也可以使用组合,将标准间和双床间设为单独的类,然后将其用作我的酒店类。

我该怎么办?

这个问题有点含糊,缺少许多细节,但我会分享一些想法...

第一件事:在设计应用程序时,最重要的是需求

您首先需要尝试识别将在您的系统中具有某些含义的实体。 假设您知道会有HotelRoom 请注意,此关系已经是一个组合,主要是因为:

  • 房间只能是1家酒店的一部分,不能在多家酒店之间共享
  • 一旦酒店被摧毁,里面的所有房间也都被摧毁

在C ++中,组合通常表示“按值”,即class Hotel可以有Room room; 这将是一个具有自动存储持续时间的对象,其生命周期与Hotel实例的生命周期相关联,如果您拥有多个房间,则可以将它们放到矢量中,以产生相同的关系:

class Room { ... };

class Hotel {
public:
    std::vector<Room> rooms;
};

(顺便说一句,聚集很可能由指针或引用表示)。 这是组成的另一个很好的例子:

在此处输入图片说明

如果您知道会有各种房间,那么第一个问题应该是:这些物体的行为是否不同? 我的系统会以不同的方式对待他们吗? ...也许您不需要追求比Room更细的粒度,并且具体房间的所有内容都将通过其属性来表示-大小,床位数,也许数十个布尔型“ has”标志(“ has” aircon”,“有电视”,“有微波炉”,...),也许它的所有属性都可以用简单的“类型”表示,您可以将其值放入enum

如果您在站点上,我将在room类上拥有一个room_type属性,并且将room_type属性的类型设置为枚举类型,并可能使用STANDARD和TWIN值。

只要根据此类型字段没有明显的行为差异,我就将其保持简单。

如果存在复杂的行为,例如根据床位数预测清理,更改价格等,我将使用抽象基类CRoom,并从中继承CStdRoom和CTwinRoom,并可能在类构造函数中设置常量num_of_beds属性。

您不应该使用语言继承为业务需求继承建模。 这只是使其很难修改或扩展业务模型。 语言继承用于实现模型的功能,而不是模型本身。

而是从“业务对象”或类似对象派生所有对象,以封装常见的内部行为,例如序列化。 您的类可以具有类型,可以使用typeinfo,也可以使用显式类型字段。 无论对象是继承还是合成,对象之间的两种链接都应该是指针(或索引ID字段)和集合(指针或索引ID的集合)。 [您的代码段很好,但是指针使整数ID避免的内存管理复杂化。]

复杂的行为应属于其他类别,例如定价,清洁等。在设置业务对象和业务动作之间的关系时,还可以使用其他模式,但也要避免使用语言功能使它们具体化。 如果系统有所增长或改变,您将后悔。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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