I am reimplementing some component and noticed that the original version has a Liskov Substitution violation. It's not all that critical, though I'd like to get rid of it in the new implementation . It is however not clear to me how to do this.
I have a component defining very simple value classes used by the system. This component has a DataValue interface and a dozen implementations such as NumberValue and GeoCoordinateValue.
The component I'm reworking is a storage layer meant for indexing data so it can easily be queried against. This component contains a set of classes that provide storage information for a particular DataValue implementing class. This information are things such as which fields a table needs to have to contain the DataValue in question, which field should be used for sorting, and what indexes should be placed. These classes all implement some DataValueHandler interface.
The LSP violation occurs for two particular methods in this DataValueHandler interface:
getWhereConditions( DataValue $dataValue ) getInsertValues( DataValue $dataValue )
The interface defines these methods take a DataValue. The implementations however expect the DataValue for which they provide information. For instance, the NumberValueHandler expects a NumberValue, and will throw an exception if it gets a GeoCoordinateValue.
So how can I get rid of this? (Before anyone suggests it: putting info of some specific storage backend in DataValue is not going to happen, as this would be worse design wise then the current LSP violation.)