<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dimitris Platis</title>
    <description>The latest articles on DEV Community by Dimitris Platis (@platisd).</description>
    <link>https://dev.to/platisd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F414582%2F3ea8243a-c1bd-49a3-9da6-1051d82bdc5e.png</url>
      <title>DEV Community: Dimitris Platis</title>
      <link>https://dev.to/platisd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/platisd"/>
    <language>en</language>
    <item>
      <title>Questions YOU should ask when being interviewed</title>
      <dc:creator>Dimitris Platis</dc:creator>
      <pubDate>Sun, 06 Dec 2020 15:38:50 +0000</pubDate>
      <link>https://dev.to/platisd/questions-you-should-ask-when-being-interviewed-57de</link>
      <guid>https://dev.to/platisd/questions-you-should-ask-when-being-interviewed-57de</guid>
      <description>&lt;h3&gt;
  
  
  🔄 Reverse interview questions for Software Engineers
&lt;/h3&gt;

&lt;p&gt;As a Software Engineer, you will go through several interviews in your career. These interviews are typically set up by the potential employers to evaluate your &lt;strong&gt;cultural and technical fitness&lt;/strong&gt; for the role.&lt;br&gt;
From the candidate's point of view, the interview process should not &lt;em&gt;just&lt;/em&gt; be about convincing the employer. That is of course important, however, it should not be your &lt;em&gt;primary&lt;/em&gt; concern unless you are in &lt;em&gt;dire&lt;/em&gt; need of a job. Instead, you should mainly aim to understand what the company works with, how your future teammates operate, what would your development be, and so on.&lt;br&gt;
In other words, you should strive to collect the necessary information which will allow &lt;strong&gt;you&lt;/strong&gt; to assess the technical and cultural suitability of the workplace, its tech and the people in it.&lt;/p&gt;

&lt;p&gt;This is what lead me to create a set of &lt;em&gt;reverse&lt;/em&gt; interview questions.&lt;br&gt;
It is tailored for &lt;em&gt;product companies&lt;/em&gt; and, nonetheless, should be adjusted depending on the setting as well as common sense. Do not try to blindly follow it irrespective of the flow of the conversation, it will just be awkward.&lt;br&gt;
Usually, the interviewer will ask you if you have any questions. This is your chance to start with them, taking into consideration what has already been discussed. No need to ask all of them, or in a particular order either. The &lt;strong&gt;context&lt;/strong&gt; matters!&lt;br&gt;
Most, if not all, questions are open-ended and there is &lt;strong&gt;no "correct" answer&lt;/strong&gt;. More precisely, it is up to you to determine whether the responses satisfy you or not. They are also best-addressed towards individuals involved with development. Do not ask them to a human resources representative or a recruiter. Furthermore, topics that should be covered in every interview, such as benefit package, working hours, salary etc, are not included.&lt;/p&gt;

&lt;p&gt;Overall, personal experience shows these questions make it easier for the interviewers to illustrate in depth &lt;em&gt;how&lt;/em&gt; and &lt;em&gt;what&lt;/em&gt; they work with. Thus far, they have been warmly welcomed and even helped to make a good impression. To say the least, they show the candidate is highly interested and seriously engaged with the process.&lt;br&gt;
More importantly, they enable you, as a Software Engineer, to make well-informed career decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  👩‍💻 Technology stack 👨‍💻
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;What does your technology stack look like?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unless already mentioned, do not forget to ask about programming languages, target operating system, build system or framework, continuous integration and version control software.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  ⚙️ Way of Working ⚙️
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Before a team member starts working on a task, what preparatory work has taken place and what occurs after?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Is the task is written down in some tool and who writes it? Are the tasks derived from a certain set of requirements? Who maintains those requirements? How is traceability ensured? How does the code get peer-reviewed?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Do you have a specific workstation setup in regards to the operating system, the IDE etc?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;In some projects, there is a very well-defined toolset, either due to company guidelines or constraints set by the product domain. Others let developers freely select their own. The latter is not always the better choice since it may be trickier to set up an efficient workflow.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Do you use any containers for your development environment and/or the product?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Using containers makes it easier to get all necessary dependencies, however, may be less flexible.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Do you do pair programming?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Some like pair-programming, some do not. In any case, it is something good to know in advance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How do you ensure knowledge sharing?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Knowledge sharing is important and there are different ways to do it, which may or may not suit you.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Are there usually person-specific tasks or can everything be taken up by anyone?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;This is one of the most important questions for me. I strongly prefer it when everyone can potentially take up any task in the team. However, others like to go deep and specialize in particular sub-domains.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How do you write documentation?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Do they maintain separate documents, is it contained in the code, or is everything self-documenting so there is no need for extra documentation?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How do you work with bugs?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What happens after a bug is discovered? Who usually reports them? How does the emergence of a bug affect their planning?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How do you collaborate with other sites?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;It is often fun to work with colleagues located in different parts of the world, however, this does come with its set of challenges.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;When developing a feature, is the team able to complete it in its entirety?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;This will give you a hint on the &lt;em&gt;size&lt;/em&gt; of the system you will be working with as well as how &lt;em&gt;vertical&lt;/em&gt; the team's domain of responsibility is.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🚅 Agile 🚅
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Do you follow any development methodology, e.g. Agile? If so, how?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Are there daily standups, retrospectives etc?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How do you write tasks?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Are they formulated as user stories? Are they estimated?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How do you release software?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;How often do the releases take place? Are they automatically built and deployed?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🚀 Open source 🚀
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Are you working with open source software? If so, how?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Can they name some open source packages they heavily utilize? Do they upstream any changes? Working with open source can be a valuable experience to carry with to the next job and upstreamed changes offer great visibility. On the other hand, there may be multiple do's and don'ts which can make your life difficult.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🧑‍🤝‍🧑 Relations with customers 🧑‍🤝‍🧑
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How do you collaborate with the customers?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dependencies, communication and collaboration with the customer can vary between projects or even teams in the same project. There are those who enjoy being tightly engaged with the customer while others prefer working more isolated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How smooth do customer deliveries usually go?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Delivering software may require intense collaboration with the customer for the new software to be integrated. Some thrive in such situations and view them as a chance to understand the customer needs better. Others try to avoid them.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🐜 Testing 🐜
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How do you test your code?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Testing and verification may happen at different levels. From unit and integration tests to manual verification and trying things out in hardware or software in the loop rigs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;What test frameworks do you use?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not all frameworks appeal the same to everyone. It is good if you know this in advance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;What are your thoughts on Test Driven Development?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Do they use TDD? If not, why?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🤵 Career path 🤵
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;What do you think I will love about this job?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A good indicator of the extent they have understood your personal goals and style as well as the incentives they have to offer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Where do you see me in 5 years?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A question often addressed to you as an interviewee. Reversing it offers you insights on the available career development paths.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How common is it for employees from this branch/department/team to advance in the higher organizational hierarchy?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Are the ones on the top coming from a different background from yours? Can your loyalty potentially pay off?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  📚 Self-development 📚
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How often do your employees attend conferences, courses, seminars or hackathons?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All companies &lt;em&gt;claim&lt;/em&gt; they care for the personal development of their employees. However few have concrete examples of how they do it. Not all activities will satisfy all engineers, therefore getting input on this can be crucial.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🤝 Collaboration with 3rd parties 🤝
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Do you work with external suppliers? If so, how?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Working with external suppliers can be both fun and/or challenging. It is good if you can find out how this synergy works.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Do you collaborate with academia? If so, how? If not, would you be open to?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Participating in research projects can be interesting and rewarding. However, it may consume a portion of your time and it is not everyone's cup of tea.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  💡 Innovation 💡
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question(s)&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Who comes up with novel features and how?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Does the responsibility for coming up with new features lie with the customer or the company's higher management? Is there an "advanced engineering" team that is tasked with this? Do the employees themselves often propose novel product functionality? Or is it interns that get to experiment with the fun stuff?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;What kind of functionality are you mostly working with, in this branch?&lt;/strong&gt;&lt;br&gt;&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Commodity&lt;/strong&gt; functionality constitutes all functionality that customers typically expect in a product or system, but that is also offered by competing companies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Differentiating&lt;/strong&gt; functionality contains the functionality that makes customers select our products or systems over those from competitors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Innovation&lt;/strong&gt; functionality is experimental functionality. Company experiments with different innovative ideas to identify new future differentiation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;The three types of functionality are found in Jan Bosch's 3LPM. &lt;a href="https://www.researchgate.net/publication/260584542_Achieving_Simplicity_with_the_Three-Layer_Product_Model" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;, &lt;a href="https://janbosch.com/blog/index.php/2017/01/28/9-out-of-10-in-rd-work-on-commodity/" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FcVoKY4Z.png" alt="3LPM Jan Bosch"&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>interview</category>
    </item>
    <item>
      <title>Top 10 practices I hate in C++</title>
      <dc:creator>Dimitris Platis</dc:creator>
      <pubDate>Tue, 29 Sep 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/platisd/top-10-practices-i-hate-in-c-2lo2</link>
      <guid>https://dev.to/platisd/top-10-practices-i-hate-in-c-2lo2</guid>
      <description>&lt;p&gt;After working with C++ for the past years, I have developed some &lt;em&gt;relatively&lt;/em&gt; strong opinions about several things people do, when writing C++. This inspired me to come up with the &lt;strong&gt;TOP 10&lt;/strong&gt; C++ practices, I hate most.&lt;/p&gt;

&lt;p&gt;Before we begin I would like to clarify the following things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Aside of the top 3, all the rest are random order.&lt;/li&gt;
&lt;li&gt;I do not claim these practices to be inherently bad. It depends a lot on the context.
Even so, in some cases I may be just expressing opinions that are more like personal preferences rather than a best practice or a "rule". That being said, if there is a relevant C++ Core guideline I will mention it.&lt;/li&gt;
&lt;li&gt;I will assume there are no technical constraints keeping you from using C++11 or newer.&lt;/li&gt;
&lt;li&gt;The code in the examples may be oversimplified&lt;/li&gt;
&lt;li&gt;The pointed out issues may not be exclusive to C++&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  (10) Not using a range-for loop, when there is a choice
&lt;/h3&gt;

&lt;p&gt;I just don't understand why people still insist on using an incrementing index to iterate over a collection of values instead of a ranged-for loop. That is, if and where there is a choice of course.&lt;br&gt;
I am under the impression this happens because they have been taught for loops that way, in a Programming 101 course long ago and since then they have been instinctively using it. I find ranged-for loops much safer and readable&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// DON'T LIKE&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// DON'T LIKE&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// DO LIKE&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The first two ways of iterating over &lt;code&gt;v&lt;/code&gt; are just... bad! You simply cannot tell what the loop actually iterates over, just "how many times". On the other hand, when you iterate over &lt;code&gt;v&lt;/code&gt; using the ranged-for loop, it becomes immediately clear that you want to do something "for every element &lt;code&gt;x&lt;/code&gt; in &lt;code&gt;v&lt;/code&gt;".&lt;br&gt;
The related C++ Core Guidelines is &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-for-range"&gt;ES.71&lt;/a&gt;, so whenever I see a ranged-for loop not being used during a code review, my next step is to see if it can be used instead.&lt;/p&gt;
&lt;h3&gt;
  
  
  (9) Manual memory management using raw pointers
&lt;/h3&gt;

&lt;p&gt;Despite all the memory leaks and the bad reputation C++ has gotten from them, people just don't learn do they?&lt;br&gt;
They keep using their &lt;code&gt;new&lt;/code&gt; operators and their &lt;code&gt;malloc&lt;/code&gt; with total disregard of smart pointers, RAII and standard library containers. I don't know about you, but I instantly get very suspicious when I see these particular keywords in a modern C++ codebase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: Raw owning pointer of Foo instance&lt;/span&gt;
    &lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// DO LIKE: the Foo instance is owned by a unique pointer&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;f2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_unique&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As a matter of fact, it is very rare I come across good and unavoidable usage of the so-called &lt;em&gt;owning raw pointers&lt;/em&gt; and memory allocation with &lt;code&gt;malloc&lt;/code&gt;. In most cases, it involves the usage of a legacy, or simply bad, API.&lt;br&gt;
Some relevant C++ Core guidelines are &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-ptr"&gt;R.3&lt;/a&gt; and &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-mallocfree"&gt;R.10&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  (8) Misused smart pointers ignoring conventions on lifetime &amp;amp; ownership
&lt;/h3&gt;

&lt;p&gt;From how I see it, the C++ Core guidelines are very clear on when one should use smart pointers.&lt;br&gt;
More importantly, they have very well documented implications on a practical as well as a semantic level in regards to lifetime and ownership.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unique_ptr&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mFoo&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;useFoo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mFoo&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;blop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;private:&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unique_ptr&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mFoo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: Bar does not need to *own* the Foo instance&lt;/span&gt;
    &lt;span class="c1"&gt;// since it does not reseat or destroy it.&lt;/span&gt;
    &lt;span class="c1"&gt;// Additionally, `f` will always exist as long as `b`&lt;/span&gt;
    &lt;span class="c1"&gt;// does, so no need to worry about it going out of scope.&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_unique&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;Bar&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)};&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Typical issues I see is using a smart pointer when a raw, non-owning pointer or a reference would have been perfectly fine. Another one is using shared pointers aimlessly without no particular excuse.&lt;br&gt;
There are many rules from  the C++ Core Guidelines that cover their usage such as &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-smart"&gt;F.7&lt;/a&gt;, &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-unique"&gt;R.21&lt;/a&gt;, &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-smartptrparam"&gt;R.30&lt;/a&gt; etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  (7) Cryptic abbreviations (I don't want to guess what they mean)
&lt;/h3&gt;

&lt;p&gt;Unfortunately, weird abbreviations and acronyms are often part of the culture and one has to guess misunderstand or awkwardly wait until a brave soul inquires about their meaning.&lt;br&gt;
This trait spans across many domains and programming languages, however I have noticed it is especially common in some low end embedded systems. Possibly a trait of C developers? Who knows! 😆&lt;/p&gt;

&lt;p&gt;&lt;a href="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/images/abbreviations-so-busy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/images/abbreviations-so-busy.jpg" alt="many abbreviations? so busy!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I sincerely think it's a very bad behavior we should leave behind as soon as possible. I hope you know there is no&lt;br&gt;
performance boost if you omit the vowels from a variable name, right?&lt;br&gt;
There's a very interesting read on this, by Elon Musk:&lt;br&gt;
&lt;a href="https://gist.github.com/klaaspieter/12cd68f54bb71a3940eae5cdd4ea1764"&gt;Acronyms Seriously Suck&lt;/a&gt;.&lt;br&gt;
Please take it into consideration when writing software!&lt;/p&gt;
&lt;h3&gt;
  
  
  (6) Avoiding to use "auto" (Why sadistically repeat redundant types?)
&lt;/h3&gt;

&lt;p&gt;To tell you the truth, my personal preference is rather on the &lt;em&gt;extreme&lt;/em&gt; side of this. I typically like to use &lt;code&gt;auto&lt;/code&gt; as much as possible. Specifically, I like to use &lt;code&gt;auto&lt;/code&gt; only when I intend to implicitly convert the value on the right side, for example when I want a number with a specific range or a sequence of characters as a &lt;code&gt;std::string&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt; &lt;span class="nf"&gt;getParameter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getFrameBuffer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: Isn't the type super obvious?&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unique_ptr&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_unique&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: Isn't the API descriptive enough?&lt;/span&gt;
    &lt;span class="n"&gt;Parameter&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getParameter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: Even if it wasn't obvious, do you really need&lt;/span&gt;
    &lt;span class="c1"&gt;// to know they are float? You may even end up doing an&lt;/span&gt;
    &lt;span class="c1"&gt;// implicit conversion by mistake&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: Use `auto` or at least an alias for the type!&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getFrameBuffer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You don't have to be as extreme as me. However you should try to avoid repeating type names. And I am not taking just about when using ranged-for loops.&lt;br&gt;
I believe that if you have good API names, then by using &lt;code&gt;auto&lt;/code&gt; your code is not only as understandable, safe, but also easily maintainable across small API changes.&lt;br&gt;
A relevant C++ Core guidelines rule is &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-auto"&gt;ES.11&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  (5) C-style strings and arrays (This isn't 1998 boomer)
&lt;/h3&gt;

&lt;p&gt;Frankly, I get puzzled when I still see these things in modern C++ codebases.&lt;br&gt;
In regards to the C-style arrays, compared to modern standard library containers such as the &lt;code&gt;std::vector&lt;/code&gt; and the &lt;code&gt;std::array&lt;/code&gt;, the difference in performance is usually insignificant. Their elements are even continuously stored in memory so you can always fall back to a pointer.&lt;br&gt;
Same goes for &lt;code&gt;std::string&lt;/code&gt;.&lt;br&gt;
The most important advantage of the modern data structures, aside of making your life easier with their extra features, is the readability and safety they offer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;someLowLevelAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: Use a std::vector or std::array&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;temperatures&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: Just don't, we have beautiful std::string now&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Dimi"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sc"&gt;'D'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'I'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'M'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'I'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;someLowLevelAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// DO LIKE: std::string's are so much easier, safer, fancier&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Dimi"&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;someLowLevelAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In case you "need" to use an C-style array or character pointer because of a legacy or external API that utilizes those types then my suggestion would be to use their modern equivalents and convert to the legacy types &lt;em&gt;only&lt;/em&gt; when you invoke the API that needs them.&lt;br&gt;
Some of the related C++ Core guidelines are &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-ap"&gt;R.14&lt;/a&gt; and &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rstr-string"&gt;SL.str.1&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  (4) Old style casting does look better but let's stop doing it
&lt;/h3&gt;

&lt;p&gt;Ideally, you'd want to avoid casts all together but there are indeed some cases where they are necessary. That being said, what you should definitely &lt;em&gt;not&lt;/em&gt; do is C-style casts.&lt;br&gt;
I like their looks, however, people sometimes tend to do nasty shortcuts using them, so let's just steer clear of them, shall we?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;elements&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: It may look nicer than static_cast but in the name of&lt;/span&gt;
    &lt;span class="c1"&gt;// safety, let's generate warnings with -Wold-style-cast and eventually&lt;/span&gt;
    &lt;span class="c1"&gt;// treat them as errors&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;nullopt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If there's a need to cast, then use a named cast, in which case a &lt;code&gt;static_cast&lt;/code&gt; will be the thing you'd want in most scenaria.&lt;br&gt;
Some cast related C++ Core guidelines include &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-casts"&gt;ES.48&lt;/a&gt; and &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-casts-named"&gt;ES.49&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  (3) Optimizing for "performance" and other excuses to write unmaintainable code
&lt;/h3&gt;

&lt;p&gt;This could be broken down to multiple practices, but the reason behind them can be traced back to the same cause:&lt;br&gt;
Someone using performance optimization as an excuse to write 💩, hard to test and error-prone software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.martinfowler.com/bliki/AntiPattern.html"&gt;&lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/images/antipattern-martin-fowler.png" alt="many abbreviations? so busy!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First of all, &lt;a href="https://platis.solutions/blog/2020/03/30/worse-is-better/"&gt;Worse is better&lt;/a&gt;.&lt;br&gt;
If you want to &lt;em&gt;optimize&lt;/em&gt; something, the first question you need to ask yourself is if this makes sense from a business perspective. Does this bring value to your product or component?&lt;br&gt;
You can discover this by defining one or more quantifiable metrics you want to improve. Then you need to prove the relation of this metric to the perceived value of your product offering. For example, you can set up an experiment with your users to verify if loading a screen 20 milliseconds faster, improves their experience.&lt;br&gt;
After you have formulated your optimization goal and mapped it to the business, you want to measure how does your system&lt;br&gt;
currently perform in regards to the particular metrics. You will end up with a difference, a &lt;em&gt;delta&lt;/em&gt;.&lt;br&gt;
Is this delta considerable enough to warrant action on this?&lt;br&gt;
Is a solution that increases the technical debt of your system, by the business gains?&lt;br&gt;
It may be so, but before you make any decisions that are detrimental to the sustainability of your product, do ask yourselves all these questions. Evaluate the implications before adopting a &lt;em&gt;singleton&lt;/em&gt; pattern, not using modern C++ or utilizing your own implementation of a standard library container just because you think it "suits your needs better" etc. 😅&lt;br&gt;
Naturally, there aren't any C++ Core guidelines for this, but instead, I encourage you to adopt the &lt;a href="https://wiki.c2.com/?RulesOfOptimization"&gt;3 rules of optimization&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  (2) Abstractions leaking details (Coupling to implementation defeats their purpose)
&lt;/h3&gt;

&lt;p&gt;When you come to think of it, it's an oxymoron, isn't it?&lt;br&gt;
An abstraction is meant to, abstract, generalize and be implementation agnostic. Once your abstract class starts giving clear hints on the underlying implementation, then you have essentially lost the benefits of using an abstraction.&lt;br&gt;
You start coding against the interface and not the implementation &lt;strong&gt;only in name and not in practice&lt;/strong&gt;. You violate the &lt;a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle"&gt;Liskov substitution principle&lt;/a&gt;&lt;br&gt;
and therefore you hurt the &lt;em&gt;reusability&lt;/em&gt; of your code.&lt;br&gt;
You claim to follow object oriented programming best practices but... you actually don't. You are simply an imposter! 😱&lt;br&gt;
OK, I may be kidding, but honestly this is an indication of a bad design. If not already, you will face its consequences very soon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Camera&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: cv::Mat of OpenCV is an implementation-specific detail&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Mat&lt;/span&gt; &lt;span class="n"&gt;getFrame&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;HardwareAbstractionLayer&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T LIKE: The layer is NOT agnostic, it implies Arduino is used&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;pinMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;digitalRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;digitalWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are two ways of leaking details through an abstraction.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using implementation specific types for the return value or the function arguments.
For example, having a supposedly agnostic Camera interface with a &lt;code&gt;getFrame&lt;/code&gt; function that returns an OpenCV matrix, does constrain you, well, in using OpenCV matrices for handling the frames! My suggestion would be to use something more generic, such as a vector of bytes or your own implementation-agnostic structure, to be able to switch among implementations that utilize different computer vision libraries.&lt;/li&gt;
&lt;li&gt;Exposing an underlying implementation by having the abstraction mirror its API.
When creating an abstraction, the interface is supposed to &lt;strong&gt;reflect the business value&lt;/strong&gt; its consumer should expect. The abstraction is generalized so that the different concrete classes that specialize it can be utilized seamlessly by the consumers. By creating a very thin and supposedly abstract wrapper over an existing concrete implementation, does not allow you to reap the benefits of using an abstraction, because well, you simply aren't.
Take a look at the &lt;code&gt;HardwareAbstractionLayer&lt;/code&gt; interface. Its name implies that it abstracts hardware, so that higher-level components don't care what kind of platform we are running on. However, if you pay close attention and you are familiar with the &lt;a href="https://en.wikipedia.org/wiki/Arduino"&gt;Arduino&lt;/a&gt; library, you will notice that the various function names imply that Arduino should be used underneath.
As a result, if we wanted to migrate our higher-level components to another platform we would have to adapt the particular hardware drivers to conform to the Arduino API and its constraints. Considering the the Arduino library was first created to be used on 8-bit microcontrollers, having to use that very same API on a &lt;code&gt;x86_64&lt;/code&gt; machine, could be &lt;em&gt;severely&lt;/em&gt; constraining.
Similarly, let's assume we want to do &lt;a href="https://en.wikipedia.org/wiki/Inter-process_communication"&gt;Inter Process Communication&lt;/a&gt; and want to create an implementation agnostic interface that can work on different machines with different IPC mechanisms. If our abstraction simply mirrors a specific API, let's say that of &lt;a href="https://en.wikipedia.org/wiki/D-Bus"&gt;D-BUS&lt;/a&gt;, then once we want to switch to another IPC software, it would be difficult to adjust our supposedly platform independent higher-level components that are consuming the, D-BUS inspired, abstraction.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Overall, if your goal is to create abstractions, then make them abstract. Let them be general. &lt;strong&gt;Don't reflect a particular implementation in the exposed types or functions&lt;/strong&gt;. If you do that you will be doing exactly what you wanted to avoid: Effectively coupling the your high-level functionality to a concrete lower-level implementation.&lt;br&gt;
Naturally, since this is more of a design concern, there isn't an explicit C++ Core guidelines rule about this. However, I do find the following somewhat relevant as they imply that abstract classes should be generic:&lt;br&gt;
&lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ri-abstract"&gt;I.25&lt;/a&gt;, &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-abstract"&gt;C.121&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  (1) Interface names with prefixes (Unnecessary tautology implying bad design)
&lt;/h3&gt;

&lt;p&gt;This is my absolute worst nightmare when it comes to C++!&lt;br&gt;
I am talking about this &lt;code&gt;I&lt;/code&gt; before an abstract class name or an &lt;code&gt;Interface&lt;/code&gt; in the end. Seriously, unless you are developing code for an existing framework that is already using this bad convention then you should simply just &lt;strong&gt;STOP doing this&lt;/strong&gt;. Especially taking into consideration the drawbacks which will be illustrated below, there is literally&lt;br&gt;
NO GOOD ENOUGH reason to put something in a class' name to indicate it is an abstract interface.&lt;br&gt;
The first question is, why should you care?&lt;br&gt;
If you would like to use a class and want to find its abstract base, then simply look at &lt;em&gt;what&lt;/em&gt; it is inheriting. It saves you little to NO TIME to have an &lt;code&gt;I&lt;/code&gt; prefix before it. I have YET to find a good argument on supporting this very bad practice. Every book and article I have seen on the topic,&lt;br&gt;
advises against it, yet in every project I have been in, people just do it.&lt;br&gt;
Overall, the consumer of an abstraction, shouldn't care it's using an abstraction and, similarly, a class that is specializing an interface, typically already knows its parent &lt;em&gt;is&lt;/em&gt; an abstraction.&lt;br&gt;
However, the biggest problem isn't in the name itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// DON'T LIKE: Tautology&lt;/span&gt;
&lt;span class="c1"&gt;// DON'T LIKE: Why should the user of IFoo care it's an interface?&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;IFoo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// DON'T LIKE (and happens too often): No generalization!&lt;/span&gt;
&lt;span class="c1"&gt;// The fact that a particular Camera sensor offers GPS coordinates&lt;/span&gt;
&lt;span class="c1"&gt;// does not mean they all do.&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;ICamera&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;Coordinates&lt;/span&gt; &lt;span class="n"&gt;getGPSCoordinates&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;getFrame&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// DON'T LIKE: What happens when you get another camera?&lt;/span&gt;
&lt;span class="c1"&gt;// ICamera indicates that it should be implemented by Camera&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Camera&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ICamera&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Coordinates&lt;/span&gt; &lt;span class="n"&gt;getGPSCoordinates&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;getFrame&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The biggest problem with prefixing, is its consequences: &lt;strong&gt;Abstractions leaking details&lt;/strong&gt;.&lt;br&gt;
This usually happens when someone first creates a class, let's say &lt;code&gt;Foo&lt;/code&gt;. Then, to conform to the "supposed" object oriented design of their product, they create an &lt;code&gt;IFoo&lt;/code&gt; interface.&lt;br&gt;
There, we have two issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The name of the interface dictates the implementation.
&lt;code&gt;IFoo&lt;/code&gt; indicates that a &lt;code&gt;Foo&lt;/code&gt; concrete class must be used.
But... what happens if we want to have variants, let's say a &lt;code&gt;Bar&lt;/code&gt;?
We would either have to make the naming inconsistent have a &lt;code&gt;Bar&lt;/code&gt; class specializing the &lt;code&gt;IFoo&lt;/code&gt; interface OR do the &lt;em&gt;correct&lt;/em&gt; thing and find out what is the business value we want to get from those two classes. Then we'd reflect that in the interface name. So why not do the correct thing from the beginning?
However, that is not the most important problem. &lt;/li&gt;
&lt;li&gt;The biggest concern is the specialization being created AFTER the abstraction. Ideally, you should &lt;strong&gt;first&lt;/strong&gt; identify what is the business value you want from a class, reflect that to the abstract interface in an implementation agnostic manner and &lt;strong&gt;then&lt;/strong&gt; move on implementing its specializations. If you do this the other way around, you run into the risk of the concrete class &lt;em&gt;influencing&lt;/em&gt; the supposedly generic design of your interface. For example, if you have a camera module that includes a GPS sensor, you naturally create a &lt;code&gt;Camera&lt;/code&gt; class with a &lt;code&gt;getFrame&lt;/code&gt; and a &lt;code&gt;getCoordinates&lt;/code&gt; functions.
If you create an &lt;code&gt;ICamera&lt;/code&gt; class simply by &lt;em&gt;mirroring&lt;/em&gt; the concrete class' API, you have implicitly made the &lt;em&gt;assumption&lt;/em&gt; that "all camera modules must have a GPS sensor too".
An application specific detail just made it into the generic/domain logic!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To summarize, this is why I hate prefixes and suffixes indicating a class is an interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This extra notation is meaningless, redundant and verbose, causing inconsistencies in naming schemes.&lt;/li&gt;
&lt;li&gt;It results in abstractions leaking implementation details. This is observed on two levels:

&lt;ul&gt;
&lt;li&gt;On a semantic level
If you have an &lt;code&gt;IFoo&lt;/code&gt;, then the name implies that the implementation is, well... &lt;code&gt;Foo&lt;/code&gt;! So whoever is using the &lt;code&gt;IFoo&lt;/code&gt; interface, already knows/suspects that &lt;code&gt;Foo&lt;/code&gt; will be used as the implementation.&lt;/li&gt;
&lt;li&gt;On a practical/design level
To be fair, this is not necessarily &lt;em&gt;always&lt;/em&gt; the case but I have seen it happen over and over:
Interfaces that come with a prefix to point out they are interfaces, are typically created &lt;em&gt;after&lt;/em&gt; the concrete implementation. Therefore, they are made to mirror the concrete API. When someone designs the abstraction &lt;strong&gt;after&lt;/strong&gt; the specialization, they are prone to insert implementation-specific details into the design of the supposedly implementation-agnostic API of the abstraction.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Youtube
&lt;/h3&gt;

&lt;p&gt;This article also exists as a video form on YouTube. Feel free to smash the Like button share the video and subscribe&lt;br&gt;
to my channel! 🎉&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/7FrHQssxgvU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>refactorit</category>
      <category>codequality</category>
    </item>
    <item>
      <title>How to write SOLID C++</title>
      <dc:creator>Dimitris Platis</dc:creator>
      <pubDate>Mon, 22 Jun 2020 16:36:29 +0000</pubDate>
      <link>https://dev.to/platisd/how-to-write-solid-c-9gp</link>
      <guid>https://dev.to/platisd/how-to-write-solid-c-9gp</guid>
      <description>&lt;p&gt;We all know, or should know, about &lt;a href="https://en.wikipedia.org/wiki/SOLID"&gt;SOLID&lt;/a&gt;. The question is, do we write C++ according to the SOLID principles?&lt;/p&gt;

&lt;p&gt;The reason for creating this tutorial is that despite a lot of great resources and videos on the SOLID principles, I could not find anything that uses C++ for its examples. Naturally, there isn't any fundamental difference in the SOLID principles themselves when writing in C++. The problem is that, as a C++ developer, when you hear people preaching about a certain way of working and you do not find any examples you can directly relate to, then you may feel reluctant and disconnected.&lt;br&gt;
I find the SOLID principles not only compatible with but also, directly or indirectly &lt;strong&gt;promoted&lt;/strong&gt; by the latest &lt;a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines"&gt;C++ core guidelines&lt;/a&gt;. Therefore, the goal of this tutorial is to show that the SOLID principles are not only relevant to C++, but also very beneficial for software targeting specialized domains such as embedded systems.&lt;/p&gt;

&lt;p&gt;Before moving on to concrete C++ examples on how to write and refactor C++ according to SOLID principles, let's get over the practicalities. What is SOLID?&lt;br&gt;
As I mentioned before there are a lot of great resources online on the principles so I will not expand on this further. Go do your research. I will just quote the Wikipedia introduction on the topic:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;SOLID is an acronym for five design principles intended to make software designs more understandable, flexible, and maintainable. They are a subset of many principles promoted by Robert C. Martin. Though they apply to any object-oriented design, the SOLID principles can also form a core philosophy for agile development.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://en.wikipedia.org/wiki/SOLID"&gt;wikipedia.org/wiki/SOLID&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a nutshell, if you work agile, these are probably some principles you want to look into.&lt;br&gt;
Let's have a deeper look into the SOLID principles.&lt;br&gt;
I will be first running a short introduction and then showing code that does not comply with each principle. In the end, I will offer suggestions on how to refactor it.&lt;br&gt;
I do warn you that the examples will not necessarily be "textbook cases" since I often find them hard to relate to. Instead, I will show you examples inspired by real projects.&lt;/p&gt;
&lt;h3&gt;
  
  
  Single Responsibility principle
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should have only one reason to change&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As the name implies it requires each module, let's say &lt;code&gt;class&lt;/code&gt;, to have responsibility for one and only one &lt;em&gt;purpose&lt;/em&gt;.&lt;br&gt;
To put it differently, the class should only have one "&lt;em&gt;reason&lt;/em&gt;" to change.&lt;br&gt;
By &lt;em&gt;reason&lt;/em&gt;, we may for example mean a change in the specification of -a- requirement.&lt;br&gt;
This principle enables you to write software with high cohesion and robustness since it's not going to be influenced as much as your system evolves. Below are some examples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;PhotoUploader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;PhotoUploader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Camera&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CloudProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cloudProvider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;getImage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;resizeImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;uploadImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Have a look at the &lt;code&gt;PhotoUploader&lt;/code&gt; class.&lt;br&gt;
It &lt;em&gt;depends&lt;/em&gt; on two resources: a &lt;code&gt;Camera&lt;/code&gt; and a &lt;code&gt;CloudProvider&lt;/code&gt;. The dependencies, combined with the name of the class, which implies that it merely uploads photos, should start making you suspicious.&lt;br&gt;
If we move towards the member functions, we can see that the class has more than one responsibility. It takes pictures as well as resizes the images (which depending on the context you may count as one or two purposes already) &lt;strong&gt;and&lt;/strong&gt; uploading images.&lt;br&gt;
The problem with this class is that as soon as we encounter a change in the way that we upload stuff on the internet, the size of the image, or the way we use the camera, this class has to be refactored.&lt;/p&gt;

&lt;p&gt;This was a relatively straight forward example, but let's discuss one with a slightly more &lt;em&gt;subtle&lt;/em&gt; violation of the Single Responsibility principle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;kPrefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user-"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;UserManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;UserManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
   &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kPrefix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kPrefix&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"insert into users (name) values (?);"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;getUsersReport&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"select name from users"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;erase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kPrefix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="p"&gt;};&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For the better or the worse, violations of the single responsibility principle are not always going to be so straight forward.&lt;br&gt;
We have &lt;code&gt;UserManager&lt;/code&gt; which depends on some kind of &lt;code&gt;Database&lt;/code&gt;. It can create users and fetch the users' report.&lt;br&gt;
One could argue, that creating a report may be counted as an additional purpose, but let's be lenient and claim this is considered part of the same &lt;em&gt;responsibility&lt;/em&gt;.&lt;br&gt;
My first and weakest objection would be the inclusion of the SQL query into a higher level class. I would argue that the database schema should not be something that modules except the database should be concerned with. But in any case, let's assume that the &lt;code&gt;Database&lt;/code&gt; class is a very thin wrapper.&lt;/p&gt;

&lt;p&gt;The biggest issue I see is that the &lt;code&gt;UserManager&lt;/code&gt; class is responsible for the formatting of the user name both before inserting it into the database but also when extracting it out.&lt;br&gt;
This effectively means that the &lt;code&gt;UserManager&lt;/code&gt; class becomes responsible for two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Input and output from the database based on a certain schema&lt;/li&gt;
&lt;li&gt;Formatting strings that get stored in the database&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If we get any requirement change in the database schema &lt;strong&gt;or&lt;/strong&gt; the way we are supposed to store names in it, we will have to refactor the class.&lt;br&gt;
Additionally, if we want to reuse &lt;code&gt;UserManager&lt;/code&gt; for a different product, we will either be forced to adopt the same schema and username format or rewrite the class!&lt;br&gt;
My solution to this would be to split things up in classes that have a single purpose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;DatabaseManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;DatabaseManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getAllUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;MyDatabaseManager&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DatabaseManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;MyDatabaseManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getAllUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;UsernameFormatter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;UsernameFormatter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;getReadableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First, we create the &lt;code&gt;DatabaseManager&lt;/code&gt; &lt;em&gt;abstract&lt;/em&gt; class. It offers the capability to add and retrieve users. Its concrete implementations most likely will be using the &lt;code&gt;Database&lt;/code&gt; itself and be responsible for the SQL queries and the project-specific schemas.&lt;br&gt;
Second, I would add a &lt;code&gt;UsernameFormatter&lt;/code&gt; interface. This interface would encapsulate the project-specific way of formatting usernames when importing and exporting from the database.&lt;br&gt;
This would leave us with a &lt;code&gt;UserManager&lt;/code&gt; class, that depends on the &lt;code&gt;DatabaseManager&lt;/code&gt; and &lt;code&gt;UsernameFormatter&lt;/code&gt; interfaces. It is &lt;strong&gt;only&lt;/strong&gt; responsible for handling the high-level user and user report creation.&lt;br&gt;
This would allow the &lt;code&gt;UserManager&lt;/code&gt; class to be reused across projects and also be indifferent to changes in the schema and the format of the database contents.&lt;/p&gt;

&lt;p&gt;Next up? The Open/closed principle!&lt;/p&gt;
&lt;h3&gt;
  
  
  Open/closed principle
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Software entities should be open for extension, but closed for modification&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The open/closed principle is an interesting one, mainly because it evolved through time along with the programming languages. The principle dictates the software modules are &lt;strong&gt;open for extension but closed for modification&lt;/strong&gt;. This allows new functionality to be added without changing &lt;em&gt;existing&lt;/em&gt; source code.&lt;/p&gt;

&lt;p&gt;In practice, the best way to achieve this with C++ is &lt;strong&gt;polymorphism&lt;/strong&gt;. Particularly, with the use of abstract interfaces, we can extend a class and specialize its behavior without changing the interface specification. This principle allows for &lt;strong&gt;reusable&lt;/strong&gt; and &lt;strong&gt;maintainable&lt;/strong&gt; software.&lt;br&gt;
Let's start by looking at a counterexample. Something you should &lt;strong&gt;not&lt;/strong&gt; do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SensorModel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;Good&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;Better&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;DistanceSensor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;DistanceSensor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SensorModel&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mModel&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;getDistance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;SensorModel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Good&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
               &lt;span class="c1"&gt;// Business logic for "Good" model&lt;/span&gt;
           &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;SensorModel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Better&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
               &lt;span class="c1"&gt;// Business logic for "Better" model&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this snippet we have a &lt;code&gt;DistanceSensor&lt;/code&gt; class, that depending on the way we have initialized it, it effectively represents a &lt;em&gt;different&lt;/em&gt; sensor.&lt;br&gt;
Unfortunately, our class design does not allow the behavior to be extended unless we modify the source.&lt;br&gt;
For example, if we want to add a new sensor model, we would have to change the &lt;code&gt;DistanceSensor&lt;/code&gt; class to accommodate the new functionality.&lt;br&gt;
By defining and implementing an interface, we avoid having to alter that &lt;code&gt;switch&lt;/code&gt; statement in a way that can make things &lt;em&gt;quickly&lt;/em&gt; very inconvenient for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;DistanceSensor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;DistanceSensor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;getDistance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;GoodDistanceSensor&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DistanceSensor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;getDistance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;// Business logic for "Good" model&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;BetterDistanceSensor&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DistanceSensor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;getDistance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;// Business logic for "Better" model&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We start by defining what we want a &lt;code&gt;DistanceSensor&lt;/code&gt; to do &lt;strong&gt;in general&lt;/strong&gt;. Remember, a &lt;code&gt;DistanceSensor&lt;/code&gt; is something &lt;strong&gt;generic&lt;/strong&gt;, i.e. it does not have a model, therefore it does not make any sense to have a &lt;em&gt;concrete&lt;/em&gt; instance of it.&lt;br&gt;
Therefore we need to define &lt;code&gt;DistanceSensor&lt;/code&gt; as a &lt;em&gt;pure abstract&lt;/em&gt; class or, an &lt;strong&gt;interface&lt;/strong&gt;, as we would say in other languages such as Java.&lt;/p&gt;

&lt;p&gt;Then, we create &lt;em&gt;specializations&lt;/em&gt; of the interface, for each of the different &lt;code&gt;DistanceSensor&lt;/code&gt; models that we have. Every time we want to add a new sensor, we can create a new child class that implements the &lt;code&gt;DistanceSensor&lt;/code&gt; interface, without changing any of the &lt;em&gt;existing&lt;/em&gt; classes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Liskov substitution principle
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;If &lt;code&gt;S&lt;/code&gt; is a subtype of &lt;code&gt;T&lt;/code&gt;, then objects of type &lt;code&gt;T&lt;/code&gt; in a program may be replaced with objects of type &lt;code&gt;S&lt;/code&gt; without altering any of the desirable properties of that program (e.g. &lt;em&gt;correctness&lt;/em&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This principle requires subclasses to not only satisfy the syntactic expectations but also the &lt;strong&gt;behavioral&lt;/strong&gt; ones, of its parents.&lt;br&gt;
To view things from a different perspective, as a user of a class, I should be able to utilize &lt;strong&gt;any of its children&lt;/strong&gt; that may be passed to me without caring about which particular child I am calling.&lt;br&gt;
This means we have to ensure that the &lt;strong&gt;arguments&lt;/strong&gt; as well as all the &lt;strong&gt;return values&lt;/strong&gt; of the children are &lt;strong&gt;consistent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The code examples illustrate why we must be able to switch or substitute among any of the parent's children, without altering the behavior specified by the parent, in particular, the interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;InertialMeasurementUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;InertialMeasurementUnit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;getOrientation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Gyroscope&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;InertialMeasurementUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="cm"&gt;/**
    * @return orientation in degrees [0, 360)
    */&lt;/span&gt;
   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;getOrientation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Accelerometer&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;InertialMeasurementUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="cm"&gt;/**
    * @return orientation in degrees [-180, 180)
    */&lt;/span&gt;
   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;getOrientation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we have an &lt;code&gt;InertialMeasurementUnit&lt;/code&gt;. The IMU.&lt;br&gt;
The IMU is something generic but specifies a behavior for every class that specializes it. Particularly, it provides its users with the ability to get the sensor's orientation.&lt;br&gt;
The problem begins when different sensors, that is, the different children that implement the interface, return the orientation in &lt;strong&gt;different ranges&lt;/strong&gt;. For example, we have a &lt;code&gt;Gyroscope&lt;/code&gt; that returns an orientation that is always positive, between 0 and 360 degrees, while the &lt;code&gt;Accelerometer&lt;/code&gt; provides an output that can be negative. Something between -180 and positive 180.&lt;/p&gt;

&lt;p&gt;If we had a class that should be able to use &lt;em&gt;any&lt;/em&gt; IMU sensor, that class would read results that should be interpreted &lt;em&gt;differently&lt;/em&gt; depending on the underlying sensor.&lt;br&gt;
Naturally, this would cause problems if not addressed. Architecturally, having a class that is supposed to work with any kind of sensor but actually needs to know what kind of sensor it is, is a definite &lt;strong&gt;smell&lt;/strong&gt;.&lt;br&gt;
In practice, you will see the violation of this principle manifesting itself either in bugs or calls to methods that reveal information about the child specializing the interface. For example a &lt;code&gt;getIMUModel()&lt;/code&gt; function in the abstract interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;InertialMeasurementUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;InertialMeasurementUnit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="cm"&gt;/**
    * Sets the frequency of measurements
    * @param frequency (in Hertz)
    * @return Whether frequency was valid
    */&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;setFrequency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Gyroscope&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;InertialMeasurementUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Valid range [0.5, 10]&lt;/span&gt;
   &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;setFrequency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Accelerometer&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;InertialMeasurementUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Valid range [0.1, 100]&lt;/span&gt;
   &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;setFrequency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As previously mentioned, the child classes have to be &lt;strong&gt;behaviorally consistent&lt;/strong&gt; not just in the return values, but also in the arguments they receive.&lt;br&gt;
Above, we have an example where we must supply a frequency to a child of the &lt;code&gt;InertialMeasurementUnit&lt;/code&gt; class, but different children receive arguments in different ranges. If an invalid argument is supplied, the children may throw an exception, return an error value, or even worse, &lt;strong&gt;behave in an undefined manner&lt;/strong&gt; since the actual sensor would not be able to make sense of the information we pass to it.&lt;/p&gt;

&lt;p&gt;There are two ways to solve this. The first one is to ensure that all children behave consistently. We should be able to substitute &lt;strong&gt;any&lt;/strong&gt; of the children and the classes that use them to be valid.&lt;br&gt;
If that is for serious reasons not possible, we should reflect on whether it makes sense to have the particular class hierarchy. We should ask ourselves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does that interface make sense?&lt;/li&gt;
&lt;li&gt;Must we really enforce the particular child-parent relationship?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second way would be our last resort. We may try to expose as little information about the child as possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;InertialMeasurementUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;InertialMeasurementUnit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="cm"&gt;/**
    * Sets the frequency of measurements
    * @param frequency (in Hertz)
    * @throw std::out_of_range exception if frequency is invalid
    */&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;setFrequency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="cm"&gt;/**
    * Provides the valid measurement range
    * @return &amp;lt;minimum frequency, maximum frequency&amp;gt;
    */&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getFrequencyRange&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Interface segregation principle
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;No client should be forced to depend on methods it does not use&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Moving on, time to contemplate the interface segregation principle.&lt;br&gt;
This principle is rather straightforward and advocates for the creation of small and atomic interfaces.&lt;br&gt;
Specifically, it is better to have &lt;strong&gt;many single-purpose&lt;/strong&gt; interfaces, than a &lt;strong&gt;single&lt;/strong&gt; (or few) &lt;strong&gt;multi-purpose&lt;/strong&gt; ones.&lt;br&gt;
This enables our software to be more reusable and customizable since we don't have to rely upon or implement functionality we don't use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Runtime&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;sendViaI2C&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bytesToSend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;readViaI2C&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numberOfBytesToRead&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;sendViaUART&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bytesToSend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;readViaUART&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numberOfBytesToRead&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;setPinDirection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PinDirection&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;setPin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;clearPin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here's a possible specification of an interface that represents a &lt;em&gt;Hardware Abstraction Layer&lt;/em&gt; for an imaginary microcontroller.&lt;br&gt;
The problem is that this interface will get progressively larger as we want to utilize more and more different parts of the hardware layer.&lt;br&gt;
The larger the interface gets, the less maintainable and reusable it becomes. For example, additional work will be required if we wanted to port it to a different system.&lt;br&gt;
To make things worse, having to implement a large interface means that &lt;strong&gt;you may have to implement things you don't have any use of&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A very characteristic indication the Interface Segregation principle is violated, are child classes with functions that have an empty implementation. The functions are merely there to satisfy the interface specification, not a meaningful specialization.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;SerialManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;registerReceiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;readLine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;MySerialManager&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;SerialManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;registerReceiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;readLine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are more &lt;em&gt;subtle&lt;/em&gt; violations of the Interface Segregation principle.&lt;/p&gt;

&lt;p&gt;Let's assume the &lt;code&gt;SerialManager&lt;/code&gt; interface. It exposes functionality to &lt;em&gt;send&lt;/em&gt;, &lt;em&gt;receive&lt;/em&gt; and &lt;em&gt;subscribe&lt;/em&gt; on keys sent via the serial port.&lt;br&gt;
Then, we have a &lt;code&gt;MySerialManager&lt;/code&gt; implementation that exposes the said functionality.&lt;br&gt;
The problem arises if we take into consideration the different objectives of the classes that &lt;em&gt;utilize&lt;/em&gt; the interface and the ones that &lt;em&gt;implement&lt;/em&gt; it.&lt;br&gt;
Particularly, users of the &lt;code&gt;SerialManager&lt;/code&gt; interface just want to communicate over UART and don't really care about reading the stream directly.&lt;br&gt;
That's why we have the &lt;code&gt;MySerialManager&lt;/code&gt; class there.&lt;br&gt;
How we want these users to operate is by &lt;em&gt;subscribing&lt;/em&gt; on certain keys and then wait for the callback they have registered to be invoked. Additionally, they may opt to &lt;em&gt;send&lt;/em&gt; something back.&lt;/p&gt;

&lt;p&gt;The problem with exposing the &lt;code&gt;readLine()&lt;/code&gt; function &lt;strong&gt;to the users&lt;/strong&gt; of the &lt;code&gt;SerialManager&lt;/code&gt; is that &lt;strong&gt;the interface relays an ambiguous intent&lt;/strong&gt; to its users. Specifically, we give the users two possible ways to do things, but in reality, we only want them to use one!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;SerialClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;SerialClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;registerReceiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;SerialReader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;SerialReader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;readLine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;MySerialManager&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;SerialClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;SerialReader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;registerReceiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;readLine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To comply with the Interface Segregation principle, we can break down the old &lt;code&gt;SerialManager&lt;/code&gt; interface into &lt;em&gt;two&lt;/em&gt; separate ones.&lt;br&gt;
A &lt;code&gt;SerialClient&lt;/code&gt; interface that exposes the functionality of a typical client that wants to communicate over UART by subscribing to keys. This is the interface that other classes most likely want to depend on.&lt;br&gt;
Then we have a &lt;code&gt;SerialReader&lt;/code&gt; interface that only includes the &lt;code&gt;readLine&lt;/code&gt; function. If someone needs to read from serial, they can use that interface.&lt;/p&gt;

&lt;p&gt;Here, you should note that the implementation of the &lt;code&gt;MySerialManager&lt;/code&gt; does not change. It remains the same. The only difference is it now implements &lt;strong&gt;two&lt;/strong&gt; interfaces instead of a single one.&lt;/p&gt;
&lt;h3&gt;
  
  
  Dependency of Inversion principle
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g. interfaces).&lt;/li&gt;
&lt;li&gt;Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Last but absolutely not least, we have the Dependency Inversion principle.&lt;br&gt;
This is one of my favorite principles and goes hand in hand with &lt;a href="https://en.wikipedia.org/wiki/Inversion_of_control"&gt;Inversion of Control&lt;/a&gt; design patterns.&lt;br&gt;
What do the principle's dimensions practically mean?&lt;/p&gt;

&lt;p&gt;In traditional layered architectural styles, the higher-level components which implement the system's application logic, depend on lower-level components that contain the domain logic. Let's delve into a simplified case common in embedded Linux systems:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JZx11F3h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/JH75swU.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JZx11F3h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/JH75swU.jpg" alt="classic layered architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are building middleware that receives signals from the UI and, depending on the business rules, sends messages over serial.&lt;br&gt;
The components that &lt;em&gt;decide what should happen&lt;/em&gt; depending on the received messages are the &lt;strong&gt;high-level&lt;/strong&gt; ones, while the ones responsible for the communication with the UI and the Serial port are the &lt;strong&gt;low-level&lt;/strong&gt; ones.&lt;/p&gt;

&lt;p&gt;As expected from a layered architecture, the business or application logic components would be using the communication components.&lt;br&gt;
In this example, we have &lt;code&gt;DecisionMaker&lt;/code&gt; which uses, or &lt;em&gt;depends&lt;/em&gt; on, the &lt;code&gt;UserInterfaceCommunicator&lt;/code&gt; and the &lt;code&gt;SerialInterfaceCommunicator&lt;/code&gt;.&lt;br&gt;
The problem is that &lt;strong&gt;our application logic is tightly coupled with the domain logic&lt;/strong&gt;. To put it differently, even if our &lt;code&gt;DecisionMaker&lt;/code&gt; operates depending on the business rules, it won't be reusable in different settings for example in different products. That is, unless we use exactly the &lt;em&gt;same&lt;/em&gt; implementation for the user interface and the microcontroller that we talk to.&lt;br&gt;
We don't want to be forced to use the same implementation because our product needs to evolve and differentiate. So how do we fix this?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wfjf4wON--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/3cLUjU9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wfjf4wON--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/3cLUjU9.jpg" alt="Dependency injection layered architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We abstract the &lt;strong&gt;essence&lt;/strong&gt; of the lower-level components in interfaces. Then, we design our higher-level component to depend on those interfaces instead of the implementation.&lt;br&gt;
Now, we can migrate our &lt;code&gt;DecisionMaker&lt;/code&gt; to different hardware as long as the interface to talk with the UI and the Serial port remains the same.&lt;br&gt;
This effectively allows us to create new products or new iterations of the same product, without having to excessively rewrite unrelated software. We can respond to changes in the environment or the customer's needs quickly, in an agile manner.&lt;/p&gt;

&lt;p&gt;This is how it could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;AwsCloud&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;uploadToS3Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;FileUploader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;FileUploader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AwsCloud&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;awsCloud&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;scheduleUpload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We need to schedule the upload of some files to the cloud, let's say &lt;a href="https://en.wikipedia.org/wiki/Amazon_Web_Services"&gt;AWS&lt;/a&gt;, and thus we create the &lt;code&gt;FileUploader&lt;/code&gt; class.&lt;br&gt;
The &lt;code&gt;AwsCloud&lt;/code&gt; class handles uploading to the &lt;em&gt;S3 Bucket&lt;/em&gt; where the term "S3 bucket" is specific to Amazon's Cloud services.&lt;br&gt;
I see two potential violations of the Dependency Inversion principle:&lt;/p&gt;

&lt;p&gt;Our high-level component depends on some lower-level functionality. This is fine.&lt;br&gt;
Unfortunately, we do not depend on an interface, which means that &lt;strong&gt;we are coupled to a very specific implementation&lt;/strong&gt;.&lt;br&gt;
This means, that if we at some point decide to move to a different cloud provider, we will need to reimplement the &lt;code&gt;FileUploader&lt;/code&gt; class, which contains logic that should be pretty much independent. Why should the &lt;code&gt;FileUploader&lt;/code&gt; care about whether we use Azure, AWS, or Google? It just wants to schedule uploads!&lt;/p&gt;

&lt;p&gt;We need to refactor this to decrease coupling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Cloud&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Cloud&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;uploadToS3Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;AwsCloud&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Cloud&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;uploadToS3Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;FileUploader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;FileUploader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cloud&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;scheduleUpload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A bit better now.&lt;br&gt;
The &lt;code&gt;Cloud&lt;/code&gt; interface was now created. It exposes the &lt;code&gt;uploadToS3Bucket&lt;/code&gt; function which does the uploading and &lt;code&gt;FileUploader&lt;/code&gt; depends on it.&lt;br&gt;
However, this is still problematic. We have an abstraction, the &lt;code&gt;Cloud&lt;/code&gt; interface, that... &lt;strong&gt;depends on a detail&lt;/strong&gt;! The &lt;em&gt;S3 Bucket&lt;/em&gt; is being mentioned.&lt;br&gt;
This means that if we were to switch to another cloud provider, we would have to either add another function named after the other provider (thus complicating everything and violating other SOLID principles) or use an inaccurate name.&lt;/p&gt;

&lt;p&gt;Both alternatives bad. &lt;strong&gt;It is not enough to take the header file of a concrete class and create an abstract interface out of it&lt;/strong&gt;.&lt;br&gt;
We need to carefully determine the &lt;strong&gt;purpose&lt;/strong&gt;, or the &lt;strong&gt;capabilities&lt;/strong&gt; we want to offer. Then, name the functions as well as the abstraction itself appropriately. We must decide &lt;strong&gt;names and signatures that do not leak or impose implementation details&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ideally, our design should be specified like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Cloud&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Cloud&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;AwsCloud&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;FileUploader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;FileUploader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cloud&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;scheduleUpload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4nSweGBh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/thHoWI1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4nSweGBh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/thHoWI1.png" alt="SOLID takeaways"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you have some examples of how to apply the SOLID principles in C++, I hope you will go forward and build or &lt;em&gt;refactor&lt;/em&gt; your systems. On a technical level, you should be as agile as you claim your team's or company's processes to be.&lt;/p&gt;

&lt;p&gt;If you feel what you heard does not apply to you, due to domain constraints or because you use a language that is not object-oriented, such as C, you should know that this &lt;em&gt;may&lt;/em&gt; not be true!&lt;br&gt;
From talking and &lt;a href="https://www.embeddedonlineconference.com/session/Best_Practices_for_Developing_Real-time_Embedded_Systems"&gt;watching some pioneers&lt;/a&gt; in the embedded software industry, the &lt;em&gt;spirit&lt;/em&gt; of the SOLID principles is indeed applicable when using C as your programming language. It's primarily the &lt;em&gt;semantics&lt;/em&gt; that change.&lt;br&gt;
I do encourage you to look more into this yourselves.&lt;/p&gt;

&lt;p&gt;That was about it folks. Please don't forget to like and share this tutorial to promote better software.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>oop</category>
      <category>architecture</category>
      <category>refactorit</category>
    </item>
  </channel>
</rss>
