Ryan Ernst first let me say that I am having this discussion because what you're saying goes against my limited understanding, and by stating what I think and listening to your response, I might learn something. You probably already know the things that I am saying. I might even find that I misunderstood what you were saying and that I agree with you.
Load balancing is used by distributed search. It happens to also be used for uploading documents, which is a client feature. Clients shouldn't be using this for sending distributed search requests. Solr does that.
I've just done a non-detailed review of CloudSolrServer. It uses a new LBHttpSolrServer object with a customized URL list for every request. Queries get sent to all replicas, updates only get sent to leaders. A TODO says that currently there is no support in the object for sending updates to the correct leader based on a hashing algorithm.
Outside of SolrCloud, the LB object makes sense for clients in master-slave replication environments, but only on the query side. Updates have to be directed to the master only. A separate load balancer does give you more flexibility, but not everyone wants to invest the time (or possibly money) required.
If the client on the server side and the client on the client side need identical functionality, then the existing situation makes sense – one implementation in the org.apache.solr.client.solrj namespace. If we think they'll ever diverge, even a little bit, then having an abstract class in the org.apache.solr.common namespace makes sense, although it should still be in the solrj source tree.