Prefactoring has generated some discussion among developers. Some developers have formed opinions about it based upon the editorial summary in Amazon. Unforunately that summary was not approved by me and was full of marketing hype that did not represent prefactoring. This entry hopes to clarify the issues.
Prefactoring evolved from a Birds of a Feather session at a Software Development conference in Washington, D.C. Martin Fowler, Ron Jeffries, myself, and several others discussed why software came to need refactoring and practices that might be used to lessen that need. Spurred by that discussion, I compiled a set of guidelines for creating software and entitled it Prefactoring.
Refactoring, according to Martin Fowler, is a controlled technique for improving the design of an existing code base. It does this by applying a series of particular
code transformations, each of which are called refactorings.. Code smells suggest refactoring,
Prefactoring guidelines emphasize things to think about before you start coding. Refactorings are code transformations performed after you have created code.
The prefactoring guidelines encompass some that are directly related to code transformations and others that are not. A commonly used refactoring is Extract Method. The Separate Policy from Implementation prefactoring guideline suggests organizing methods into ones that perform implementation (e.g. totaling a customers purchases) and ones that perform policy (e.g. giving the customer a discount based on total purchases). If you think about this guideline as you develop the code, you may find yourself separating many methods, and therefore requiring fewer Extract Methods. Separating policy from implementation is not an operation you can perform mechanically. Its something that you have to do intentionally. Coding with intention makes your code start with less smells.
Other prefactoring guidelines do not deal with code transformations. The Easiest Code to Debug is That Which is Not Written.guideline suggests that you use Google as a development tool. Before even writing a single line of code, google to see if the feature you are about to create exists in either open source or commercially available software. If it is, check it out. You may get away with not having to write a single line of code. Even if the software doesnt work out, youll have an opportunity to see how others have approached a solution. Developing software is not just about writing code; its about delivering solutions, regardless of how they are created.
There is no big design up front in prefactoring. The Think About the Big Picture. guideline is not about big design. It suggests that you spend a little bit of time investigating the environment in which you are going to create your software. The environment (e.g. a corporate infrastructure, J2EE, or web services) may provide numerous services (e.g. security or error handling) that you dont need to develop or it may suggest ways for structuring your code to fit into the framework.
Following the prefactoring guidelines does not mean you dont refactor your code. The guidelines can help keep the smells out. . But when code starts to smell, refactor it. As you go through development, you gain more knowledge about the total project, which can generate new ideas. Performing a retrospective after every release, as one guideline states, can help direct this generation of new ideas.
Agility is about delivering working software to the customer. Iterative and incremental development and customer communication, as shown in the example in the book, are key principles to enable that delivery. You can use multiple tools to achieve the goal refactoring performing transformations on created code is one tool, prefactoring thinking about things before coding is another.
There's something very interesting about this to me. When I've seen refactoring patterns I've always assumed if it's good to change code in a certain way, then it's probably good to consider designing it that way initially. It never occurred to me that by stating these as ways to change code that people might not grasp that. Is it your contention that there are many people who only consider these design prinicples (that's what they are, really) after the intial design? It's seems crazy but on the other hand it would explain a lot of designs.
It doesn't seem clear how this is not just design.
Is it that: this is a particular style of lightweight design? In which case what is a characterisation of that style? Or is it that this is particular style of design derived from observation of refactoring cases and frequencies etc.? In which case what synthesis of style emerged? Or perhaps something else...
Could you possibly furnish me with a simple description of how this is novel and distinct?
Refactoring is also about restructuring code based on existing code (working code), you restructure a concrete piece of code based on the its context (the rest of the code). Almost for any possible refactor there exists an opposite refactor, and so the extract method has the inline method. There is no a general rule or guideline for which one apply without taking into account the context of the refactored code.
Refactor is a bottom-up design technique. What you call prefactoring just seems general top-down design guidelines. Shouldn't be related.
I think refactoring is good for two reasons 1) existing code is crap 2) you cannot know how the code should look like before you've written at least part of it.
I think prefactoring contradicts the second point - which makes me wonder if it is any good.
When I say you cannot know how the code should look like in advance, this reflects my experience.
When I start designing a library/component, I usually have a vague plan what the responsibilities of the classes are - but it gets clear after I've written a couple of methods.
At this point, I usually start to refactor to make methods and classes smaller and clearer. I then sometimes wonder if it had been worth the time to think about the design more in advance - but I usually come to the conclusion that it both saves time and increases the quality to refactor instead.
In conclusion, I'm not saying that you should release badly designed code - but it is ok to start with an average design and then refactor before releasing the code.
> 2) you cannot know how the code should look like before > you've written at least part of it. >... > In conclusion, I'm not saying that you should release > badly designed code - but it is ok to start with an > average design and then refactor before releasing the code.
I agree only to a point. If I am going to write a GUI, I know off the bat that I am going to design using a builder pattern and/or mvc. What you are saying is true but generally only when you don't really have a good picture of the solution to start with. One way to deal with this is to hack out some code, figure out what you need to do. Hide it. Start over with a good design. Repeat as needed.
Refactoring is good but it can be expensive. Sometimes you can paint yourself into a corner when you aren't looking at the big picture.
> > 2) you cannot know how the code should look like before > > you've written at least part of it. > >... > > In conclusion, I'm not saying that you should release > > badly designed code - but it is ok to start with an > > average design and then refactor before releasing the > code. > > I agree only to a point. If I am going to write a GUI, I > know off the bat that I am going to design using a builder > pattern and/or mvc. Yes, I agree. I was exaggerating. What I meant is that you don't need to know what the method signatures will be and how a component is distributed among classes.
But you do need to know what your architecture will look like (the distinction between architecture and micro-design is floating, of course).
I also think that you do need to know the general performance implications (depending on your needs).
> What you are saying is true but > generally only when you don't really have a good picture > of the solution to start with. I realize that I was describing micro-design. Would you agree that on that?
All this talk about "smells" constantly conjures up an atmosphere of smelliness, farts and the like. I know that his Grace the venerable Fowler started this manner of expressing a 'bad impression', but did everyone else have to follow. Couldn't someone have told him off before everyone else followed.
At least we could start talking about bouquets, rather than 'smells'. A bad bouquet conjures up images of withering flowers, rather than moulding feet and trashcans. Definately preferable.
Come on folks, have mercy on us super-sensory types; my imagination isn't coping well. Actually I think I'll get out of this programming lark.
Goodbye, humans, and thanks for all the smells....
...and before I leave: anyone want decent south american music check out this - www tumimusic com . Andean stuff particularly pleasant.
OK. That makes more sense (that it came from you.)
> What I meant is that you don't need to > know what the method signatures will be and how a > component is distributed among classes. > > But you do need to know what your architecture will look > like (the distinction between architecture and > micro-design is floating, of course). > > I also think that you do need to know the general > performance implications (depending on your needs). > > > What you are saying is true but > > generally only when you don't really have a good > picture > > of the solution to start with. > > I realize that I was describing micro-design. > Would you agree that on that?
I suppose, yes, the more I think about it. But I think that refactoring can really leave the micro-design or abstraction quickly, especially in a rigid language like Java.
I guess my point is that while I agree with most everyone else here that the concept of 'prefactoring' is not novel, I think there is something to be said for spending a little time thinking up front. I've done a lot of 'cowboy-coding' and a lot if times I end up in nearly the same place, it just takes me a lot longer because I end up writing the entire thing 3 times instead of 1.5 times when I really think up-front. I also sometimes end up with cowboy artifacts where I look at it later and think "what the hell was I thinking?"
Correct me if I'm wrong, but what I see as prefactoring is based on the idea that if we know what good design is through refactoring, why don't we use that knowledge and do the good design in the first place? Certainly it's good and desirable to have some idea what you are doing before you start. The unstated assumption that conflicts with the intent of the refactoring book and agile methods in general is that it is possible to get it right the first time, up front.
We do have techniques, like test-driven development, pair programming, and so forth, that help guide us on the right path, but we need to be aware of our limitations. As noted at http://www.c2.com/cgi/wiki?ExtremeHumility, we can adopt the attitude that we aren't omniscient and we do make mistakes and adapt our techniques. We also keep in mind that change is inevitable, and balance the desire to get it right based on what we know now with an awareness that in the future, our understanding may be invalidated by circumstances.
Nothing in agile or refactoring says, to me, "don't think ahead", but instead says, "don't be overconfident and imagine you can get it right the first time, and don't believe that what's right for now will always be right." Prefactoring seems based on the opposite view.
> Nothing in agile or refactoring says, to me, "don't think > ahead", but instead says, "don't be overconfident and > imagine you can get it right the first time, and don't > believe that what's right for now will always be right." > Prefactoring seems based on the opposite view.
Maybe. I kind of see a lot of accepted design principles as ways of making code more easily fixed when the mistakes are inevitably discovered.
Flat View: This topic has 23 replies
on 2 pages