To succeed in problem solving and programming, you need to learn how to build structure, whether those structures are software or mental models.
This article originally published in my newsletter, The Solution
To Succeed, Build Structure
How do we build structure?
It’s a paradox.
If you want to build a structure, you must learn how.
If you want to learn how, you must build a structure.
According to the authors of Make It Stick, structure building is:
…the act, as we encounter new material, of extracting the salient ideas and constructing a coherent mental framework out of them.
AKA mental models.
Like any construction project, it takes time to build mental models. As Steve McConnell writes in Code Complete:
People who are effective at developing high-quality software have spent years accumulating dozens of techniques, tricks and magic incantations. The techniques are not rules; they are analytical tools.
Time is not the only requirement to become an effective problem solver.
What else does it take?
The authors of Make It Stick distinguish two paths to building mental models: high structure and low structure.
We want to take the former route because high structure-builders:
… develop the skill to identify foundational concepts and their key building blocks and to sort new information based on whether it adds to the larger structure and one’s knowledge or is extraneous and can be put aside.
High structure-builders see the forest for the trees.
Low structure-builders get lost in the weeds.
How do we become high structure-builders?
Reflection.
“Reflecting on what went right, what went wrong, and how I might do it differently next time helps me isolate key ideas, organize them into mental models, and apply them again in the future with an eye to improving and building on what I’ve learned.”
We want to learn the rules and not the examples.
When we learn by rules, we can apply them to new situations. If we learn by example, we get trapped in the black hole of tutorials and copypasta. Additionally, learning the underlying principles of a concept allows us to more easily and quickly get in a flow state.
As Barbara Oakley writes in A Mind for Numbers:
Once you understand why you do something in math and science, you don’t have to keep reexplaining the how to yourself every time you do it.
Manage Complexity
In Code Complete, Steve McConnell coins the phrase software metaphors and proffers his favorite for development: construction.
Like building a house, we build software.
As in construction, McConnell counsels against reinventing the wheel:
In building a house, you won’t try to build things you can buy already built.
We’re accustomed to this as developers. We rely heavily on libraries, frameworks, and package managers to expedite our workflow. But we can also use “off-the-shelf” mental models, too.
McConnell defines Software’s Primary Technical Imperative as managing complexity and outlines several heuristics to aid us in this endeavor:
-
Find Real-World Objects: This is the ‘by-the-books’ object-oriented approach to software design; in brief:
-
Identify the objects and their attributes (methods and data)
-
Determine what can be done to each object
-
Determine what each object is allowed to do to other objects
-
Determine the parts of each object that will be visible to other objects—which parts will be public and which will be private
-
Define each object’s public interface
-
-
Form Consistent Abstractions: Abstraction is the ability to engage with a concept while safely ignoring some of its details—handling different details at different levels.
-
Encapsulate Implementation Details: Encapsulation helps to manage complexity by forbidding you to look at the complexity.
-
Inherit When Possible: Inheritance simplifies programming because you write a general routine to handle anything that depends on an object’s general properties and then write specific routines to handle specific operations on specific kinds of objects.
-
Hide Secrets: Hide complexity so that your brain doesn’t have to deal with it unless you’re specifically concerned with it. Hide sources of change so that when change occurs the effects are localized
-
Identify Areas Likely to Change: Accommodating changes is one of the most challenging aspects of good program design. The goal is to isolate unstable areas so that the effect of a change will be limited
-
Keep Coupling Loose: Make connections as simple as possible.
-
Look for Common Design Patterns: Most problems are similar to past problems, and those can be solved using similar solutions, or patterns.
But.
McConnell cautions us:
If you buy into any single methodology 100 percent, you’ll see the whole world in terms of that methodology.
Or, as Maslow said:
I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail.
This is The Law of the Instrument.
It’s a common anti-pattern in software development.
So common it’s referred to as The Golden Hammer.
In AntiPatterns, the authors define this phenomenon as “a familiar technology or concept applied obsessively to many software problems”.
We need more than hammers to build our structures.
Build a Structure Building Habit
If you really want to build a structure, stack your habits.
In Atomic Habits, James Clear outlines a formula for forming habits, asking us to fill-in-the-blanks in this sentence:
I will [BEHAVIOR] at [TIME] in [LOCATION].
Just like Software’s Primary Technical Imperative, we need to manage complexity and be specific about what we want and how we will achieve it.
As Clear explains:
When your dreams are vague, it’s easy to rationalize little exceptions all day long and never get around to the specific things you need to do to succeed.
As in building a structure for learning and software, we can also build structure for habit formation. Clear defines this as habit stacking and outlines a formula:
After [CURRENT HABIT], I will [NEW HABIT].