OOP设计问题:容器或容器中的责任?

我专注于使软件设计灵活可靠,而实现这一目标的关键概念之一就是封装.
最近,我遇到了一个特殊的设计问题,我不能(和我自己)争论最好的解决方案是什么.

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

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创建总线接口.

这样做绝对是一个考虑因素,我想您曾经在另一种类型的总线上运行此代码的几率很小.

上一篇:javascript-扩展Aloha Editor的格式插件


下一篇:一组相关的PHP函数:最有效的组织方法是什么?