What your describing could have some flyweights representing each of those nested classes. But in this case that would be more of an implementation detail. In my experience, flyweights are usually called for at the architectural level or implementation level but rarely as an element of design.
Consider this class -
public interface IMyData {
IdType MyId { get; }
byte[] BlobData { get; }
long SizeOfBlob { get; }
}
public class MyData : IMyData {
public IdType MyId { get; private set; }
public byte[] BlobData { get; set; }
public long SizeOfBlob { get { return BlobData.LongLength; } }
}
}
In your multi-tiered application, this object needs to travel from the source database, to a manager's IPhone for approval based on the blob size, and then to an accounting system for billing. So instead of transporting the whole thing to the IPhone App, you substitute the flyweight:
public class MyDataFlyWeight : IMyData {
public MyDataFlyWeight(IdType myId, long blobSize){
MyId = myId;
BlobSize = blobSize;
}
public IdType MyId { get; set; }
public byte[] MutableBlobData { get {
throw new NotImplmentedException();
}
}
public long BlobSize { get; private set; }
}
}
By having both implement IMyData
and by building the system with the interface and not the concrete type (you did this, right?!), then you could use MyDataFlyweight
objects from the IPhone App and MyData
objects in the rest of the system. All you have to do is properly initialize MyDataFlyweight
with the blob size.
The architecture which calls for an IPhone App would dictate that a flyweight is used within the IPhone App.
In addition, consider the newer Lazy<T>
class:
public class MyData : IMyData {
public IdType MyId { get; private set; }
private Lazy<byte[]> _blob = new Lazy<byte[]>(() =>
StaticBlobService.GetBlob(MyId));
public byte[] BlobData { get { return _blob.Value; } }
public long SizeOfBlob { get { return BlobData.LongLength; } }
}
}
This is an example of using the flyweight purely as an implementation detail.