这个 Composition 是否违反了面向对象编程的任何原则?

Is this Composition violating any principle of Object-Oriented Programming?

假设我有以下两个类:

public class MyDevice
{
    int id;
    string name;
    // other resources

    public MyChannel CreateChannel()
    {
        return new MyChannel(this);
    }
} 

public class MyChannel
{
    int id;
    MyDevice _device;
    // other resources        

    public MyChannel(MyDevice device)
    {
        _device = device;
    }
}

实际上每个设备都可以有可变数量的频道。所以关系是每个设备都有一个通道的集合。令我困扰的是代码的编写方式 MyChannel 对象有一个 MyDevice 对象。但是代码中定义的关系更方便,我也想保持简单。

为了平息脑后的唠叨——我一直指出 SqlConnectionSqlCommand 的结构方式,其中每个 SqlCommand 对象都有一个 SqlConnection 对象,尽管每个 SQL 连接都有一系列 SQL 命令。

我是否违反了面向对象编程的任何原则/这段代码有味道吗?

编辑:

明确地:在面向对象设计方面,将 has-a 关系放在头上是一个很大的禁忌吗?如果是这样,那么单一原则是什么ignored/neglected?

我推测示例中所说的 Device 应该是 MyDevice。您基本上可以参考父通道,即设备。我不认为这会破坏 OO,而且在很多情况下很有用。纯粹主义者会说它打破了父级的封装并创建了从通道到通道外和通道以外的任何东西的耦合。

这并没有违反任何原则。您将经常拥有包含其他对象的对象。

我假设您想让 MyChannel._device 字段实际上是一个 MyDevice?

此外,您可能需要考虑在 MyDevice 对象中包含一个 MyChannel 对象列表,以便在需要时更轻松地进行双向遍历。只需确保您在两个字段之间强制执行一致性。

我认为这种模式原则上没有任何问题。有时,存在两个真正紧耦合的 classes。

但是,我确实认为将您的频道 class 设为私有是一个非常好的主意,并且 使用 CreateChannel 方法对其进行实例化,同时添加带有 public getter 且没有 public setter 的频道对象的私有集合作为您设备的成员。这样,您就可以确保您的设备 class 始终控制自己的频道。