I focus on making my software design flexible and reliable, and encapsulation is one of the key concepts for this. Recently, I have encountered a particular design problem, and I cannot argue (with myself) which is the best solution.
A specific example illustrating the problem: the device has an address (on the bus). The device has several registers. The register also has an address (inside the device - a virtual address / mapped address), therefore, for example, to write to the register on the device, you must write (registerAddress, value) to the device address. I cannot decide where to place the read / write functions of the registers:
1) the register must be able to read the record itself, that is, it must know about the communication channel between the device and itself. This seems to be strange / wrong, I canโt explain why, though ..
2) The device reads / writes to / from registers. The register is simply a placeholder for information (data, access rights, etc.) that the device can request / modify. This also seems wrong, because the responsibility for reading / writing the register must really be in the register (for example, the file knows how to read / write itself).
Which solution makes sense and why? Maybe there is a completely different solution that makes more sense?
Solution 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)
...
return chan.Read(address);
}
public Write()
{
chan.InitTransfer(address)
...
chan.Write(value);
}
}
Decision 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)
...
return chan.Read(address);
}
private void WriteRegister(int address, int value)
{
chan.InitTransfer(address)
...
chan.Write(value);
}
}