Sonntag, 8. August 2010

Simpler Java #7: The Query / Command Pattern

Yet another pattern for simpler programming, but this time its a rather controversional one, i suspect.

The language Eiffel devised the "query / command" pattern for its methods:
Queries are methods with result values (functions, in some other languages). A query can be used to calculate values, but may not introduce modifications to the object.
Commands are methods with side effects (produces). A command will change the state of an object or resource, but it does NOT provide information about the process (hence, void return type).

This separation, detailed in more detail in a lot of sources, can be very productive for ANY programmer to follow. In the sense of java, query / command would mean the following:
A query may only return new data. it is not allowed to use commands by itself, expect for temporary objects which it created. Especially is it not allowed to change any kind of global public state.
A command may only modify data, but never yield information. After each command, the internal states of all queries might have changed. Up this point, all queries of the object are guaranteed to yield the same results for the same inputs (are referential transparent).

Advantages / Disadvantages
  • Query command is the clean bridge between the functional and the imperative world. All queries are guaranteed to be pure functions which will always yield the same result UNTIL the state changes.This allows for optimizations.
  • State-changes (void methods) are easily to see in source-code, since they have no result.
  • The code can be more verbose, since command chaining is not allowed, and streaming is more complicated. An example of stream are java file streams and iterators. Both have a kind of "next" method, which yields the next result and the moves forward to the next. In the query-command pattern, this must be separated into to methods (in example, next and get).
  • The former can actually be seen as an advantage: Since commands are required to be given line-by-line and not inspected for informations, they cannot be confused with queries AND this pushes immutable solutions, which solely rely on queries and can be easily chained.
  • The query / comand patter is a very good model of a real-world concept. One of the disadvantages of functional programming is that mutable state requires more complex concepts as effect systems. The query command pattern describes imperative programming on the other hand as valid to "go to the next state" BUT it does not allow it to return values, as calculation must be done in (pure) functions.
 Yielding the query/command pattern should be the goald of any good programmer. Try to really use the "void" type if you want a command with sideeffects. Command-Chaining, like in the StringBuilder, is a very powerful tool, but I am now less convinced wether it is also a valid one.. Making the imperative world a bit harder, but easier to understand, and the functional one more prominent seems to be an approach which is well-worth the trying.

Keine Kommentare:

Kommentar veröffentlichen