Method Selection Engine I have this working code that selects which method to call based on values in 
the parameter:

@Override
public Iterator&lt;DBObject&gt; __find(DBObject ref, DBObject fields, 
        int numToSkip , int batchSize , int limit, int options){
    Preconditions.checkNotNull(ref, "Reference object can't be null");

    LOG.info("Reference object=" + ref);

    DBObject query = (DBObject) ref.get("$query");
    DBObject orderby = (DBObject) ref.get("$orderby");

    // Remove special fields
    dataCleansing(ref);

    if (query != null){
        LOG.info("Query object=" + query);
        if (orderby != null){
            LOG.info("Sort object=" + orderby);
            Iterator&lt;DBObject&gt; it = _store.getSortedObjectsLike(query, orderby);
            return it;
        } else {
            Iterator&lt;DBObject&gt; it = _store.getObjectsLike(query);
            return it;
        }       
    } else {
        if (orderby != null){
            LOG.info("Sort object=" + orderby);
            Iterator&lt;DBObject&gt; it = _store.getSortedObjects(orderby);
            return it;
        } else { // query and ordeby are both null
            Iterator&lt;DBObject&gt; it = _store.getObjects();
            return it;
        }   
    }
}


I really think there's some way to better address this selection of functions than just plain if-else statement. 

As conditions might grow and more objects passed for condition checking. Is there an "elegant" way to deal with this kind of "choose which method to execute based on parameters values and existence" ?
One possibility is to create a method that accepts all possible parameters, and have that method gracefully handle null values, or use the Null Object pattern for those parameters. getSortedObjectsLike(query, orderby); seems like a good candidate, if you could pass nulls for query and orderby or new EmptyQuery() and new NoOrderBy().


pro : no need for method selection, simply evaluate whether a parameter is available or not, and pass null or Null Object if unavailable.
pro : simplified API
con : adding parameters in the future will involve increasing the complexity of the one method that handles all parameters (can probably be mitigated with some refactoring)
con : implementation of the method that handles all parameters may degrade into the kind of method selection we try to avoid here.




Alternatively you could use introspection, and select a method based on the available parameters.


pro : adding future parameters (if done judiciously) will not affect the method selection implementation
con : every added parameter will double the number of methods needed on the API (for every existing one, we'll need one that also has the new parameter)
con : harder to debug
con : hides dependencies
con : query and orderBy are currently the same type, introspection can't tell them apart