Refactoring

Using the Strategy Pattern

The strategy pattern lets you make "pluggable algorithms", so clients have different behavior without having different code themselves. We often use it to capture the "consequence in code" of some condition, which we can then let other code use without re-testing the condition. Here’s a little java snippet: dimension = horizontal ? width : height If you’re not familiar with ternary operations, what this says is "if horizontal is true, use the width, otherwise use the height". That snippet occurs …

Using the Strategy Pattern Go to Post »

Dealing with Nulls

Another refactoring topic today: dealing with nulls. There are a bunch of techniques, but they amount to a) don’t, and b) do but only one time ever. The basic idea: a null always occurs in a particular context, and in that context, it has a meaning. When we pass it up or down our call-stack, we are changing contexts, and hence changing meanings. We’re using the same symbol to mean different things at different times. Using the same generic symbol …

Dealing with Nulls Go to Post »

Refactoring Strategy: Move It Where You Can Test It

When I can’t test it where it is, I look to move it somewhere else, where I can test it. Today’s notion isn’t so much a single refactoring as it is a strategy that can be achieved in different ways (and different multiple steps). A modern and frequently occurring case: using a cool framework to expose service endpoints, we write a function and then we annotate it and poof, it’s an endpoint. This is how Java+Swing works, or Python+Flask. When …

Refactoring Strategy: Move It Where You Can Test It Go to Post »

Refactoring: Invert Dependency With Observer

Another refactoring today: Use the observer pattern to invert an infelicitous dependency. In and of itself, this is a modest refactoring, but its smell often co-presents with others, and unraveling it all can be tricky. (Note: We aren’t remotely done talking about first and second-order refactorings, there are plenty more to go. But I’m not writing a catalog, I’m working a project, so when a hefty one like this comes along, that’s when I’m talking about it. You’re gettin’ em …

Refactoring: Invert Dependency With Observer Go to Post »

Refactoring: Demeter-Wrapping

Today, another small 2nd-order refactoring. I call it "wrap a Demeter". As with the others, this is a very modest step, but still quite useful in some situations. Demeter violations are places where a client accesses not just an upstream service, but that service’s upstream services, or even that service’s service’s upstream services. It’s a common problem in evolving code, and left untended, a classic source of unchangeable code. Demeter calls look this: a.getB().getC().doSomething() a is getting a B, but …

Refactoring: Demeter-Wrapping Go to Post »

Refactoring: Keep It Running

A key value for those who take up the change-harvesting approach: "keep it running". This is actually a direct result of human, local, oriented, taken, iterative, and argues against many finish-line efficiency approaches. Think of a change as a point A, with an arrow coming out of it and ending at a point B. At the two points, we have a running system, but along the arrow, we don’t: our change is in flight. The change-harvester seeks to keep those …

Refactoring: Keep It Running Go to Post »

Chunking and Naming

In our continuing conversation about refactoring, I want to go a little abstract today, and talk about chunking and naming. Naturally, a topic thisi important has already been addressed by a stupid joke in the movie Airplane!, so we’ll start there. A passenger is approached by a steward, asking if he might be able to help with a problem in the cockpit. He says, "The cockpit! What is it?". She says, "It’s the little room at the front of the …

Chunking and Naming Go to Post »

Large-Scale Transformation and the Bias for Action

Continuing on our conversation about large-scale transformations, I want to talk about change-harvesting’s “bias for action” and tell you a weird thing I did in kontentment the last couple of days. Change-harvesting takes the stance that our most reliable strategy for change is a highly iterative process of act-look-think, in roughly equal proportions, repeated in small local cycles. We oppose that approach to look-think-act, emphasis on think, in large global cycles. This opposition is, of course, not a philosophical light-switch, …

Large-Scale Transformation and the Bias for Action Go to Post »

Large-Scale Refactorings

Large-Scale Refactorings — given the recent refactoring-related muses, a respondent asked me to talk about large or larger scale refactoring work. (I love it when people’s questions trigger my writing. Please do ask these things.) First things first, “large scale refactoring” is really a colloquial expression, a shorthand we sometimes use, but in my experience there is no such thing, for two reasons. The first reason is definitional. Remember, refactoring doesn’t mean “changing my design”, it means “changing my design …

Large-Scale Refactorings Go to Post »

Second-Order Refactoring: Narrow The Question

Another small second-order refactoring for you today. I call it “narrow the question”. If you’re asking an object for data, ask for exactly what you want to know, instead of what you’d need to compute what you want to know. A very simple example: the PlayerView wants to disable/enable some of its controls when the Player is actively playing. In the “before” code, PlayerView asks the Player for its PlayerState and decides, based on its value, whether that means the …

Second-Order Refactoring: Narrow The Question Go to Post »

Scroll to Top