When designing libraries, I often end up resorting to the following pattern, which I don't like as it results in lots of type-casting.
The basic pattern is:
The code using the library hands an object to the library, the library then hands the object back to the calling code. The calling code is forced to cast the object, as the library hands back a generic type. (Stripped-down code example below)
The library defines the following objects and function:
TThing = Class
End;
TThingProcessor = Class
Public
Function CreateThing : TThing; Virtual; Abstract;
Procedure ProcessThing (Thing : TThing); Virtual; Abstract;
End;
Procedure DoEverything (Processor : TThingProcessor);
The calling code then uses the library by overriding the objects and calling DoEverything, as follows -
TMyThing = Class(TThing)
Public
X : Integer;
End;
TMyThingProcessor = Class(TThingProcessor)
Public
XSum : Integer;
Function CreateThing : TThing; Override;
Procedure ProcessThing (Thing : TThing); Override;
End;
Function TMyThingProcessor.CreateThing : TThing;
Begin
Result := TMyThing.Create;
End;
Procedure TMyThingProcessor.ProcessThing (Thing : TThing);
Begin
XSum := XSum + (Thing As TMyThing).X;
//Here is the problem, the caller is forced to cast to do anything
End;
The processor class is also a TThing factory. The library guarantees that it will only pass TThings to the corresponding TThingProcessor that created them, so it works, but isn't type-safe. While the code above is a bit stupid in that it doesn't really do anything, it shows why ProcessThing can't simply be shifted to TThing and be polymorphic - the XSum variable needs to be updated.
How can I restructure the code so the cast is unnecessary? I need to keep the library code separate but be able to accept any type.
Edit: Changed the hard-cast to an as-cast due to suggestion so it will at least throw exception instead of crash in the case of mismatched types