So I have a class (I'll call it Chunk, the details of its use aren't important) with an identity crisis. It can't decide (and I can't decide) if it wants to be an object or value. At first I thought it would just be a value:
(Code is C# btw)
struct Chunk
{
public String Name;
public MetaDataItem[] MetaData;
public String[] Tags;
}
Chunk needs to be persisted so I have an interface IChunkBase. I could do this:
void Foo()
{
IChunkBase chunkBase = // Get concrete class from somewhere
Chunk newChunk;
// Do stuff to update newChunk
chunkBase.Save(newChunk);
}
That was all well and good except I realized that I had a few issues
1. The fact that I'm persisting chunk means it has an identity (in fact it has an actual ID), which was a red flag it shouldn't be a value.
2. If I want to do further updates to newChunk I want the persisted version to stay in sync as much as possible and I don't like passing chunkBase around everywhere.
So fine, I think. I'll make chunk an object.
class Chunk
{
private IChunkBase chunkBase;
public String ID;
public String Name;
public MetaDataItem[] MetaData;
public String[] Tags;
public Chunk(IChunkBase chunkBase) { this.chunkBase = chunkBase; }
public void Save()
{
chunkBase.Save(this);
}
}
This works well enough except I found situations where I wanted to move a chunk between locations. Moving it required creating a new copy of it with a new ID, but in my tests I wanted to compare equality as I would a value:
Chunk copiedChunk = chunkBase.Move(originalChunk, newLocation);
Assert.AreEqual(copiedChunk, originalChunk);
Except they *aren't* equal. They have differing ID's even if their other values are identical. I played with writing a "AreChunksSimilar" method but that kind of smells to me. I've finally settled on creating a nested struct for the values.
class Chunk
{
public struct Data
{
public String Name;
public MetaDataItem[] MetaData;
public String[] Tags;
}
private IChunkBase chunkBase;
public String ID;
public Data chunkData;
public void Save()
{
chunkBase.Save(this);
}
}
Am I approaching this in the right way? Is there something obvious that I'm missing? Thanks all.