Too many commands in a group
The most common mistake made in choosing command granularity is to
package all the fields on a page in a single command, regardless of the organi-
zation of the data on the page. For our example, we could choose to use a
single command to collect all of the information in the insurance policy along
with some additional customer-level data. In practice, that decision might not
be all bad, if the expectation is that all of the customer information will be
needed every time a policy is retrieved. In our case, let's suppose that we know
that our policy data will need to be retrieved independently. This decomposi-
tion, called page-level granularity , would be too coarse. The problems with
page-level command granularity include:
Reuse is damaged. To reuse a command (which is essentially a wrapper
around a model), our units must be based on granularities that make
sense for the model, not the user interface.
User interface redesigns are more difficult, because the command layer is
organized around the user interface. The command layer loses much of
its promise. Instead, if our commands are grouped logically, we can
expect them to be applicable across many different solutions.
Commands are not in logical units for other purposes, such as undo/redo.
In a user interface, it would not make sense to “Undo customer and
policy change.” (This is applicable only to update commands.) Logical
groupings would allow better packaging for undo / redo functions.
Essentially, though our application's model and view are physically decou-
pled, we have built a logical coupling based on our granularity decision. In the
next section, we will explore the characteristics of a better grouping.
Solution: Refactor to appropriate granularity
So far, the examples in this topic have used a single command per page. That's
due to the simplicity of the examples that we have chosen. Multiple com-
mands per controller and output page are relatively common and can be good
designs, especially when user interfaces get complex. Figure 4.4 shows this
architecture with our latest example, refactored.
In most cases, refactoring this antipattern is straightforward. We'll borrow
a couple of ideas from relational database theory. Here are the steps for refac-
toring coarse commands.