May 2020

Steps, Value, and Change-Harvesting

Let’s talk about steps and value. Out in the world, folks make a lot of decisions involving these ideas, they reason about them. We want to make sure our reasoning is based on a thorough understanding of the implicit premises. What’s a step? A step is a gap or space, in time and activity, in between two points, a Before point and an After point. At the Before point, a system is "ready". At the After point, a system is […]

Steps, Value, and Change-Harvesting See Full Post

My Best Bug

I shipped a word processor that formatted the hard drive every 1024 saves. Must have been ’84 or ’85. I was a bright 25-year-old with about five years in the game. I was one of two programmers who wrote & maintained a suite of apps kinda like Office: spreadsheet, wp, database, plotter, such like. We customized everything for three or four vertical markets. So I wrote most of the wp. This was in Forth, on a variety of OS/CPU combinations.

My Best Bug See Full Post

Juniors And Seniors

Lotta inspiration for junior geeks stuff floating around. I’m having a low productivity day today because, well, you know all of that, so I’ll take a minute nd pitch in. Do you know what I did for about twelve elapsed hours of coding time? I solved a problem. Cuz, you know, I got mad skillz, and have been geeking for forty years, and am even, in a couple of microdomains, a bona fide citable expert. I’ll tell you the problem

Juniors And Seniors See Full Post

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 See Full 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 See Full 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 See Full 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 See Full 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 See Full 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 See Full Post

Scroll to Top