What is Abstraction?

You are a person, but clearly you are much more than that. You are good looking and very intelligent and you have a wide range of outstanding skills. You may be great at cooking, an outstanding pianist and perhaps one of the best parents in the world.

However, if I were to interview you for a ColdFusion developer role I would not be very interested in knowing that you make a mean red curry. Although you are a great many things to many people, I would primarily be interested in your skills as a developer. Do you write clean code? Have you used some of the community frameworks? How many years have you been working with ColdFusion? And so on.

In fact my focus would only be on a small part of what you are. I would be focusing on the essential characteristics in you that particularly suited my needs. I would ignore all of the wonderful things about you that are not directly relevant. I have abstracted you into something more generalised and less detailed. You become the abstraction "ColdFusion Developer." Consider the object that represents You:

Then what you would look like after being abstracted into a ColdFusion Developer:

Let’s look at a definition of abstraction from Grady Booch (one of the authors of the Unified Modeling Language):

"An abstraction denotes the essential characteristics of an object that distinguish it from all other kinds of object and thus provide crisply defined conceptual boundaries, relative to the perspective of the viewer."

And a process to find an abstraction from Wikipedia:

"Abstraction is the process of generalization by reducing the information content of a concept or an observable phenomenon, typically in order to retain only information which is relevant for a particular purpose."

Abstractions are intended to simplify things by isolating only what is required for a particular purpose.

So what’s the point?

Hal Helms has written a good article on abstraction, and in it he writes:

"But people engaged in application design too often mistake their mission: they think they’re writing code instead of designing abstraction layers. Thus, they concentrate on the implementation and neglect to abstract the details into a simpler interface."

What Hal is saying is that we need to stop focusing on the how we implement each particular function, and instead spend more time identifying generalised and simplified sets of functions to use in our components.

This is a very important idea – so let’s work through an example through two different views; Tony, who does not use abstractions and Jennifer who makes use of abstractions.

The Task

You are given a query which needs to be saved to one of several file formats: An XML file, a comma separated file and a tab delimited file. Your task is to design the components required and the corresponding functions, and not worry about actual implementation at this stage.

Let’s start with Tony, who does not have any familiarity with abstractions. Keep in mind that Tony is an excellent developer who has come from a non object oriented background, so his solution is likely to be good, but without any particular focus on abstractions.

Abstractions; why bother?

Hi, I’m Tony. I have never thought about abstractions during my development. I don’t really understand what that they are, but at the same time I have never really had a problem.

So here’s how I would solve the task – with a QueryToFile.cfc.

To use this in code you would have something like:

<cfset queryToFile = createObject("component","QueryToFile").init()>
 
<cfif fileType eq "xml">
	<cfset queryToFile.saveQueryToXmlFile(myQuery,myFile)>
<cfelseif fileType eq "csv">
	<cfset queryToFile.saveQueryToDelimitedFile(myQuery, COMMA_CHAR, myFile)>
<cfelseif fileType eq "tab">
	<cfset queryToFile.saveQueryToDelimitedFile(myQuery, TAB_CHAR, myFile)>
<cfelse>
	<cfoutput>Unknown file type</cfoutput>
</cfif>

So what I have here is my QueryToFile.cfc and you just call whichever function you require – easy, simple and works!

Abstractions; make me sound smart!

Hi, I’m Jennifer. I like Tony’s solution, but I have recently begun exploring abstractions and have come up with another approach.

Firstly I can see that we need to

a) Write a query to an XML file, and

b) Write a query to a comma separated file

c) Write a query to a tab separated file.

Well, these are all writing queries to files, so perhaps I can generalise this idea to say that these are all Query File Writers. Also, (b) and (c) are both delimited files, so I can generalise this idea to say that these two are Delimited Query File Writers, however this is just a more specific version of the Query File Writer idea.

So what does the generalised Query File Writer do? Well, in its simplest form, it will just take a query and write to a file, so I would perhaps write my Query File Writer as follows:

This is an abstraction, because it extracts the essential features of what the writers need to do in this case – convert a query to a file.

However this doesn’t help us much on its own because at some point we need to indicate if we are saving to an XML or a delimited file.

We can achieve this by creating two more specific (less generalised) components:

You can see that the XML and Delimited Query File Writers extend the original QueryFileWriter.

To use this in code you would have something like:

<cfif fileType eq "xml">
	<cfset queryFileWriter = createObject("component","XmlQueryFileWriter").init()>
<cfelseif fileType eq "csv">
	<cfset queryFileWriter = createObject("component","DelimitedQueryFileWriter").init(COMMA_CHAR)>
<cfelseif fileType eq "tab">
	<cfset queryFileWriter = createObject("component","DelimitedQueryFileWriter").init(TAB_CHAR)>
<cfelse>
	<cfoutput>Unknown file type</cfoutput>
</cfif>
 
<cfset queryFileWriter.write(myQuery,myFile)>

Actually, it would be better if the creation of the query file writers was in another component, say a "factory" that knows how to make the query file writer objects. This is another abstraction – to generalise the creation of objects:

<cfset queryFileWriter = factory.getQueryFileWriter(fileType)>
<cfset queryFileWriter.write(myQuery,myFile)>

Abstractions do not mean less code

Keep in mind that abstractions do not reduce the amount of code you write. In fact you may need to write more code. At the end of the day, the actual implementation still has to be written, but abstractions just organise this code in a different way.

What are the benefits of abstractions?

Abstractions are about identifying the essential characteristics in things and creating generalisations of those things accordingly. This brings with it a several important benefits:

Easy to revise the implementation

Abstractions hide away how something is implemented – all you need to know about is the public facing functions.

Suppose, for example, that the code to build the XML file above used string concatenation to build the output file. It was then decided to change this process to use ColdFusion’s built in XML capabilities instead. The benefit is that the code that uses components above does not need to be changed.

Same interface, different behaviour

In this situation you implement multiple components that have the same set of functions and parameters, but the underlying behaviour of each is different.

For example, with Jennifer’s QueryFileWriters, both the XML and delimited writers have the same function: write(). When we retrieve the object from the factory, we don’t know which type of QueryFileWriter it is – and it really doesn’t matter at that point in the code. All that matters is that it has a write() function which takes a query and filename as parameters.

Reduce complexity

Abstractions are intended to provide you with the essential functions that you need to get the task done. As a user of the abstraction, you only need to learn the functions the abstraction provides and do not need to be concerned with the complexity of detail that may lie beyond.

Where to from here?

Thinking in a more abstract way is not easy. Abstractions are often not very clear – particularly when a non abstract solution is staring you in the face. I believe the best way to get started with abstractions is by studying design patterns. They will set your brain on the right path to seeing what abstractions really look like.

Good luck!

This entry was posted in OOP and tagged , . Bookmark the permalink. Both comments and trackbacks are currently closed.

21 Comments

  1. Sami Hoda
    Posted November 16, 2007 at 4:06 pm | Permalink

    Nice post.

  2. Posted November 16, 2007 at 4:52 pm | Permalink

    Very nice explanation. Thanks.

  3. Posted November 20, 2007 at 4:20 am | Permalink

    If you would like to read more, you may like to take a look at these other articles:

    Wikipedia – Abstraction
    http://en.wikipedia.org/wiki/Abstraction

    Abstractions by Hal Helms
    http://coldfusion.sys-con.com/read/48230_p.htm

    Abstraction, Encapsulation, and Information Hiding by Edward V. Berard
    http://www.toa.com/pub/abstraction.txt

    What is abstraction? by Alex Mueller
    http://muellerdesigns.net/DasBlog/PermaLink,guid,f8b83896-31f3-47aa-98a9-ea3d77dd9f66.aspx

  4. Posted December 5, 2007 at 9:28 am | Permalink

    Excellent post Kevan!

    I’ve been trying to learn OO over the past few weeks (alongside Model-Glue) as I am about to embark on a huge project and I think the approach will help a lot.

    Your post has really helped me to ‘get’ OOP. I hadn’t really thought about it in terms of abstraction even though a lot of what I’m been looking at is of course doing just that… Thinking about things in this way has really helped me to begin the modelling process for my new project – it makes perfect sense.

    My challenge now is working out how to efficently combine the various abstracted objects I’m designing, though the more I think about it the more I like the service object idea.

  5. Abhishek Kada
    Posted June 1, 2008 at 7:41 am | Permalink

    Nice Post , really Helpful
    Tx

  6. sajid raza khan
    Posted July 11, 2008 at 7:09 am | Permalink

    Awsome KEvan….

    your Explanation is very easy to understand…
    thanks you very much…

  7. Ajit Kumar(SSB)
    Posted December 28, 2008 at 10:28 pm | Permalink

    I can confidently say, it is the best article on Abstration.
    Every OOP programer must read it.

  8. Posted April 1, 2009 at 11:40 am | Permalink

    If only if all developers could think on this level, our worlds wouldn’t be so complex.

  9. suryasasidhar
    Posted August 10, 2009 at 5:15 am | Permalink

    good explanation, thanks for giving such a nice explanation

  10. Deepak Dhyani
    Posted June 15, 2010 at 12:50 pm | Permalink

    Very nice way to explain abstraction. Thanks

  11. Rasik Bihari
    Posted August 4, 2010 at 4:40 am | Permalink

    Indeed a very cool way for a layman to understand.

  12. visitor
    Posted August 24, 2010 at 5:58 am | Permalink

    wow !!! awesome explanation. I was never clear about abstraction until i found this article. Great job. Thanks.

  13. Renuka
    Posted October 5, 2010 at 4:43 am | Permalink

    Great post. It was very helpful. Thanks..

  14. Karthikeyan K
    Posted November 29, 2010 at 10:43 am | Permalink

    This is the best article on abstraction that i have ever read.

    Keep posting like this

    thanks

  15. avdhut
    Posted April 20, 2011 at 9:40 am | Permalink

    Hey this is really great article.

  16. SAM SHKRELI
    Posted May 13, 2011 at 7:49 am | Permalink

    Thanks for sharing great facts.I had carried out a exploration around the challenge and learnt most people will agree with your level.

  17. George
    Posted July 2, 2011 at 2:49 pm | Permalink

    You have given an excellent abstract about abstraction, which is crisp and clear. Thank you for posting this marvellous article.

  18. Suma
    Posted August 5, 2011 at 11:15 am | Permalink

    It is a nice explanation of the concept of abstraction. But your explanation of the advantages of abstraction are not convincing and I don’t agree with.

    “Easy to revise the implementation” -> Your explanation doesn’t convince me why it is easy to revise Jennifer’s classes?. I think it is easy revise Tony’s version too. But there is one advantage with Jennifer. When you revise Jennifer’s class, you are limiting the testing to that particular class and you don’t need to test all other functionality. But in Tony’s class, though you are making changes to a specific function, you will have to test all other functionality too.

  19. Suma
    Posted August 5, 2011 at 11:29 am | Permalink

    Continuation from my previous post…

    Same interface, different behaviour-> Your explanation is not convincing enough to use abstraction. But I think the real advantage with Jennifer design is, if someone else writes a better version of the XmlQueryFileWriter, then it is easy to replace the Jennifers class with the better version. This is offcourse assuming the new version also implements the QueryFileWriter. In this case, the factory creates this new version and the client of the class is unaware that it is using the new version. Thereby eliminating the testing of the client class.

  20. Suma
    Posted August 5, 2011 at 11:45 am | Permalink

    Reduce Complexity -> In what way it reduces complexity?. For me Tony’s version is not complex at all. The logic is in one place. Client just happy to use this class without bothering how Tony has implemented it.
    Jennifer’s design has more classes. It also has a factory.

    For me, this may not be the reason to use Abstraction at all.

  21. Posted August 6, 2011 at 2:11 am | Permalink

    Hi Suma, thanks for taking the time to comment.

    RE: Easy to revise the implementation. Yes, it might be better to say ‘Easy to *replace* the implementation’. As you’ve indicated, if something is abstracted well then the underlying implementation can often be replaced without changing the client code that uses it (as is the case with the QueryFileWriter)

    RE: Same interface, different behaviour. What you’ve said here is pretty much what I was trying to get at. The QueryFileWriter’s interface is just a write(query,filename) method, so as long as an object has this available then the client will generally be indifferent to it’s implementation.

    RE: Reduce Complexity. You are right, I think that in most cases the abstract approach would be more complex to write than the less abstract approach. Here I was really intending that it reduces complexity for the client.

    Your last note raises a good point – should we use abstraction at all? I believe that in some cases it’s not a good idea. If some area of code is unlikely to change then developing an abstraction may take more time and make the code unnecessarily complex.