Understanding levels of abstraction can improve your code design

The right level of abstraction in coding helps your code become easier to read/understand and bringing consistency and a logical design to your code.  When you see the right level of abstraction used it intuitively seems right.

Getting the correct level of abstraction is creating a consistent level of design in your code.

Understanding Abstraction

Understanding Abstractions in code design is difficult and takes repeated attempts at learning the concepts.  It’s worth persevering with because abstractions play a key role in code design and two important concepts of good code design

  • Encapsulate what varies
  • Code to an interface not a concrete class

To get started with abstraction in code design and understand the benefits read my blog post below

Why understanding abstractions can help you write better code

The right level of Abstraction

There are many articles/books which mention the concept of getting the level of abstraction right in your when designing code but not many of them explain the concept clearly.

To know if you understand something you should be able to explain it someone (or yourself) in simple terms don’t understand it well enough.

Albert Einstein

I found the concept of the right level of abstraction difficult to understand until I read a great section on exceptions in Code Complete 2.  The chapter described defensive programming and exception handling.  Below I will go through a similar example found in the book.

When you choose to pass an exception to the caller, make sure the exception’s level of abstraction is consistent with the routine interface’s abstraction

If I had a class called car with a method to return the engine size

Class Car{

Public GetEngineSize() throws ArrayTypeMismatchException


Calculating the engine size if all the correct fields aren’t set the code throws an ArrayTypeMismatchException, so the code throws this error.

Now ask yourself the question, is this exception the right level of abstraction?

The calling code doesn’t need to know the detailed error about arrays or type conversion errors.  Instead the calling code is more interested in data is not available.

The right level of abstraction would be improved with this error

Public GetEngineSize() throws CarDataNotAvailable

The calling function level of abstraction is concerned about the Car data, the original error message was at a lower level of detail.  The lower level of detail is the correct error to the concrete car class which implements the code logic, it’s useful to know what type of exception is thrown because it might deal with different errors in different ways.

The interface is a higher level, Engine, wheels, colour.  Classes using the interface are only interested in problems with the data, not the actual error which caused the problem.

The benefits of getting the right level of abstraction are

  • The code feels right
  • The design of the code is logical and easy to understand
  • Consistency

Why should I care about the level of abstraction

Setting the right level of abstraction is one small part of the process of improving the design of your code to make it easier to maintain in the future.

Finding the right level of abstraction for your code is often done after the initial code has been written.

Creative writers have to edit their first draft, advice to writers is to give themselves permission to write a bad first draft.

Writing code is similar because the first draft of code is focused on getting the code working, delivering the required functionality.  Designing good code is an emerging process, which I discuss in this blog post

Unit tests are a vital part of emerging code design

Developers should refactor their code after the initial draft.  The initial draft usually gets the code to work (short term goal) further iterations should improve the code by

  • simplify the code
  • reduce complexity
  • Improve readability
  • Improve the naming of classes, methods and variables
  • reduce coupling by creating new classes and methods
  • Setting the right level of abstraction and putting code in the right place

Another similarity with writers emerges because hopefully we are removing unnecessary lines (and methods).  In coding terms fewer lines of code means fewer lines of code to maintain, debug and read.

The refactoring and improving the design of the code is a stage often missed out by many developers.  The code will still work the same so many developers don’t see the value of refactoring and improving the design of the code.

The code working as required is the initial requirement

Refactoring and improving the design fore fills the long term requirements of maintaining code once written, such as

  • Reading/understanding the code
  • Resusing code
  • Easier to debug
  • Easier to extend
  • Reduces the effects of change on the code

If you miss out the refactoring stage you will soon end up creating legacy code and technical debt.  Read the articles below for more information


Good development is as often making lots of small good choices and avoiding making mistakes. Each complex method/class you avoid writing should be replaced with something simple.  Putting code in the right place and getting the level of abstraction correct is one of many small good design choices.

If you add put together lots of good code design choices you will end up with good code.


Why understanding abstractions can help you write better code

I have been a developer for many years, working with APL, Java, Javascript and C# and I considered myself a decent programmer (doesn’t everyone?)

I had read articles on the S.O.L.I.D principles

I had a decent grasp of OO design principles and understanding Polymorphism, encapsulation, abstraction and inheritance.

I used interfaces and abstract classes but it was only recently that I understood some of the benefits of abstraction with regards to code design.

This  understanding has come through reading (re-reading in some instances) various parts of the book mentioned below

  • Code Complete 2
  • Clean Code
  • Head First Design Patterns
  • Design Patterns – Elements of Reusable Object-Orientated Software
  • S.O.L.I.D design principles

Head First Design Patterns mention these design principles, which I found really useful to understand the effects of good OO design

  • Encapsulate what varies
  • Favour composition over inheritance
  • Program to interfaces, not to implementations
  • Strive for loosely coupled design between objects that interact
  • Depend upon abstractions. Do not depend upon concrete classes

Knowledge is like a jigsaw puzzle

I had read some of the material a long time ago, on my recent reading I found my initial understanding of some of the concepts was lacking a bit of understanding.  This isn’t unusual when trying to understand complex and abstract concepts, here is an interesting article on that phenomenon.

When learning new ideas and concepts you can get a partial understanding where bits of it are clear, whilst other areas can be fuzzy.  I view information/ideas as having a 3D property where it suddenly makes sense when you view the information/idea from a different perspective.

This article talks about the metaphor as knowledge as a jigsaw puzzle

Your understanding grows as more pieces of the puzzle fall into place

What is Abstraction?

Before looking at abstraction from a coding point of view what is a general definition of abstraction, Wiki has a few definition


Abstraction in its main sense is a conceptual process by which general rules and concepts are derived from the usage and classification of specific examples, literal (“real” or “concrete”) signifiers

Conceptual abstractions may be formed by filtering the information content of a concept or an observable phenomenon, selecting only the aspects which are relevant for a particular purpose. For example, abstracting a leather soccer ball to the more general idea of a ball selects only the information on general ball attributes and behavior, eliminating the other characteristics of that particular ball

Abstraction – Computer Science

In computer scienceabstraction is a technique for managing complexity of computer systems. It works by establishing a level of complexity on which a person interacts with the system, suppressing the more complex details below the current level

When abstraction proceeds into the operations defined, enabling objects of different types to be substituted, it is called polymorphism. When it proceeds in the opposite direction, inside the types or classes, structuring them to simplify a complex set of relationships, it is called delegation orinheritance.


Code Complete 2 gives a clear definition of what an abstraction is

abstraction is the ability to view a complex operation in a simplified form.  A class interface provides an abstraction of the implementation that’s hidden behind the interface

What is an abstraction?

Abstractions are used regularly in everyday language, we use abstraction when talking about lots of things, such as
  • Chair
  • Table
  • Computer
  • Mobile Phone
These are abstract ideas which everyone understands but people don’t have a mobile phone, they have an exact make of mobile phone but most people don’t talk about the exact type by the abstract type of mobile phone.
Mobile phones have some core data
  • Ringer
  • Screen
  • buttons
  • Mic
  • Speaker
A mobile phone would be a good case for a Abstract class which could be inherited by a real instance which may add more features.

Why is understanding Abstraction important

Abstractions help hide concrete code which can change with abstractions such as interfaces and abstract classes which are less likely to change.

Using abstraction limits dependencies in code, reduced dependency means reducing the effect of change in your code.

Two of the key long term goals for developers when writing code

  1. Increase the readability of the code
  2. Minimise dependencies in code, reducing the effects of change

The two goals will make maintaining the code easier, below I talk how abstraction can help you to achieve those goals.

Junior developers seem reluctant to use abstractions in code because of a mixture of not understanding how abstractions work and because they are focused on getting the code working and bypass the creation of abstractions, which can lead to big complex methods, few classes and no abstractions.

Junior developers are focused on the short term goal of getting the code working with the intent of leaving the design and creation of abstractions until later (later often doesn’t come).

Which leads me to write articles like the two below


Understanding Abstraction

Abstraction is one of the key principles behind many of the OO design principles such as

  • Inheritance
  • Polymorphism
  • Composition
  • Benefits of abstraction
  • Code is easy to understand
  • Manages change and the effect of chnage
  • Creates cohesive code – it finds common fields
  • Create loose coupling

Abstraction refines concepts to their core values, stripping away ideas to the fundamentals of the abstract idea.  It leaves the common details of an idea.

Abstractions make it easier to understand code because it concentrates on core features/actions and not on the small details.

My understanding started to grow whilst reading these two OO design principle

  • Encapsulate what varies
  • Program to interfaces, not to implementations.

The various books and articles concentrated on the benefits of these two design principles I start to understand how abstraction could reduce dependences and the affect of changes on code, you can see I started thinking about whilst writing this article Information Hiding.

How to find abstractions?

In the blog post  How to find classes I talked about how to find classes, finding abstractions is a similar exercise.  Common abstractions are
  • Nouns – things, people, systems
  • Verbs
  • Types
  • Behaviours
  • Is A – Inheritance
  • Has A – Behaviours

Actions/Verbs are often abstractions e.g. Drawing, validating, processing, routing.

When I mention types I am referring to

Abstractions are useful in life

People use abstractions all the time, you often mention 

  • Computers
  • Chairs
  • People
  • Cars

You don’t talk about the distinctive type of car but say car in general and people will understand you what you are talking about.

The same idea can be used in your code design.  You can find a common action like validating, drawing, Updating, exceptions.  The common action will be the interface and the concrete classes can hide behind it.

Exceptions are a good example you have a core exception (the ones lazy programmers throw when they don’t want to specify the exact error) and then distinctive exceptions extend it.

Exception is the abstraction and InvalidPluginExecutionException , NullReferenceException etc are the implementing concrete classes.  


I had some code where which was triggered on the change of state and depending on certain values it would be go a different route, there were lots of different routes

The abstraction was Route, I made this an interface and it was then implemented by many different Routes through the system.  If the users wanted more routes the code was made to encapsulate what varies.  

Half the code used the interface Route, any changes by adding more routes would mean the code which used the interface would need to change or be effected by the change.

Why Abstractions are so important

Abstractions help create well designed code.

The code is easy to understand because if you have captured the right abstractions is obvious what the code is doing.

Abstractions help create loosly coupled code.  The reason is the abstraction acts like a type and encapsulates the potential changes behind the abstract class/interface.  

To understand why this is import you need to understand the statement

code to an interface, not a concrete class.

A classic abstraction is creating a database layer, an abstract class or interface which parts of the code users to interact with the database. The abstract minimises the effects of change because the code which interacts with the interface will not be effected by the implementation/concrete class changing.  It also allows the code to change in the future and more types being added.

Adding more types will not effect any code which interacts only with the interface.

This brings me nicely to the design principle

Encapsulate what varies

Business rules or algorithms are a good example.  When you have a behaviour or type you have an Abstraction.  Using an abstract class will manage the effects of change and create a loosely coupled system which will manage the effect of change.

Understanding abstraction can take time

Abstractions are used everywhere because they make life easier

  • Common language
  • S.O.L.I.D principles
  • Design Patterns
  • Design Principles

It was until I began to understand the terms Encapsulate what varies and Code to an interface that I slowly (very slowly) could see how abstractions made it easier to organise code/reduce dependencies and how abstractions through abstract classes and interfaces helped manage the affects of change.

Change can ripple through poorly designed code because poorly designed code is fragile, you change one part of it and an unrelated part of the code suddenly breaks.  The reason for this sudden breaking is dependency.

Abstractions (interfaces/Abstract classes) reduces dependencies and the abstraction acts as a barrier to dependency and change.

The next stage of my personal appreciation of abstraction was when writing the blog post – How to find classes, the method of looking and finding classes through nouns and types made it easier for me to identify potential abstractions.

Studying design patterns and good code will help you to understand and learn how great code uses abstractions.  The two books below are great books to get started with design patterns, my vote goes to Head First Design Patterns because it’s easier to get started with.


Abstractions are a handy tool to understand when designing your code, it can make maintaining code much easier because you will improve readability and reduce dependencies in the code.

It’s definitely time well spent understanding abstractions in code design and it will make designing code easier.

Understanding abstractions can make you look at your existing code base from a different perspective because the potential abstractions highlight where the code might change in the future and areas of potential refractoring.


How to find classes

This is the 3rd part of my trilogy of blogs on classes and code quality in plugins, the previous two parts are

  1. Are your CRM plugins creating technical debt?
  2. Are CRM Developers are afraid of creating classes?

I have written an increasing number of articles focusing on the quality and design of code, which you can find Hosk’s CRM Developer Articles

To summarise the first blog discusses the effects of creating plugins and putting the code into the plugin.

  • Complex code
  • Hard to read
  • No code reuse
  • Difficult to debug
  • Writing unit tests is hard so most CRM developers don’t bother
  • Creates duplicate code

The second blog post discusses the benefits of creating classes and using abstractions, it allows the developer to manage the effects of change whilst cr

The role of classes

  • Removes duplicate code
  • Modelling real world and abstract ideas
  • Reduces complexity
  • Manages the effects of change
  • Information hiding
  • Create reusable code

The benefits of classes

  • The code is created from many simple classes and methods
  • The code is easy to unit test
  • Well designed classes have minimal dependencies
  • Well designed classes should be able to be reused
  • Classes and method can make the code easier to understand
  • Good abstractions can be used in different projects

You should now be convinced creating classes is the way to go, so how do you find classes

Finding classes

The benefits of creating classes have been outlined above but finding classes and abstractions can be tricky.  Numerous times I have created some initial classes only to find my one class could then be broken into two or three separate classes.

The design of code emerges overtime with unit tests allowing developers to change the code and test it still works.  Development tools can help refactor the code but there is an overhead to changing existing code and tests.

The earlier you can successfully identify classes/abstractions the less time you can spend refactoring your code, so it’s worth improving the methods you use to find classes.

There are some common methods to help developers find classes which I will outline below.

NOUNS = Class, Verbs = Methods

CRM developers usually get a requirements document/functional spec.  It’s good practise to create a use case document to see what steps the end user will go through using the functionality (This will find the different paths through the customization).

The requirements document/use case can be used to find nouns and verbs to help you creates classes and methods.   Nouns give you the classes and Verbs give you the methods.

Nouns – Person/Place/Things
Verbs – Methods/Behavior/action

Using the nouns/verbs method gives you a good start identifying classes but it’s far from fool proof and will miss some classes and create duplicates.

When using this method be aware classes are not always specified as nouns, you may need to look a bit harder.

The nouns/verb method of finding classes and methods is a good start point for finding classes/methods.  When using the process keep in mind you are trying to find abstractions and common functionality in the requirements, design is an iterative process which involves understanding the problem and solution, uncovering more details as you go.

It’s common in use case to use different nouns whilst referring to the same abstraction, so you will find duplicate nouns and part of the process will involve getting rid of duplicates and merging some of the nouns together.

Code Complete 2 gives a clear definition of what an abstraction is

abstraction is the ability to view a complex operation in a simplified form.  A class interface provides an abstraction of the implementation that’s hidden behind the interface

A good way to think about classes as an interface, methods are the actions performed.  Inside a class you have hidden variables.

Finding classes, designing the methods before you start coding helps give a developer a more holistic top down view of the design.  Once a developer starts coding the perspective tends to shift more towards a bottom up approach of the functionality required.


After identifing a list of potential classes a good method to find the relationships between those classes is to do a quick Conceptual object of those classes

Object-modeling technique

This helps to identify the interactions between classes, the goal of this task is to highlight any missing classes.

This will show you the behaviour of the classes and what classes will interact with other.  Some of these behaviours will have been found when you looked at the adjectives in the use case.


It’s interesting to think about the responsibilities your classes are going to have, which class is responsible for certain data

Responsibilities can be

  • Knowledge/state an object maintains
  • Actions/methods an object will perform
  • Services/functionality provided by an object

It can be useful to CRC models

CRC models shows the Colloborators and Responsiblities of a class, below is a useful video


Find Common Functionality

Classes are also in common functionality and actions used by other classes.

It can help to create class diagrams to see the classes and the interactions between classes.  This can help you find missing classes.

The next stage is create the classes, code and unit tests.  Once the code is working you can think about refactoring/tidying the code and thinking about apply SOLID principles

A good way of finding 2 or more classes within one class is to check the class is focused and doing one thing e.g. The Single Responsibility principle.

A quick way to check if a class is doing more than one thing is the name of the class.  The class should clearly describe what it is/what it does.  Badly named classes often are badly named because they are doing more than one thing.

Actions, manager, Super

Class smells

Here is a list of class smells which often indicate the class is doing to much and could be split into more separate classes

  • Difficult to name the class?  This is usually a sign the class is doing more than one thing
  • Cohesive.  Are all class variables used by most methods, do some methods not use certain variables.  A lack of cohesion is usually a sign a class can be broken out.
  • To many methods.  A high number of methods usually means high complexity, indicating the class is a candidate for refactoring to simplify the code
  • Method length (in lines) – a class bigger than 200 or 300 hundred lines is to big

When checking classes you are often checking for cohesion and if the class can be broken into smaller more cohesive classes.

Cohesion when used to describe design can confuse some readers, so here is wiki’s definition of cohesion

In computer programming, cohesion refers to the degree to which the elements of a module belong together.  Thus, it is a measure of how strongly related each piece of functionality expressed by the source code of a software module is.

Cohesion is the concept all the variables and methods in the class fitting together under the name and purpose of the class.  A class should have a single responsibility, a single purpose.  If a class has more than one purpose then it should be split up.


Here is a quick example

ATM Machine

A bank customer must be able to make withdrawals from the ATM machine using their card.  The card must be validated before the ATM will give money.

ATM machine will check the user has at least the amount of money to be withdrawn in the account.

The bank customer can make a balance enquiry.


  • Customer
  • ATM Machine
  • Card
  • money


  • withdrawn
  • check
  • validated

Further reading


From the awesome Bertrand Meyer.  I found the article above very useful

Are CRM Developers are afraid of creating classes?

I have seen lots of CRM code and my initial thoughts are CRM developers don’t seem to create many classes or spend much time designing their code.  In this blog post I will discuss the effects of not creating classes and explain the benefits of classes and abstractions.

Are CRM Developers afraid of creating classes?

The problem seems to be self reinforcing.  Previous CRM projects contain few classes and most of the code exists in the plugin, this sets an unspoken standard which encourages developers to not create classes.

This is a mixture of a safety in numbers/wisdom of crowds approach, it could be seen as consistency and a standard approach to CRM development is good.  Consistency in CRM development helps developers maintain, debug and extend CRM projects.

In the case of putting code in the plugin and not creating classes I think it’s bad practise and every plugin you add creates more technical debt for the CRM project and CRM projects quickly resemble legacy projects with complex CRM customizations

The end result is complex code doing lots of things and impossible to reuse and extremely difficult to work with (maintain, debug, read, etc).

To not use classes and put all or the bulk of the code in the plugin class

  • makes it impossible to reuse code
  • create complex code which does many things
  • creates duplicate code
  • create code which is hard to understand
  • Code is very difficult to test

CRM plugins are often small, focused code but to not create classes or abstractions is to create a code base technical debt.  This debt is paid back when CRM developers take longer to interact with the code in the future.

Plugins with few or no classes results in each developer creating new code every time because it’s impossible to reuse any of the code in the other plugins.

If CRM developers are not creating classes they are creating legacy code and plugins contain monster methods – Hosk

Boy Scout rule

The focus when creating code should be to keep the quality high, test everything and keep code as simple as possible.

When you create plugins or every time you make a code change you make you should leave the code in better state than you found it.  Why you should write code and customizations like a boy scout

Quality of code is fundamental to the long term success of a CRM project and as soon as you lower your coding standards and let in bad code, it will soon spread Bad code is like a virus, don’t get infected

What is the role of Classes in programming

I advocate no code logic should be added to the plugin class except a call to a class passing in the entity, IOrganisationService, ITracing.

Putting logic in a plugin creates complex code, which is difficult to unit test but there are other reasons to create classes which are listed below

No Duplicate code

Duplicate code is one of the worst code smells and it has multiple bad side effects

  • More code = more potential bugs
  • duplicate code = bug fixing can result in multiple fixes
  • bug fix one set = miss out changing duplicate code, which one is right?

When ever you find duplicate code or are about to create duplicate code, take the opportunity to find the common behaviour and abstract it into a class.  This will enable you to reuse this single piece of code in many places.

Using classes and functions is the primary weapon against duplicate code because you are logically sorting code in logical class/method, which will allow developers to easily find and use it.

Modelling real world and abstract ideas

Classes allow you to model real world objects (account) and abstract concepts (printing, validating).  The benefit is you can split up the code into logical abstractions which give clarity to the intent of the code.

CRM out of the box models plenty of real world objects

  • Accounts
  • Contacts
  • Opportunities
  • Phone Calls

Abstract classes

  • Security role
  • Solution
  • Behaviours

You can create classes to model behaviours, this could be things like validating, printing, logging.  These behaviours can be use in composition and used in multiple classes.  The benefit of modelling behaviours is reuse

  • Create abstract objects
  • Create real world objects

Reduce complexity

Classes reduce complexity by splitting code into abstract or logical sections.  The term abstract can be confusing, instead replace it with logical groups.  Splitting code into logical groups organises the code into smaller/reusable sections.

Breaking the code into classes creates cohesive code and reducing dependencies between classes.

Creating well named classes with well named methods reduces complexity and makes the code using those methods and classes easier to read/understand.

Creating classes and methods allows you to create descriptive methods, e.g. call the a print method is easier to understand than reading all the lines of code needed to print.  At a high level you might not need to know all the details of printing.

Manage the effect of change

Classes help reduce the effects of change by removing dependencies between classes (assuming the classes are well designed).  Using abstract classes can remove the effects of change on the code using the abstract classes.

Well designed code can make it easy to add new types by encapsulating what varies and programming to interfaces.  Adding a new type should not effect the other types or the code using the abstract class.

Managing the effects of change can reduce dependences and stop changes in code unexpectedly breaking other parts of the system.  You could rename this to limiting the effects of change by reducing the ripple effect change has on badly designed code.

Information hiding

Read my blog post Good coding practices – Information hiding

hold data instead of lots of parameters

You can structure classes to hold the data instead of passing lots of variables between methods.  This makes the code easier to understand and interact with.

Create reusable code

Many CRM projects I have worked on/inspected have had almost no code reuse partly due to the lack of classes created.  Part of the reason is attitude, CRM developers don’t view creating reusable code as a priority.

CRM organised internal entities to make it easier to understand how it works.  If we take security roles as an example.

The security role entity contains the main privileges which have a value of TRUE or FALSE and one of the four access levels Global, Business Child, Business unit, user.

Every time we add a new entity, we can set privileges for Create, Read, Write, Delete, Append, Append To, Assign, Share.

Whilst thinking about the example above I would except Privilege to be a separate class but we can see understanding the data in this structure is easier.

The benefits of designing classes 

The clean coder has a good change on classes which talks about change isolating change

Needs will change, therefore code will change. We learned in OO 101 that there are concrete classes, which contain implementation details (code), and abstract classes, which
represent concepts only. A client class depending upon concrete details is at risk when those details change. We can introduce interfaces and abstract classes to help isolate the impact of those details.

Abstraction and modularity allows developers to work on separate parts of a system without having a detailed knowledge of the whole system.

Plugins allow developers to create new plugins without affecting other plugins.  The crm dev needs to check there are no other plugins being triggered on the same entity.  Good design of the code is based on on the plugin interface and not the concrete class e.g. your plugin.

Well designed classes have many benefits

  • The code is created from many simple classes and methods
  • The code is easy to unit test
  • Well designed classes have minimal dependencies
  • Well designed classes should be able to be reused
  • Classes and method can make the code easier to understand
  • Good abstractions can be used in different projects

Coding to an interface

The benefits of coding to an interface and using classes behind the interface is you limit the effects of change behind the interface.

You can add new types behind the interface without affecting any of the code which uses the interface.

A quick example is routing records to different users or teams, for this you could create an interface called Route and then concrete classes will contain the routing details and default value of the users/teams.

Route – Interface

  • RouteToTeam
    • RouteToDefaultTeam
    • RouteToSalesTeam
    • RouteToMarketingTeam
  • RouteToUser
    • RouteToSalesManager
    • RouteToCaseManager

The benefits of coding to an interface and using classes

  1. Any code using the Route interface will be unaware of what specific type of route they are using.
  2. The code calling the interface has no knowledge of what objects, variables are used to route, it calls the Route interface methods
  3. Its easy to add new Routes which will involve changing minimal amount of code
  4. The code using the Interface is decoupled from the concrete classes
  5. The effects of change are restrained by the interface
  6. Easy to test
  7. Selecting the type can be done dynamically at runtime

Dependency Inversion Principle (DIP)

Reading about the Dependency Inversion Principle (DIP) helped me understand abstractions and the benefits of using them.  To remind you what DIP is

Depend on abstractions, not on concretions.

Wiki adds two more points to help understand

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.

I highly recommend you read Uncle Bobs article The Dependency Inversion Principle, where he explains it a lot better than me.

This article DIP in the Wild has a good example of using DIP which helps understand  the concept and it’s usage in developer life.

Abstract ideas can be tricky to understand, to make this easier to understand think of black boxes.

Black boxes are code which works but the user of the black box doesn’t know how the code works inside the black box.  The internal code can change but the consumers of the black box wouldn’t know.

Change has been isolated inside the black box, Interfaces and abstract classes operate as black boxes hiding the change behind them.   Any code which interacts with an interface/abstract class won’t need to change if the internal workings behind the interfaces/abstract classes change.

A good example is using the CRM SDK to interact with the CRM database.  Microsoft can change how the internal workings of the CRM SDK change and can change the CRM database structure (in CRM 2015 they removed CRM database extension table).

Microsoft removed a whole table but CRM developers who used the SDK wouldn’t have noticed any difference (I didn’t notice) but those who developed code/reports directly against the CRM table would suddenly find their code/reports no longer worked when they upgraded to CRM 2015.

The next blog in the series is how to find Classes