Reputation: 2944
I'm trying to come up with a good design for converting a set of different objects into a common object. Basically, I receive one (of many slightly different) complex object from system A, and must convert it into a simpler object for system B.
The objects I'm converting from all inherit from the same base class, so part of the conversion is always the same. But in every case, the conversion does involve something very specific to the type of the object I'm converting. It could be a RPC, an HTTP fetch, a database lookup, or something entirely different.
I'm looking at the Template method and the Strategy patterns. But neither seems like a perfect fit. The problem is that the method/strategy to use is tied to the type of object being converted and so isn't interchangeable.
This is a sketch of what I'm thinking about doing:
class FooConverter {
Map<String, FooConverter> converters;
Foo convert(Bar bar) {
Foo foo = ...; // Common part of the conversion.
FooConverter c = converters.get(bar.getType(), foo);
c.finishConversion(bar, foo);
return foo;
}
}
What annoys me is that FooConverter
must define an additional conversion method that takes the partially converted object as a parameter. So I end up with a mix of a Strategy (since all the converters implement the same interface) and Template method (since the common part of the conversion is shared by all the converter). Is there a better way?
Upvotes: 2
Views: 1334
Reputation: 10882
There are at least two ways to do it:
Upvotes: 1
Reputation: 233170
It sounds like you need to traverse a structure and be able to do something with each element in the structure. That 'something' varies by the type of the element, and you also want to be able to vary how that 'something' is implemented.
If that is the case, it sounds like a perfect fit for the Visitor pattern. I just recently used it myself in a scenario much like yours where I needed to convert one structure into another in a flexible manner.
Upvotes: 3
Reputation: 106352
You are taking a bunch of "Convertable" objects, perhaps you could make "Foo" have Decorators for each "Convertable" base type, when you detect the "Convertable" type, you can add the appropriate Decorator to the "Foo"?
Upvotes: 2
Reputation: 69342
You could implement a subclass of the target type with a constructor for each of the given types you're converting from. From the constructors call the overloaded constructor of its parent type.
Something like:
public class ConvertedFoo extends Foo
{
public ConvertedFoo(SuperTypeA a) {
// Do some common stuff here.
}
public ConvertedFoo(SubtypeOfSuperTypeA a) {
ConvertedFoo((SuperTypeA)a);
// Do more specific stuff here.
}
}
If the ConvertedFoo
class gets too large, it can easily be split up for subtypes.
This would allow for maximum code re-use and would centralize of all your conversion code without the use of dynamic type-checking.
I don't think this is a named pattern. If anyone knows, I'd like to know its name.
Upvotes: 0