Web Log of Ross Chapman

Web Log of Ross Chapman

Harmful ways to write about software

Dispatch from Soekarno-Hatta International Airport. Arrived way too early because of traffic fantasies.

While leafing through my daily software briefs I came across an article with that dissapointing refrain in our industry: this should be easy to do. There’s probably no better way to put a reader on the defensive and create an adversarial teaching situation. Suddenly I’m challenged to match the author’s intellectual prowess or else remain befuddled and continue writing shitty code. Why you fuckin with my head???

The article is another offering to the OO world which introduces the dependency indirection “injectable factory” design pattern as a cure for “rigid direct dependencies” in unit tests. Super simple stuff.

Also just LOL the indexical disambiguation science of the OO world. I’m just in love with Steve Yegge’s satire about this. A true kingdom of nouns. Frankly it’s a deliciously bookish world compared to JS-land where it’s function function function function.

If I grokked it right, I think the article is just a way of instructing the use of mocks without dependency injection, helping you avoid writing a service implementation for your tests that looks like this:

public class OrderServiceImpl implement OrderService {
  private final ShoppingCartService cartService;
  private final PricingService pricingService;
  private final InventoryService inventoryService;
  private final UserSession userSession;
  private final TimeProvider timeProvider;
  // ... and many more, this list will keep increasing when more requirements added

  public OrderService(
      ShoppingCartService cartService,
      PricingService pricingService,
      InventoryService inventoryService,
      UserSession userSession,
      TimeProvider timeProvider) {
    this.cartService = cartService;
    this.pricingService = pricingService;
    // ....
  }

  public CreateOrderResponse createOrder(CreateOrderRequest req) {
    // ...
  }
}

Ah yeah that looks hairy. I’m flashing to Jest unit tests where small function implementation details are mocked all the way down.

I remember a moment, a phase if you will, in my first couple of years working professionally as a softwhere engineer when I thought that understanding OO design patterns was part of our right of passage into…seniority, I guess? At the time I was beginning to write more in the Rails parts of our codebase and as a consequence, began inheriting a pressure, a notion – from where I’m not sure – to achieve familiarity with common OO design patterns.

From where, indeed. It’s really subtle how this worldview is propogated amongst our ilk but I think I’m starting to see, with clear eyes, the quiet, viral expansion.

For example, this digesis about “injectable factory” thats got me irked. When the author completes the situation and complication setup, he begins his solution section with:

The pattern is pretty simple.

Umm great, so what you’re proposing is just a fancy name for something I probably already know about? But then:

It’s implemented as a mutable value holder. This pattern is related to the factory, service locator, singleton pattern and ambient context pattern. All these patterns are considered anti-patterns according to most DI articles. But in practice, those patterns, especially singleton, are very handy and useful. They are prevalent in almost every non-trivial project. But they come with caveats. InjectableFactory tries to prevent those caveats at the same time keep the convenience and simplicity of those patterns.

It’s so simple I just need to have a solid undertanding of these (what must be other simple) concepts as well:

  1. dependency injection
  2. a value holder (probably Java slang for some kind of variable?)
  3. mutable value holder
  4. factory pattern
  5. service locater pattern
  6. singleton pattern
  7. ambient context pattern

I’m reminded of Rich Hickey’s 2012 Rails Conf talk where he disambiguates simple from easy which is a linguistic casuality which creates confusion in our industry about what “simple” or “easy” software really is or achieves. In the talk Hickey helps recoup a specificity for each word through an etymological tracing. Distilled you take away that simple is objective and easy is relativistic.

In consideration of the foregoing, our Javian knight likely means easy, which, by Hickey’s redefinition (rather reinstatement of acuity), means a spacial relativism of nearness. As in easy to go to or get or near to our understanding. In other words familiar. Like a better developer experience. Like:

…can I get this instantly and start running it in five seconds?

But he probably also means “being near to our capabilities”, the promise of easy.

Even if the usage intent is closer to Hickey’s easy, what about this list of like seven things I need to know that may not be near my capabilities? Like, easy for whom? What type of reader is summoned here? Since the author never names his imagined reader/audience we’ll never know for sure, but we can infer it’s likely folks who are experts in OO and the Java lang. Perhaps that’s the transgression that bothers me. This invocation of simple to self anoint as meister amongst a court of meisters, but without warning patronizingly forecloses access for an unitiatied reader. I think this is the gatekeeping emerging, infectiously. Almost too quickly to observe. I’m really glad Hickey also finds circumscribing code as easy dangerous for our industry’s wellbeing:

And we don’t like to talk about this because it makes us uncomfortable because what kind of capabilities are we talking about? If we’re talking about easy in the case of violin playing or piano playing or mountain climbing or something like that, well, you know, I don’t personally feel bad if I don’t play the violin well because I don’t play the violin at all.

But the work that we’re in is conceptual work, so when we start talking about something being outside of our capability, well, you know, it really starts trampling on our egos in a big way. And so, you know, due to a combination of hubris and insecurity, we never really talk about whether or not something is outside of our capabilities. It ends up that it’s not so embarrassing after all because we don’t have tremendously divergent abilities in that area.

Sigh. The deleterious effect of gatekeeping. Like is there some insecurity at play here for the author that requires he front his meisterness?

Though what if…I wonder if the author actually intended to describe injectable factory as simple by Hickey’s definition? As in, requiring less effort to “repurpose, substitute, move, combine, extend”, and less coupled (“interleaved”). The root of the word is one fold, braid, or twist. That does seem to be accomplished in the design. Nevertheless, I can’t get over the heavy connotation of reader culpability and capability implied in the (weak) qualification of “pretty simple.” Language is weird.

I’m thinking it’s probably best to avoid “simple” and “easy” in technical writing. Let’s not fuzzy match.

This reminds of when the words good or bad are used when discussing code. Without more objective substance, simple evidence, they just do a big hand-wave over facts and truths of the software’s outcomes and the shared understanding of the folks in the conversation. Is the software reliable, easy to change? What level of expertise is required, what audience are you interpolating into this discourse of nouns?

Is simplicity achieved?:

There are tons of libraries that look, oh, look, there’s different classes; there’s separate classes. They call each other in sort of these nice ways, right? Then you get out in the field and you’re like, oh, my God! This thing presumes that that thing never returns the number 17. What is that?

Is easiness achieved?:

…can I get this instantly and start running it in five seconds?