Some features, idioms and styles affect the scope of a refactoring session. First some examples (mainly from Java):
- Java requires routines to declare (most of) the exceptions they throw. Thus if you add an exception to a routine, you also have to add a declaration to the routines which call it, the routines which call them, and so forth.
- If a method has been marked as private or final and you want to use or override it, you have to modify its declaration. (See MethodsShouldBePublic for more discusson.)
- If you change the name of a class, you have to update all places where variables of that class are declared. (In Smalltalk you often only have to update where the instances of the class are created.)
For these and many other reasons, refactoring in Java is harder than refactoring in Smalltalk. There is an argument that Java programmers should consciously adapt their style to make refactoring easier. For example:
- Don't use exceptions.
- Don't use private methods. MethodsShouldBePublic.
- Use abstract base classes and interfaces for variable declarations.
Alternatively, we could be content to break the refactoring into smaller units. Where cascading changes are necessary, find the minimum at each step necessary to satisfy the compiler. On MethodsShouldBePublic
puts it like this:
- "Regarding machine support for private methods, I would like for Smalltalk to have a warning when you use a private method externally from a class. (Notwithstanding that this isn't quite possible.) Why? Because it would alert me to an anomaly in the system, which I would then have an opportunity to correct, by refactoring, by making the private method public, whatever. I would not, however, want the world to stop until I fixed it."
The idea is that the system be allowed to remain in a "bad" state, temporarily, so we can postpone some of the work of the current refactoring session to a later one (perhaps only a few minutes later). This is often hard in Java, but perhaps good advice for language designers.
One practical idiom would be:
- Throw new RuntimeExceptions (which don't need to be declared). Redefine them later to be subclasses of Exception. (At this point you will want to verify that they are actually caught and handled properly.)
This is partly motivated by the pages cited, but also a recent discussion in comp.object in which BertrandMeyer
argued that good languages should never
offer compiler warnings. I'm still interested in the differences between his attitude (shared by much of Java), and the Smalltalk/XP community. -- DaveHarris
"Don't use exceptions."
You can get around the problem cited here if you DeclareThrowsExceptionByDefault
. You can use the other CheckedExceptionPatterns
to deal with the other problems raised by exceptions in Java. -- PhilGoodwin
Better tools could make many of the necessary transformations easier.
Wiki pages are easier to refactor if you write in the third person.
If you take a subjective ThreadMode
comment written in first person and convert it to a document mode OpeningStatement
you pretty much have to rewrite it. Is this a bad thing?
Well, it's more work anyway. I think that it's better to leave the thread mode as is and use it as inspiration to write a new DocumentMode OpeningStatement
. -- PhilGoodwin