Refactoring I'm familiar with. Ken Pugh I'm familiar with. Ken Pugh talking about prefactoring sounded interesting. And it was!
You may not know what prefactoring is. I didn't. Ken defines prefactoring as "developing code that reduces the need to refactor".
Oh, I get it. Ken's talking about good coding principles!
Sure enough, that's exactly what this talk was about. A few that stood out for me:
- Know the assumptions you're making. When serializing a spreadsheet out to disk is it better to write it out be rows or by columns? The "correct" answer completely depends on your current context. Make your implicit assumptions explicit and then make your decisions based on that full set of information.
- When in doubt, choose the option that will make it easier to change things in the future. For example, it's easier to combine concepts than to split them apart. Gerry Weinberg (kibitzing from amidst the crowd) generalized this to "It's easier to lose information than to find it". Similarly, pretend there are no primitives and make classes for everything. If Account changes from an int to a string, do you really want to inspect every int in your application to decide whether it needs to be changed?
- Define every class using a single sentence. When contemplating adding a responsibility to a class, vet it against that sentence to determine whether it really fits in the class. Good names are still important, but a succinct definition of a class's purpose is extremely useful even if it's name is the most perfect name imaginable.
- Separate concepts into classes based on behavior, not data. Inheritance hierarchies whose lower levels differ only in the data they return are misusing inheritance. Instead, create a single class that is configured with the differing data.
- Write single purpose functions. Ken takes this further than the common "a method should do exactly one thing and no more" and advises that you separate the policy of a method (what it does) from its implementation (how it does it). For example, don't embed blocks of code in the conditionals and various branches of an if statement but instead call methods that encapsulate that code. This is just one part of a larger practice Ken also espouses: intentional programming. Code that has been programmed intentionally says what it means and means what it says and is more understandable than code that has just been written.
- Be sure you're using the entire interface when you inherit. If you're just using part of the interface containment is likely a better option. Along the same lines, split a single interface into multiple interfaces if multiple clients need different parts of the interface.
Now if Ken could just show me how to prefactor my way out of maintenance altogether...<g/>
*** Comments, questions, feedback? Want a fun job on a great team? I need a tester! Send two coding samples and an explanation of why you chose them, and of course your resume, to me at michhu at microsoft dot com. Great coding skills required.