Table of Contents
Characterizing Sets And Weighting Principles
Characterizing Sets
A principle language cannot free the designer from actually taking a decision. There is no algorithm which replaces a sound judgment. Rather principle languages point to the relevant aspects to consider. For a given design problem, the result is a characterizing set of principles which describes the dimensions of the design space, i.e. the advantages and disadvantages of possible solutions. A typical characterizing set has around five principles.
There are two typical questions which can be answered using a characterizing set:
- Given a design problem and a solution, is the solution good?
- Given a design problem and several solutions which one is the best, i.e. the appropriate one?
In the first case the solution can be rated according to the principles in the characterizing set. If the benefits justify the liabilities, the solution is appropriate. Otherwise it is worthwhile to think about alternatives.
For the second question all the solutions are rated. The solutions which are not pareto-optimal (see conflicting principles) are clearly bad solutions. The others are all “good” but have different downsides and benefits. The characterizing set of principles shows which they are and helps reasoning about which solution to take.
Weighting Principles
Note that it's not the number of principles which is essential. Weighting the principles and taking the decision is still the task of the designer. Sometimes the weights may be derived from the requirements. Where this is not possible the weighting is an expression of the personal style of the designer, the team or the project.
The DRY principle is a typical example of a principle which might be weighted differently. Virtually everyone will agree that DRY is valid. But there are also downsides of DRY code. The wiki page lists KISS as a contrary principle. Removing duplication typically has the downside of increased complexity. But how much complexity is justified for making code less redundant? Moving duplicate code to an extracted method creates a further level of indirection but is typically still quite light-weight. But refactoring code according to DRY sometimes also means to extract a new base class. And for some forms of duplication, even code generators are necessary adding further complexity to the build process.
Certainly some people will rather favor KISS and others will prefer DRY. Some will say one duplication is tolerable and you should only refactor when there are three similar pieces of code (see Rule Of Three). But others will say that every tiny bit of duplication demands refactoring and even complex code generators are justified if they ensure that there is a single, unambiguous, authoritative representation for each piece of information (see Rule Of Generation). Neither position is wrong and to some extent this kind of weighting is just personal style. Nevertheless according to UP it is a good idea to roughly agree on some weighting in a team or for a specific project.