{"id":21899,"date":"2017-01-27T10:00:49","date_gmt":"2017-01-27T15:00:49","guid":{"rendered":"https:\/\/simpleprogrammer.com\/?p=21899"},"modified":"2023-02-13T21:58:14","modified_gmt":"2023-02-14T02:58:14","slug":"respecting-abstraction","status":"publish","type":"post","link":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/","title":{"rendered":"Respecting Levels of Abstraction"},"content":{"rendered":"<p><a href=\"https:\/\/simpleprogrammer.com\/better-software-engineer-tips\/\">As software developers, we get to improve<\/a> by learning many good practices which we strive to apply in our code.\\n\\nFor instance, we learn the importance of good naming of variables and functions, encapsulation, class cohesion, the usage of polymorphism, concision, readability, code clarity, expressiveness, and many other principles.\\n\\nIf you consistently deploy all of these practices, you&#8217;re in fact doing one thing: <strong>respecting levels of abstraction<\/strong>. As we\u2019ll see in greater detail in this article, an abstraction is characterized by what a particular piece of code intends to do as opposed to how it is implemented.\\n\\nThis is the <strong>one principle to rule them all<\/strong> because it automatically applies all the best practices mentioned above and more besides. When you follow it, you\u2019ll find yourself naturally writing code with a high-quality design.\\n\\nA good design of code pays off in the long run because well-designed and expressive code is <em>manageable.<\/em> It is vital for long-term projects, and for projects with a team of several developers as well as for big-sized industrial ones.\\n\\nThis overarching principle is based on simple notions, but it took me years of practice and study to realize how this is the most central notion of all.\\n\\nTo prove this principle\u2019s key importance, I will define levels of abstraction, show how a lot of best practices of code are equivalent to respecting them, and finally derive a technique for improving the expressiveness of a given piece of code.\\n\\n<\/p>\n<h2>The What and the How<\/h2>\n<p>\\n\\nWhat are \u201clevels of abstraction\u201d in the first place ? This notion is easy to grasp when you look at a call stack. Let&#8217;s take the example of a piece of software dealing with financial products. The user has a portfolio of assets that he wants to evaluate; the value of a portfolio is the sum of the values of all the assets it contains.\\n\\n<img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-21901 aligncenter\" src=\"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/respect_levels_of_abstraction1.png\" alt=\"abstraction\" width=\"443\" height=\"325\" \/>\\n\\nThis call stack can be read from the bottom up in the following way:\\n\\n<\/p>\n<ul>\\n    <\/p>\n<li>To evaluate a portfolio, every asset has to be evaluated.<\/li>\n<p>\\n    <\/p>\n<li>To evaluate a particular asset, say that some type of probability has to be computed.<\/li>\n<p>\\n    <\/p>\n<li>To compute a probability, there is a model that does mathematical operations like +, -, etc.<\/li>\n<p>\\n    <\/p>\n<li>And these elementary mathematical operations are ultimately binary operations sent to the CPU&#8217;s arithmetic and logic unit.<\/li>\n<p>\\n<\/ul>\n<p>\\n\\nIt is natural to think that the code at the top of this stack is <strong>low-level code<\/strong>, and the code towards the bottom is <strong>high-level cod<\/strong>e. But level of what? They are <strong>levels of abstraction<\/strong>.\\n\\nRespecting levels of abstraction means that all the code in a given piece of code (a given function, an interface, an object, or an implementation) is at the same abstraction level. Said differently, abstraction levels are respected if, at a given level, there isn\u2019t any code coming from another level of abstraction.\\n\\nA given level of abstraction is characterized by <strong>what<\/strong> is done in it. For example, at the bottom level of the stack, a portfolio is evaluated. On the next level, assets are evaluated, and so on.\\n\\nWhen we move from a higher level of abstraction to a lower one, the execution of the tasks in the less abstract level is <strong>how<\/strong> we implement the more abstract level. In our example, evaluating an asset is accomplished by computing a probability. We compute a probability (higher abstraction) with elementary mathematical operations (lower abstraction), and so on.\\n\\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-21902\" src=\"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/respect_levels_of_abstraction2.png\" alt=\"abstraction\" width=\"434\" height=\"316\" \/>\\n\\nSo the crucial question to constantly ask yourself when you design or write code is: &#8220;<strong>In terms of what<\/strong> am I coding here ?&#8221;\\n\\n<\/p>\n<h2>One principle to rule them all<\/h2>\n<p>\\n\\nI deem respecting the levels of abstraction to be the <strong>most important principle in programming<\/strong>, because it automatically implies many other best practices, like <a href=\"https:\/\/simpleprogrammer.com\/kiss-one-best-practice-to-rule-them-all\/\">keeping it simple (KISS)<\/a>. Let&#8217;s see how several well-known best practices are just various forms of respecting levels of abstractions.\\n\\n<\/p>\n<h3>Polymorphism<\/h3>\n<p>\\n\\nMaybe the first thing you thought of when reading about abstraction is polymorphism. Indeed, polymorphism involves providing interfaces or abstract classes to manipulate decoupled implementations of a single concept.\\n\\nPolymorphism consists of segregating levels of abstraction.\\n\\nIndeed, for a given interface (or abstract class) and concrete implementation, the base class is <strong>abstract<\/strong> and the implementation is<strong> less abstract<\/strong>, because the base class describes <strong>what<\/strong> it does as an interface, while the implementation code describes <strong>how<\/strong> it does it.\\n\\nNote that the derived class is still somewhat abstract since it is not expressed in terms of 0 and 1, but it is at an inferior level of abstraction compared to the base class. The base class represents <strong>what<\/strong> the interface offers, and the derived class represents <strong>how <\/strong>it is implemented:\\n\\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-21903\" src=\"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/respect_levels_of_abstraction3.png\" alt=\"abstraction\" width=\"444\" height=\"213\" \/>\\n\\n<\/p>\n<h3>Good naming, encapsulation, cohesion<\/h3>\n<p>\\n\\nLet&#8217;s take the example of a class in charge of maintaining a caching of values. This class lets you add or retrieve values of type V with keys of type K.\\n\\nIt is implemented with a map&lt;K,V&gt;:\\n\\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-21904\" src=\"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/respect_levels_of_abstraction4.png\" alt=\"abstraction\" width=\"788\" height=\"263\" \/>\\n\\nImagine now that we want the interface to be able to provide the whole set of results at once. Then we add a method to the interface. How do we name this method ? A first try may be &#8220;getMap&#8221; because it effectively provides the map that associates all the keys to the values in the cache.\\n\\nBut as you might notice, &#8220;getMap&#8221; is <strong>not<\/strong> a <strong>good name<\/strong>. It isn\u2019t a good name because \u2014 at the abstraction level of the caching interface \u2014 &#8220;Map&#8221; is a term of <strong>how<\/strong> (observe that it appears in the bottom part of the diagram), and not <strong>what<\/strong>, so \u201cMap\u201d is not at the same abstraction level as the thing it names. Calling it &#8220;getMap&#8221; would mix several abstraction levels together.\\n\\nA simple fix would be to call it &#8220;getAllValues&#8221; for instance. &#8220;Values&#8221; is a consistent term with the level of abstraction of the caching interface and is therefore a name that is more adaptable than &#8220;Map&#8221;.\\n\\nYou can accomplish <strong>good naming<\/strong> by giving names that are consistent with the abstraction level they are used in. This works for variable names, too. Because naming defines levels of abstraction and is therefore such an important topic, we will have a dedicated post about it at a later stage.\\n\\nBut isn&#8217;t it a violation of encapsulation to provide the map of results to the outside of the class in the first place? Indeed, encapsulation is the restriction of access to implementation data inside an object.\\n\\nActually, the answer depends on whether the very concept of a results container is logically part of the abstraction of the class. If this concept of container is seen as implementation, details then exposing it breaks encapsulation. And if in your design the caching has the responsibility of providing all results at the same time, exposing the concept of container (potentially with read-only attributes) does not break encapsulation.\\n\\nTherefore, breaking <strong>encapsulation <\/strong>means providing information that goes beyond the abstraction level of the interface.\\n\\nNow imagine that we added a new method in the caching class to do some formatting on values:\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/9ab3e4645a061ae09bddc93c93595ddd.js\"><\/script>\\n\\nThis is obviously a bad idea because this class is about caching values, not about formatting them.\\n\\nDoing this would break the <strong>cohesion<\/strong> of the class. In terms of abstraction, even though caching and formatting don&#8217;t have a what-how relationship, they are two different abstractions because they are in terms of different things.\\n\\nSo <strong>cohesion<\/strong> consists of having only one abstraction at a given place.\\n\\n<\/p>\n<h3>Concision, readability, expressiveness<\/h3>\n<p>\\n\\nLet&#8217;s go down to the function (or method) level.\\n\\nTo continue on the financial example, let&#8217;s consider financial indices such as the Dow Jones or the S&amp;P that contain a collection of equities like Apple, Boeing, or Caterpillar.\\n\\nSay that we want to write a function that triggers saving an index in a database after having done some checks on it. Specifically, we want to save an index only if it is valid, which means, say, having an ID, being quoted on a market, and being liquid.\\n\\nA first try for the function implementation could be the following:\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/debfaf3a1d10c5a1be645a68a0d0240d.js\"><\/script>\\n\\nWe could object to this implementation on the grounds that it has a complex Boolean condition that could be grouped and taken out of the function for code <strong>concision<\/strong> and <strong>readability<\/strong>:\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/92228f5b7e45e47809182b7f37884ba0.js\"><\/script>\\n\\nWhen we think about this fix, it is in fact pushing out the implementation of <strong>how<\/strong> an index is considered valid (having an ID, quoted, liquid) and replacing it with <strong>what<\/strong> the save depends on (being valid), which is consistent with the level of abstraction of the save function.\\n\\nAn interesting thing to note at this point is that respecting levels of abstraction goes <strong>beyond<\/strong> the simple concision of code. Indeed, we would still have done this fix <strong>even if being valid only meant having an ID.<\/strong>\\n\\nThis wouldn&#8217;t have reduced the number of characters typed in the code (it would even have slightly increased it), but this would have improved code clarity by respecting levels of abstraction.\\n\\nLast but not least, there\u2019s <strong>expressiveness<\/strong>, which is the focus of my site <a href=\"http:\/\/www.fluentcpp.com\/\">Fluent C++<\/a>.\\n\\nSay that we want to remove some components from the index if they are not valid.\\n\\nA first trial might write a <em>for-loop<\/em> to do this, but the best solution here in C++ is to use the remove_if algorithm of the C++ Standard Template Library (STL). STL algorithms say <strong>what<\/strong> they do, as opposed to hand-made <em>for-loops<\/em> that show <strong>how<\/strong> they are implemented. By doing this, STL algorithms are a way to raise the level of abstraction of the code to match the one of your calling site.\\n\\nI think expressiveness is the primary characteristic to strive for in code. This is particularly true for long-term or industrial-strength projects because expressive code is manageable in that it tells what it means to do.\\n\\nIn expressive code, bugs can be spotted and fixed, new features can be added, and performance can be tuned. By using expressive code, new developers in a project can come up to speed fairly quickly, move forward at a fast pace, and draw satisfaction out of their efforts.\\n\\n<\/p>\n<h2>Transforming obscure code to expressive code: Raising levels of abstraction<\/h2>\n<p>\\n\\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-21910\" src=\"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Obscure-Code-1-1024x576.png\" alt=\"\" width=\"710\" height=\"399\" srcset=\"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Obscure-Code-1-1024x576.png 1024w, https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Obscure-Code-1-300x169.png 300w, https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Obscure-Code-1-768x432.png 768w, https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Obscure-Code-1.png 1280w\" sizes=\"auto, (max-width: 710px) 100vw, 710px\" \/>\\n\\nUnfortunately, all the code out there is not expressive. For instance, you might have legacy code in your system (as many companies do), which is obscure and wastes developers\u2019 \u00a0energy and motivation.\\n\\nA technique can be derived from respecting the levels of abstraction that allows you to transform an obscure piece of code into an elegant and expressive one.\\n\\nIn many cases of obscure code, lower-level code is in the middle of a higher-level layer of the stack \u2014 levels of abstraction have been disrespected.\\n\\nThe problem is code that describes <strong>how<\/strong> it performs an action rather than <strong>what<\/strong> action it performs. To improve such a piece of code, you need to <strong>raise its level of abstraction.<\/strong>\\n\\nAnd to do so you can apply the following technique:\\n\\n<strong>Identify what things the code does, and put a label on each one of them.<\/strong>\\n\\nThis has the effect of dramatically improving the <a href=\"http:\/\/www.amazon.com\/exec\/obidos\/ASIN\/020161622X\/makithecompsi-20\">expressiveness of the code<\/a>. Let\u2019s illustrate with an example. The following case is written in C++, but the technique is not specific to a language, which is what makes it so powerful.\\n\\nLet\u2019s consider an application where the user can plan a trip across several cities in the country. He would drive straight through from one city to the next if they are close enough (under 100 kilometers, say); otherwise, he would take a break on the road between two cities. The user doesn\u2019t take more than one break between two cities.\\n\\nWe have the planned route in the form of a collection of cities.\\n\\nYou need to write a piece of code that works out how many breaks the driver has to take in order to budget his time effectively.\\n\\nThe existing class, City, represents a city on the route. It can provide its geographical attributes, amongst which are its location, which is represented by a class, Location. And a Location can itself compute the driving distance to any other location on the map:\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/78d71057792706c6f3a0945238e58f4a.js\"><\/script>\\n\\nHere is a possible implementation of a function to determine how many breaks the driver has to take:\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/1d2e6cac317d712022ce55cbb27326e4.js\"><\/script>\\n\\nThis code hasn\u2019t been taken from one codebase in particular, but I have synthesized different techniques I\u2019ve seen in production code or from being advised on the Internet in order to make a realistic example.\\n\\nThe problem with this code is that it doesn\u2019t say what it intends to do; rather, it invites the reader to work out what is happening in it\u2014this code is not expressive. Let\u2019s use the previous guideline to improve expressiveness: that is to say, let\u2019s <strong>identify what things the code does, and replace each one with a label.<\/strong>\\n\\nLet\u2019s start with the iteration logic:\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/8a548463af79355d3f6af480907757b8.js\"><\/script>\\n\\nMaybe you have seen this technique applied before. This is a trick to manipulate adjacent elements in a collection. it1 starts at the beginning, and it2 points to the element right before it1 all along the traversal. To initialize it2 with something, we start by setting it at the end of the collection and check that it2 is no longer at the end within the body of the loop to actually start the work.\\n\\nNeedless to say, this code is not exactly expressive. But now we have determined <strong>what <\/strong>it means to do: it aims to manipulate <strong>consecutive<\/strong> elements together.\\n\\nLet\u2019s tackle the next piece of the code, in the condition:\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/e4c6ef72d724334e8c05bd454079ef25.js\"><\/script>\\n\\nTaken on its own, it\u2019s easier to understand what the code means to do. It determines whether two cities are <strong>farther away<\/strong> than MaxDistance.\\n\\nLet\u2019s finish the analysis with the variable nbBreaks:\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/fba80ff0a667307647e5beeda0704068.js\"><\/script>\\n\\nHere, the code increments the variable depending on a condition. It means to <strong>count<\/strong> the number of times a <strong>condition<\/strong> is satisfied.\\n\\nIn summary, function:\\n\\n<\/p>\n<ul>\\n    <\/p>\n<li>Manipulates <strong>consecutive<\/strong> elements together.<\/li>\n<p>\\n    <\/p>\n<li>Determines if cities are <strong>farther away<\/strong> than MaxDistance.<\/li>\n<p>\\n    <\/p>\n<li><strong>Counts<\/strong> the number of times a <strong>condition<\/strong> is satisfied.<\/li>\n<p>\\n<\/ul>\n<p>\\n\\nOnce this analysis is done, we are really close to turning this obscure code into a meaningful one.\\n\\nThe guideline was to put a label over each of the three things the code does, in order to hide the implementation code. Here, we are going to do the following:\\n\\n<\/p>\n<ul>\\n    <\/p>\n<li>For manipulating <strong>consecutive<\/strong> elements, we can create a component that we would call \u201cconsecutive,\u201d and that would transform a collection of elements into a collection of element <em>pairs,<\/em> each pair having an element of the initial collection and the one next to it. For instance, if route contains {A, B, C, D, E}, consecutive (routes) would contain {(A,B), (B,C), (C, D), (D, E)}. In C++ this is called a range adaptor. You can see my implementation <a href=\"https:\/\/github.com\/joboccara\/ranges\/blob\/4ec506e8e94c68ba1c9137928fcffe620095da3c\/adjacent.hpp#L65\">here<\/a>. One such adaptor that creates a pair of adjacent elements has recently been added to the popular <a href=\"https:\/\/github.com\/ericniebler\/range-v3\">range-v3<\/a> library under the name of <a href=\"https:\/\/github.com\/ericniebler\/range-v3\/blob\/afd3c77dabdf9816ffb7e266a8d9d55b86005834\/test\/view\/sliding.cpp\">sliding<\/a>.<\/li>\n<p>\\n    <\/p>\n<li>For determining whether two consecutive cities are farther away from each other than MaxDistance, we can simply use a function object that we would call <strong>FartherThan<\/strong>. I recognize that C++11 functors have mostly been replaced by lambdas, but this functor here has the slight advantage over a named lambda because it can completely hide the implementation code from the computeNumberOfBreaks function. This can also be achieved with a lambda, but it involves a bit more work (as shown in this <a href=\"http:\/\/www.fluentcpp.com\/2017\/01\/19\/making-code-expressive-lambdas\/\">post about making code expressive with lambdas<\/a>). So here let\u2019s just stick with a functor to get the point across:<\/li>\n<p>\\n<\/ul>\n<p>\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/62d264fee41b1a60d45ae702ea056007.js\"><\/script>\\n\\n<\/p>\n<ul>\\n    <\/p>\n<li>For counting the number of times a condition is satisfied, we can just use the STL algorithm, <strong>count_if.<\/strong><\/li>\n<p>\\n<\/ul>\n<p>\\n\\nHere is the final result, obtained by replacing the code with the corresponding labels:\\n\\n<script src=\"https:\/\/gist.github.com\/joboccara\/d90d98f4e781f4df3ee17cea5b9c96f3.js\"><\/script>\\n\\n(Note: the native count_if C++ function takes two iterators to a begin and end of a collection. The one used here simply calls the native one, with the begin and end of the passed range.)\\n\\nThis code shows what it does and is much more expressive than the initial one. The initial one only told how it did the work, leaving its reader to do the rest of the job.\\n\\nThe above technique can be applied to many <a href=\"http:\/\/www.amazon.com\/exec\/obidos\/ASIN\/0132350882\/makithecompsi-20\">unclear pieces of code<\/a> to turn them into very expressive ones. So next time you stumble upon obscure code that you want to refactor, think about identifying what things the code does and replacing each one with a label.\\n\\nYou\u2019ll be surprised with the results.\\n\\nLabeling focuses on the code itself, though. If you want to learn an interesting methodology to writing clean code, you should definitely check out John\u2019s post about <a href=\"https:\/\/simpleprogrammer.com\/2016\/07\/21\/write-clean-code\/\">how to write clean code<\/a>.\\n\\n<\/p>\n<h2><b>Code for the Long Term<\/b><\/h2>\n<p>\\n\\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-21911\" src=\"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Code-For-The-Future-1-1-1024x576.png\" alt=\"\" width=\"708\" height=\"398\" srcset=\"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Code-For-The-Future-1-1-1024x576.png 1024w, https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Code-For-The-Future-1-1-300x169.png 300w, https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Code-For-The-Future-1-1-768x432.png 768w, https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Code-For-The-Future-1-1.png 1280w\" sizes=\"auto, (max-width: 708px) 100vw, 708px\" \/>\\n\\nFollowing the principle of respecting the levels of abstraction will help you make good choices when designing code. This leads to greater expressiveness and robustness in your code, making it an asset for the future of your codeline and your company, rather than a liability.\\n\\nIf you think about this principle when designing your code and constantly ask yourself the question, &#8220;<strong>In terms of what <\/strong>am I coding here?&#8221;, your code will flow naturally, perform its function well, and be a pleasure to use for the other programmers and developers who have to work with it.\\n\\nAs developers, expressive code is generally what we call \u201cbeautiful\u201d code. And having code that developers find beautiful is something a software company should look for. By <strong>identifying what things the code does and replacing each one with a label<\/strong>, we know how to raise levels of abstraction in order to make code more expressive.\\n\\nAs I indicated throughout the post, many best practices depend on respecting levels of abstraction.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As software developers, we get to improve by learning many good practices which we strive to apply in our code.\\n\\nFor instance, we learn the importance of good naming of variables and functions, encapsulation, class cohesion, the usage of polymorphism, concision, readability, code clarity, expressiveness, and many other principles.\\n\\nIf you consistently deploy all of these practices,&#8230;<\/p>\n","protected":false},"author":1029,"featured_media":21912,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[162232877],"tags":[],"class_list":["post-21899","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-better-software-engineer"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Respecting Levels of Abstraction - Simple Programmer<\/title>\n<meta name=\"description\" content=\"Good design of code pays off in the long run because well-designed code is manageable. To achieve this, one must respect the levels of abstraction.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/simpleprogrammer.com\/respecting-abstraction\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Respecting Levels of Abstraction - Simple Programmer\" \/>\n<meta property=\"og:description\" content=\"Good design of code pays off in the long run because well-designed code is manageable. To achieve this, one must respect the levels of abstraction.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/simpleprogrammer.com\/respecting-abstraction\/\" \/>\n<meta property=\"og:site_name\" content=\"Simple Programmer\" \/>\n<meta property=\"article:published_time\" content=\"2017-01-27T15:00:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-02-14T02:58:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Respecting-Levels-Of-Abstraction.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Respecting Levels of Abstraction\",\"datePublished\":\"2017-01-27T15:00:49+00:00\",\"dateModified\":\"2023-02-14T02:58:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/\"},\"wordCount\":3088,\"commentCount\":1,\"image\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/simpleprogrammer.com\\\/wp-content\\\/uploads\\\/2017\\\/01\\\/Respecting-Levels-Of-Abstraction.png\",\"articleSection\":[\"Better Software Engineer\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/\",\"url\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/\",\"name\":\"Respecting Levels of Abstraction - Simple Programmer\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/simpleprogrammer.com\\\/wp-content\\\/uploads\\\/2017\\\/01\\\/Respecting-Levels-Of-Abstraction.png\",\"datePublished\":\"2017-01-27T15:00:49+00:00\",\"dateModified\":\"2023-02-14T02:58:14+00:00\",\"author\":{\"@id\":\"\"},\"description\":\"Good design of code pays off in the long run because well-designed code is manageable. To achieve this, one must respect the levels of abstraction.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/#primaryimage\",\"url\":\"https:\\\/\\\/simpleprogrammer.com\\\/wp-content\\\/uploads\\\/2017\\\/01\\\/Respecting-Levels-Of-Abstraction.png\",\"contentUrl\":\"https:\\\/\\\/simpleprogrammer.com\\\/wp-content\\\/uploads\\\/2017\\\/01\\\/Respecting-Levels-Of-Abstraction.png\",\"width\":1280,\"height\":720},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/respecting-abstraction\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/simpleprogrammer.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Respecting Levels of Abstraction\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/#website\",\"url\":\"https:\\\/\\\/simpleprogrammer.com\\\/\",\"name\":\"Simple Programmer\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/simpleprogrammer.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"\",\"url\":\"https:\\\/\\\/simpleprogrammer.com\\\/author\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Respecting Levels of Abstraction - Simple Programmer","description":"Good design of code pays off in the long run because well-designed code is manageable. To achieve this, one must respect the levels of abstraction.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/","og_locale":"en_US","og_type":"article","og_title":"Respecting Levels of Abstraction - Simple Programmer","og_description":"Good design of code pays off in the long run because well-designed code is manageable. To achieve this, one must respect the levels of abstraction.","og_url":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/","og_site_name":"Simple Programmer","article_published_time":"2017-01-27T15:00:49+00:00","article_modified_time":"2023-02-14T02:58:14+00:00","og_image":[{"width":1280,"height":720,"url":"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Respecting-Levels-Of-Abstraction.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Written by":"","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/#article","isPartOf":{"@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/"},"author":{"name":"","@id":""},"headline":"Respecting Levels of Abstraction","datePublished":"2017-01-27T15:00:49+00:00","dateModified":"2023-02-14T02:58:14+00:00","mainEntityOfPage":{"@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/"},"wordCount":3088,"commentCount":1,"image":{"@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/#primaryimage"},"thumbnailUrl":"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Respecting-Levels-Of-Abstraction.png","articleSection":["Better Software Engineer"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/simpleprogrammer.com\/respecting-abstraction\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/","url":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/","name":"Respecting Levels of Abstraction - Simple Programmer","isPartOf":{"@id":"https:\/\/simpleprogrammer.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/#primaryimage"},"image":{"@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/#primaryimage"},"thumbnailUrl":"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Respecting-Levels-Of-Abstraction.png","datePublished":"2017-01-27T15:00:49+00:00","dateModified":"2023-02-14T02:58:14+00:00","author":{"@id":""},"description":"Good design of code pays off in the long run because well-designed code is manageable. To achieve this, one must respect the levels of abstraction.","breadcrumb":{"@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/simpleprogrammer.com\/respecting-abstraction\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/#primaryimage","url":"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Respecting-Levels-Of-Abstraction.png","contentUrl":"https:\/\/simpleprogrammer.com\/wp-content\/uploads\/2017\/01\/Respecting-Levels-Of-Abstraction.png","width":1280,"height":720},{"@type":"BreadcrumbList","@id":"https:\/\/simpleprogrammer.com\/respecting-abstraction\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/simpleprogrammer.com\/"},{"@type":"ListItem","position":2,"name":"Respecting Levels of Abstraction"}]},{"@type":"WebSite","@id":"https:\/\/simpleprogrammer.com\/#website","url":"https:\/\/simpleprogrammer.com\/","name":"Simple Programmer","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/simpleprogrammer.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"","url":"https:\/\/simpleprogrammer.com\/author\/"}]}},"_links":{"self":[{"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/posts\/21899","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/users\/1029"}],"replies":[{"embeddable":true,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/comments?post=21899"}],"version-history":[{"count":0,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/posts\/21899\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/media\/21912"}],"wp:attachment":[{"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/media?parent=21899"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/categories?post=21899"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/tags?post=21899"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}