I am trying to decide the best way to structure some code. I will admit this may be overboard and is turning into something more academic than practical. Sometimes you just cannot help yourself.
Let me contrive a simple example:
Suppose you have classes/interfaces such as:
interface IProcessedPhoto { }
interface IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes);
void Alter(IProcessedPhoto processedPhoto);
}
class PhotoProcessedWithAMethod : IProcessedPhoto { }
class PhotoProcessedWithBMethod : IProcessedPhoto { }
class AProcessor : IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes); // Returns PhotoProcessedWithAMethod
void Alter(IProcessedPhoto processedPhoto)
{
var casted = processedPhoto as PhotoProcessedWithAMethod;
// a "B" would crash here.
}
}
class BProcessor : IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes); // Returns PhotoProcessedWithBMethod
void Alter(IProcessedPhoto processedPhoto)
{
var casted = processedPhoto as PhotoProcessedWithBMethod;
// an "A" would crash here.
}
}
class Algorithm
{
void DoStuff()
{
var processor = ProcessorFactory.CreateProcessor(//stuff);
var processedPhoto = processor.ProcessPhoto(new byte[100]);
processor.Alter(processedPhoto);
}
}
So basically I want the DoStuff() method to create one kind of image processor, and call the appropriate Process method. However, despite what the interface suggests, Process only works on an IProcessedPhoto of the appropriate type (A and B photos are NOT interchangeable, they just have similar method names). My real code is more complicated in that each processor has several classes specific to them and not interchangeable, but I want to perform the same set of “logical” operations like a template method.
var artifactA = processor.DoA();
var artifactB = processor.DoB();
var final = processor.Process(artifactA, artifactB);
I hope that explains it.
You can use generics to bind the specific implementation of
IProcessedPhototo yourIPhotoProcessors:The downside is that your factory also needs this information: