DSL vs. Fluent interface: Compare & Contrast
Let us take a simple example, scheduling tasks, and see how we can demonstrate the difference between the two. From the perspective of the client, what do we want from a scheduling tasks?
- Define named tasks
- Define what happens when the task is executed
- Define when a task should execute
- Define conditions to execute the task
- Define recurrence pattern
Now, let us look at the fluent interface for this:
new FluentTask("warn if website is not alive") .Every( TimeSpan.FromMinutes(3) ) .StartingFrom( DateTime.Now ) .When(delegate { return WebSite("http://example.org").IsAlive == false; }) .Execute(delegate { Notify(“admin@example.org”, “server down!”); });
And contrast that with the DSL sample:
task "warn if website is not alive": every 3.Minutes starting now when WebSite("http://example.org").IsAlive is false then: notify "admin@example.org", "server down!"
The second version has far less line noise, it a lot more clearer, and allows me to grow my DSL as I get more information, without hitting the language limits.
It also brings to mind another issue, who define these tasks and when?
Most of the time, I use a DSL as a way to setup and configure a runtime engine. I might talk later about imperative vs. declarative DSL. I tend to write my DSL at a different time than the code.
In fact, if you have no need to ever do something externally, and a fluent interface manages to express the ideas that you have clearly enough, than you probably should just use that.
If you need to do things externally, than a DSL is the place to look for. In fact, if you feel the urge to put XML into place, as anything except strict data storage mechanism, that is a place to go with a DSL.

Comments
Comment preview