Question

This is a general patterns/best practices question. I'm using C# but I think it's equally applicable to Java and other environments. It's very common for libraries to expose a builder class that goes somewhat hand in hand with a more service-oriented class. Take a hypothetical ORM that allows you to do this:

var sql = SQLBuilder.Select("*").From("Users");
var users = db.ExecQuery<User>(sql);

As a library developer it's tempting to combine these into a more fluent, discoverable API with only one object to be concerned with:

var users = db.Select("*").From("Users").ExecQuery<User>();

Note that the difference is strictly in the API surface; under the hood we'd still have multiple classes with proper separation of concerns.

One potential drawback of the second approach is testability. In the first approach, it's much easier to stub out the service object. But what if the library developer took care of this by exposing some sort of static TestMode property that can be configured on app startup or test setup and signals that the service calls should be recorded/faked?

From a purist standpoint, other than testability, is there anything "wrong" with the second approach? I'm actually debating whether to do this in a couple libraries I'm working on, and my main red flag is that the first approach just seems so much more common.

Was it helpful?

Solution

I think the second approach is fine, as long as the public API class is only concerned with providing the fluent interface and delegates the work properly.

OTHER TIPS

I actually intend to do take the second approach for the next version of my micro orm. It didn't come up in my mind that testability would suffer and thinking about it right now, I think it won't. Because that fluent builder is merely a facade and at least the last part I'd probably implement it as an extension method which is easily testable

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top