These are not the buzzwords you're looking for
Sometimes you come across expressons which are commonly used in the Agile community, but which lack a formal or straightforward definition.
I have to say that in the Agile and eXtreme Programming community the scenario is often much better: Test-Driven Development has a page on Wikipedia which explains it in and out; Continuos Integration is a standard practice.
The last thing the Agile movement wants is to have his terms hijacked as buzzwords. However here is my take on three terms which I encountered over and over, without a clear explanation accompaining them.
Axis of change
In this metaphor, the axis can be thought of as a cartesian axis, while a class is a point on the plane or in space.
The single responsibility principle (SRP for friends) can be explained with this metaphor: there should be a single axis in the reference frame of a class. The class can move along this single axis when its specification changes, but the change itself is contained in one dimension. When a class does too much work, it often has from 2 to N axis of change, and it can be pulled in different directions at the same time, especially if the axis are not orthogonal to each other.
For example, no modern developer would mix generation of SQL queries and HTML code in a single class: the result would be an item able to move in multiple directions, one detailing HTML generation and one detailing SQL query parts. After a certain point, the complexity would be overhelming.
Orthogonality of components is a similar concept: in this case, you'll prefer two classes, one for each axis. Then you will be able to tie them together to produce a final component which can be anywhere in the plane. As anyone with a loose background in physics can tell you, rectilinear motion is much simpler to deal with that motion in free space.
An Intention-Revealing Interface is a Domain-Driven Design transposition of the concept of defining interfaces which are not simply the signature of an implementation, but an helpful abstraction. The concept is somewhat similar to fowler's Role Interface.
In the DDD terminology, however:
- the interface must adhere to the domain language;
- it is intended as more than an interface as defined in Java or other class-based programming languages.
In fact, even the set of public methods in a class is an implicit interface, especially if there's no explicit interface implemented there (in languages like PHP or Ruby where duck typing is so diffused, for example).
In this picture, each class, method and parameter name should convey a meaning which asbtracts away the complexity of the implementation.
In our example of HTML generation, we will prefer a method named createTitleBox($text) to one named createH1($containedHtml).
Emergent Design is design that emerges from the code and the tests that you write, instead of by blindly applying architectural (and non-architectural) patterns.
For example, recently I was developing with my colleague a class named Changeset, a DTO which goes from the user interface through my lower layers.
At first, we were using an array. When we started wrapping it in a class, we needed a bit of indirection for the instantiation: otherwise we would call a constructor with 4 or 5 arguments, a very ugly Api as in these cases you often fail to remember the right order of parameters, and the meaning of one or more of them.
So we had now a class used for creation of another class. This should raise your design patterns spidey sense. However, we already felt that multiple method calls were needed on that class, because of the extent of the contained data.
Furthermore, some subsets of the data were repeated, like the collections modifications list. This mapped well to multiple addCollection() method calls.
We wanted an immutable object graph anyway, that once constructed cannot change anymore. So the construction had to take place at once. We added a method build() to our indirection class, which when called constructs a Changeset object, with some collaborators, using the data injected in the Builder up to this point.
In this case, the Builder pattern emerged: a creation indirection when we gather data with some orthogonal methods, and then create an object all at once; the object graph created is hidden by the root object, which is returned by the Builder. The client code that creates the Changeset only deals with the Api of the ChangesetBuilder.
I realized recently that explaining patterns by describing how they emerge may be the most effective way to do so. However, I'm not totally sold on the concept of Emergent Design, as I prefer to refactor towards a pattern as long as I see the need for it. Patterns are standard solutions ro recurring problems, and I don't have to solve the problem again and again if I already know the solution. Blindly applying patterns results in over-engineering: but patterns are not One Size Fits All solutions, as they have many variants and extension points. Just borrowing the language of a pattern is already helpful, but you'll implement the code everytime any way. By recognizing the need for a pattern before applying it, you'll have however a guide instead of going into uncharted solution space.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)