Vlad's Roam Garden

Powered by 🌱Roam Garden

level of abstraction

This is an "Orphan" page. Its core content has not been shared: what you see below is a loose collection of pages and page snippets that mention this page, as well as snippets of this page that were quoted elsewhere.

Referenced in

Clean Code: A Handbook of Agile Software Craftsmanship

The statements within a function should all be written at the same level of abstraction, which should be one level below the operation described by the name of the function. This may be the hardest of these heuristics to interpret and follow. Though the idea is plain enough, humans are just far too good at seamlessly mixing level of abstraction. Consider, for example, the following code taken from FitNesse:

Clean Code: A Handbook of Agile Software Craftsmanship

My goal, at this point, was to create the necessary separation and get the tests to pass. I accomplished that goal easily, but the result was a function that still had mixed level of abstraction. In this case the mixed levels were the construction of the HR tag and the interpretation and formatting of the size variable. This points out that when you break a function along lines of abstraction, you often uncover new lines of abstraction that were obscured by the previous structure.

Clean Code: A Handbook of Agile Software Craftsmanship

Mixing level of abstraction within a function is always confusing. Readers may not be able to tell whether a particular expression is an essential concept or a detail. Worse, like broken windows theory, once details are mixed with essential concepts, more and more details tend to accrete within the function.

Clean Code: A Handbook of Agile Software Craftsmanship

DSLs, when used effectively, raise the abstraction level above code idioms and design patterns. They allow the developer to reveal the intent of the code at the appropriate level of abstraction.

when you develop software you invent a language

Each class and each function add a concept to your language. Every time you create one - either from primitive statements or from other concepts you've already defined - you make your language more expressive. You rise it's level of abstraction.

Clean Code: A Handbook of Agile Software Craftsmanship

Separating level of abstraction is one of the most important functions of refactoring, and it’s one of the hardest to do well. As an example, look at the code below. This was my first attempt at separating the abstraction levels in the HruleWidget.render method.

Clean Code: A Handbook of Agile Software Craftsmanship

The percentFull function is at the wrong level of abstraction. Although there are many implementations of Stack where the concept of fullness is reasonable, there are other implementations that simply could not know how full they are. So the function would be better placed in a derivative interface such as BoundedStack.

Respecting level of abstraction

[[good code/names should be consistent with the level of abstraction they are used in]]

Clean Code: A Handbook of Agile Software Craftsmanship

Now look again. This method is mixing at least two level of abstraction. The first is the notion that a horizontal rule has a size. The second is the syntax of the HR tag itself. This code comes from the HruleWidget module in FitNesse. This module detects a row of four or more dashes and converts it into the appropriate HR tag. The more dashes, the larger the size.

Clean Code: A Handbook of Agile Software Craftsmanship

This change separates the two level of abstraction nicely. The render function simply constructs an HR tag, without having to know anything about the HTML syntax of that tag. The HtmlTag module takes care of all the nasty syntax issues.