liveBook · Manning

Straightforward implementation

As explained in Grokking Simplicity

A software implementation pattern that expresses behavior with operations at similar levels of abstraction while omitting irrelevant lower-level details.

A straightforward implementation solves the problem implied by a function signature at one appropriate level of detail. Irrelevant lower-level details—especially ad hoc data-structure operations—make code harder to read and maintain. section 8.4 section 8.8

Use these signals when designing or reviewing a function:

  • Keep operations in the body at similar levels of abstraction; mismatched call-graph arrow lengths reveal mixed detail levels. section 8.6
  • Extract a general function when a low-level loop or indexing operation distracts from the function's purpose. section 8.6 section 8.8
  • Use naming and focused responsibilities to clarify the implementation, rather than merely hiding unclear code inside helper functions. section 8.8
  • Treat extra detail as a design smell, while avoiding layers added only for appearance or sport. section 9.14

Making a shopping-cart function straightforward

A cart function that loops through an array to find a tie and a tie clip mixes business logic with representation details. Replacing the loops with isInCart(cart, "tie") and isInCart(cart, "tie clip") lets freeTieClip express the business rule directly; the search detail remains in the more general isInCart function. section 8.5

function freeTieClip(cart) {
    var hasTie   = isInCart(cart, "tie");
    var hasTieClip = isInCart(cart, "tie clip");
 
    if(hasTie && !hasTieClip) {
        var tieClip = make_item("tie clip", 0);
        return add_item(cart, tieClip);
    }
    return cart;
}
 
function isInCart(cart, name) {
    for(var i = 0; i < cart.length; i++) { #1
      if(cart[i].name === name)
        return true;
    }
    return false;
}

Inspect the refactored JavaScript listing to compare business-level operations in freeTieClip with the extracted search loop in isInCart. section 8.5

Call graphs, function signatures, and function bodies provide complementary clues about the intended level of detail. As functions become more general, they often become easier to test and unexpectedly reusable; later data-structure changes can also leave many business operations as one-liners. section 8.8 section 9.10

How Grokking Simplicity covers it

How deep it goes
Explains definitions, call-graph clues, extraction, testing, reuse, and a shopping-cart refactoring, while deferring other design patterns.
Examples
Uses JavaScript shopping-cart operations, including freeTieClip, isInCart, remove_item_by_name, and later data-structure changes.
What it assumes
Assumes familiarity with functions and basic code structure while developing the use of signatures, bodies, call graphs, and layers as design clues.
What you can do after
Diagnose mixed abstraction levels with call graphs and refactor low-level loops into clearer, more general functions.
How it connects
Connects straightforward implementation with stratified design, abstraction barriers, minimal interfaces, call graphs, testing, reuse, and data structures.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Grokking Simplicity. The section links point to the parts of the book it draws on.