So, I have this public API that my application exposes, allowing customers to write plug-ins. For the sake of this example, let's say it's a fairly simple key-value pair system, something like:
public interface Key {
// marker interface, guaranteed unique in some scope
}
public interface KVPService {
Set<Key> getKeys();
Object getValue(Key k); // must be a key provided by getKeys() or it blows up
}
Now let's say that internally, the Key
has some attributes that shouldn't be exposed -- say a database ID. What I'm currently doing is something like this:
/** Internal impl of external Key */
class InternalKey implements Key {
int getDatabaseId() {
// do something...
}
}
/** Internal impl of external KVPService */
class InternalKVPService implements KVPService {
// ...
public Object getValue(Key k) {
InternalKey ik = (InternalKey) k;
return getValueFromDBOrWherever(ik.getDatabaseId());
}
// ...
}
This seems less than ideal. Is there some way I can rearrange the responsibilities to avoid the cast and still maintain the inside/outside encapsulation?
Note that in the real world it's a fair bit more complicated than this; the Key
equivalents have a fair bit of metadata attached and there's a number of things someone might want to do with one other than get a simple value, so just exposing, say, Map.Entry
-like objects instead won't necessarily solve the problem.
The only thing I've been able to come up with is to separate the internal and external keys entirely, and keep around a Map<Key, InternalKey>
. But in that case I'd have to either copy the metadata, which violates DRY, or have the external Key
delegate to InternalKey
, in which case the Map
violates DRY.
Can anyone think of something more clever?