OOP 设计问题:包含对象或容器中的责任



我非常注重使我的软件设计灵活可靠,而实现这一目标的关键概念之一是封装。最近我遇到了一个特殊的设计问题,我无法(与自己)争论什么是最好的解决方案。

说明问题的具体示例:设备具有地址(在总线上)。设备具有多个寄存器。寄存器也有一个地址(在设备内部 - 又名虚拟地址/映射地址),因此例如,要写入设备上的寄存器,您必须写入(寄存器地址,值)到设备的地址。我无法决定将读/写寄存器的功能放在哪里:

1)寄存器应该能够读取写入本身,这意味着它需要知道设备与自身之间的通信通道。这似乎很奇怪/错误,但我无法解释为什么..

2) 设备向寄存器读取/写入寄存器。寄存器只是设备可以查询/更改的信息(数据、访问权限等)的占位符。这似乎也是错误的,因为读取/写入寄存器的责任实际上应该在寄存器中(就像文件知道如何读取/写入本身一样)。

什么解决方案最有意义,为什么?也许有一个完全不同的解决方案更有意义?

解决方案 1

class Device
{
    private CommChan chan;
    private Register register1;
    private Register register2;
    ...
    public Device(int deviceAddress)
    {
        chan = new CommChan(deviceAddress);
        register1 = new Register(0x01, chan);
        ...
    }
    public void DoSomething()
    {
        register1.Write(0x22);
        byte b = register1.Read();
    }
}
class Register
{
    private int address;
    ...
    public Read()
    {
        chan.InitTransfer(address)
        ... // Other setup
        return chan.Read(address);
    }
    public Write()
    {
        chan.InitTransfer(address)
        ... // Other setup
        chan.Write(value);
    }
}

解决方案 2

class Device
{
    private CommChan chan;
    public Device(int address)
    {
        chan = new CommChan(address);
    }
    public void DoSomething()
    {
        WriteRegister(0x01, 0x22);
        byte b = ReadRegister(0x01);
    }
    private byte ReadRegister(int address)
    {
        chan.InitTransfer(address)
        ... // Other setup
        return chan.Read(address);
    }
    private void WriteRegister(int address, int value)
    {
        chan.InitTransfer(address)
        ... // Other setup
        chan.Write(value);
    }
}

被驱动到逻辑极端,总线本身就是一个对象。 读取或写入寄存器是一种总线操作,不同的总线有不同的方式访问寄存器。 使用方法 ReadRegister 和 WriteRegister 创建总线接口。

过度这样做当然是一个考虑因素,我想你在另一种类型的总线上运行这段代码的可能性很小。

问题实际上是关于"注册应该是一个单独的实体吗?好吧,这取决于你。您需要回答问题:为什么注册必须成为类?

最新更新