we have no class (a personal journey of not learning OO)

Disclaimer – this is a commentary about the state of the industry not about my specific place of employment. If it were, I’d have quit and found another job already. I haven’t, therefore it isn’t. QED.

Disclaimer 2 – it got pretty long but I’ve been typing it on and off for a week and I’m not sure much more I can edit it. I hope it gets you thinking.

I feel as if the OO train left and very few people were on it. There I said it. Don’t feel bad if you missed it, I’m pretty sure that I’m not on it either. What the heck am I talking about? Let me explain.

In the beginning

Way back in the dark ages I learned to program (20 years ago now that I stop to think about it). I did this with an Amstrad CPC 6128. It had a built in 3” (not 3.5) floppy drive and I had a hundred programs on disk but every month something magical happened. A magazine would arrive (Amstrad Action) containing 3 or 4 pages of type-ins. These consisted of programs written in Amstrad BASIC which you would read from the magazine and type in by hand.

I was hooked instantly. I’d found a way of controlling my computer and it let me be creative and feel powerful all at the same time. I had no idea what I was doing of course. I was just a fleshy copy-paste mechanism, a form of chinese room.

Skip forward a few years. By now I’ve learned BASIC enough that I can cobble together some rudimentary programs of my own. The trick is to write down what you want to do and figure out the program flow. Then you carve that flow up into chunks and implement the chunks into different areas of memory.

You did this with line numbers. By default line numbers started at 10 and went up by 10 for every new line but you could restart the code at any line number. So you’d implement the drawing routine at 300 and the movement logic and 1000 and before long you had some kind of snake clone. It’s funny, even though these numbers were arbitrary I’d still occasionally be working on a section of program in the early part of the line numbers and accidentally overwrite a later part.

My primary units of program control were if statements, for loops and the dreaded goto. My primary units of data were primitive integer types, strings and arrays (of integers or strings).

The school daze

Fast forward a few more years. Now I’m in high-school and they’re teaching me Pascal. This language is great. There are no line numbers and you refer to functions and procedures by name. Each function can have sub-functions and functions from the outside can’t see those so you can define little areas of your program and focus on just those bits without ever running out of line numbers. If you get a really big program you can define units (but I never really do). 

I almost never use gotos any more but I use select-case statements and call functions a lot. To the for-loop I added a do-while and a repeat-until and of course if was still around. There’s pointers but that stuff is hard. In the data space we got the record which was amazing. Now I could start creating abstractions like person, customer and salesrecord. At least in class, my own programs lacked such sophistication. The most complex program I wrote in this era, a simulation of the classic board-game battleship, used 2 10x10 arrays so I saw no need.

Wander forward in time again. Not too far as I’m gaining momentum now. About half way through high-school. They’re trying to teach me logo (is that not a step down from Pascal?) but I bought a C++ compiler and snuck it into class. Here we can create classes which is this weird organizational thingy where we have a record with some functions on it (to save it to disk or print it on the screen or calculate age or whatever you needed). There’s also these things called objects which are related to classes somehow but I’m not entirely sure how. Apparently global variables are bad so you put them in a class which limit’s their scope (Pascal was big on scope so I know that word). There’s also this thing called inheritance where you can re-use code without copying and pasting but as everything is a function you can get a lot of re-use from having a large mass of parameters (or declaring class variables).

I guess you can tell that OO was completely lost on me. Polymorphism, Inheritance and Encapsulation are really big words that were explained to me in very academic language from very dry books and their meaning and it’s potential impact on me at this stage in my education are completely lost. Effectively I’m writing Pascal code using the C++ language.

Hire education

So I graduate high-school and move to university. Here they teach us assembly (using the IJVM) and functional programming (in gofer of all languages). It was a weird course. There is some C (which I figured was like C++ only far less confusing) and then we were introduced to Java.

This was a language in which everything is an object (or class, I hadn’t yet figured out the difference). If you wanted to write stuff to the screen you might call upon the services of screen object or if you wanted to read from a file then you’d use a file object. 

Lecturers spoke about encapsulation whilst showing a slide of a person object with a private dob field and a public getAge method. They showed us Inheritance hierarchies containing Shape, Circle and Square and how we could add a draw method to each and then draw a list of “shapes” without knowing which we were dealing with. In short very, very simple examples.

Next we were introduced to the UML Class diagrams. To me this notation (which is meant to help people understand object collaborations) just reinforced my views that the whole class thing was an organizational unit. After all what looks easier in a diagram? One box with one label that says “SendNewsletter” or 5 boxes that collaborate (whilst remaining decoupled) to send a branded, personalized monthly newsletter to some subset of users in a database.

In my experience UML makes it too easy for the inexperienced user to ignore complexity and give a complex issue a very shallow treatment. Every box becomes a Facade for a system you don’t bother to draw (and hence is never implemented).

I was in tertiary institutions for a total of 10 years (2 universities and 1 TAFE) and I managed to graduate without understanding Objects in the slightest. The few people that I am still in contact with from those days seem to be in pretty much the same boat. In point of fact, if I look around at the industry at large I don’t see a lot of people engaged in OO Design at all.

The Real World (TM)

Since leaving my structured studies behind and tackling more real world problems I have become more and more aware of the lack of OO knowledge in myself and those around me.

Whenever I’m confronted with an existing scenario and new complexity is introduced I open my tool-box and find find my trusty if-else-statement or switch-statement. After a while this makes my methods disappear off of the bottom of the screen and so I tend to use the handy extract-method refactoring which is built into Visual Studio to break it up a bit.

There are a few people that I’ve worked with (most I’d guess) who think that this is going a bit too far. After all, how are they supposed to figure out what is going on when I keep breaking bits of logic out on their own. Now they have to skip about the class looking at each of the methods in turn and use their highly-prized UML skills to construct a sequence diagram. Or they would if anyone cared about sequence diagrams. More likely they’ll invent their own diagramming technique for program flow and then use that which makes it impossible for them to effectively communicate their findings to anyone else.

People will lose the plot even more if you start adding in collaborating objects into the mix. Now they have to check in different files for what is going on and their home-spun diagrams have stopped making sense even to themselves. They say they’d prefer simplicity and maintainability and yet they refuse to acknowledge the benefits of the SOLID design principles. Oh that’s just for complex stuff, they’ll say. We just get data on and off of forms with some business rules.

I have some news for you. That IS the level of complexity of most systems. Most systems boil down to business rules, data entry and reporting. Most of the other stuff you do is probably to support one of those 3 things.

So why don’t we leverage Object Oriented design and thought processes? I think that Kent Beck and Ward Cunningham summarized what I feel the issue is quite nicely in their paper entitled “A Laboratory For Teaching Object-Oriented Thinking”:

The most difficult problem in teaching object- oriented programming is getting the learner to give up the global knowledge of control that is possible with procedural programs, and rely on the local knowledge of objects to accomplish their tasks.

Kent Beck, Apple Computer, Inc.
Ward Cunningham, Wyatt Software Services, Inc.

From the OOPSLA'89 Conference Proceedings 
October 1-6, 1989, New Orleans, Louisiana 
And the special issue of SIGPLAN Notices 
Volume 24, Number 10, October 1989

The very reason that OO became a dominant paradigm in the first place is because the programmers of the day were unable to keep track of the state of their entire application as those applications got bigger and bigger. To counter this effect they invented a technique for breaking the program into smaller chunks that could each act as a discrete unit and could delegate tasks out to or request required information from other chunks as required. This meant that the programmer no longer needed to know the state of the entire program to make changes. Instead we can work within the confines of a single class and assume that our collaborating classes know their job.

Very few of us seem to have mastered this (and I count myself as one who hasn’t). You can see that when people start writing down call stacks and setting breakpoints in their code. It is fundamental to the way a programmers mind typically works that we have to have all of the information. We cannot let go at the borders of a single object but we have been told that we must. So the solution is to cram as much into a class as we can. After all, a class that does 27 things is more reusable than one which does 2 or 3 right? And I can’t just add new classes to the system, who will update the UML diagram?

It’s interesting to note that some DO seem to get it. Many frameworks and libraries get quite clever and use OO techniques under the covers. These same libraries have a habit of throwing a darned Facade in the way making the end user capable of using them without understanding a single thing about how they work. I guess the smart guys got sick of the rest of us harping on about what we need to do to use their stuff.

Some frameworks get really bold and require us to create our own classes. The usually proscribe 2 or 3 types of class that are necessary (i.e. View, Presenter and Entity) and so we go about creating one of those whenever we really have to. We make those classes work really hard though don’t we? They end up with a lot of variables and methods. In fact they end up like little Pascal programs all on their own.

Is this a problem? I feel like Neo standing before Morpheus in The Matrix wondering whether to take the Red Pill or the Blue Pill. Either the industry is full of people making the same mistakes over and over or I’m fooling myself about our potential effectiveness.

I don’t have all the answers but I’m attacking this one the same way that I usually do. Reading voraciously and trying to absorb so much knowledge that hopefully some small portion will stick. I’m looking for good materials on learning (and teaching) good OO techniques so if you know of any, leave me a comment.

I believe that this isn’t an effective way of learning OO techniques though. They need to be applied to real world problems. Ones that have jagged edge cases.

I think that taking special care of the Single Responsibility Principle and aggressively refactoring code regularly will help. I also think that designing for testability (and in particular Test-First) are also great at making us aware of where the edges of our classes are.

What do you think? Do you do OO? Are those around you baffled by your preference for creating new classes over new methods? Do they see you producing very small units of logic and data and wonder how you keep track of the big picture? Do they ever create a new class to encapsulate an existing concept or do they just create mammoth utility classes with 500 static methods?

The OO train may still be at the station. Have you got your ticket?

learningalt-netcontinuous-improvement
Posted by: Mike Minutillo
Last revised: 27 May, 2011 02:42 PM History

Comments

08 Sep, 2009 01:01 PM @ version 0

I wouldn't say you need to use OO aggressively in your projects, but you do need to understand it properly.

The reason is that OO is a language and shared understanding for communicating with other developers about the design and workings of your code. In fact, it's pretty much the lingua franca of modern software design.

It lets you say, "We've used an Adapter/Facade/Singleton here" rather than trying to come up with a hand-waving explanation of what you're doing that the other person is likely to misunderstand.

If you don't understand OO, you're going to struggle to explain how your code works and why it is built the way it is to other members of your team. You'll also struggle to understand why most modern frameworks are built the way they are, and you'll end up in the land of cargo cult programming.

01 Sep, 2009 06:56 AM @ version 0

Hi,

My favourite OO book is Object Thinking by David West (Microsoft Press).

I have to re-read it to get the concepts back in my head sometimes - I learned to programme in a very similar way to you - but it has had a very positive influence over me.

Regards,
Matt Ellen

Anonymous
Anonymous
29 Aug, 2009 12:31 AM @ version 0

I started programming with C64 basic. Even after so many years I do not do pure OOP. My CSharp classes are more like components. They do have a common base class incase I need to add something that needs to be shared. I don't think I have any classes that are deeper then 3 in inheritance. To bring my components together I use a shared class(DataBus) that contains a dictionary object. With this class I dynamically at runtime compose my application. It's similar to MEF, but not strong typed. So I would say my work is decoupled service component oriented... not pure OOP.
Byron Adams

28 Aug, 2009 10:13 PM @ version 0

I don't necessarily have great advice on how to make it easier (OO always just 'made sense' to me), but I can tell you that all the programmers I truly respect 'get' it. There are plenty of us out there. Like everyone at Google and Microsoft, for instance.

24 Aug, 2009 06:22 PM @ version 0

My favorite quote (re: C++ and OOP) is from Alan Kay: "When I coined the term Object-Oriented Programming, I can tell that C++ is NOT what I had in mind."

One of the problems (I feel) is that many modern languages that call themselves "object-oriented" actually aren't. They really are just "data+operations" languages, and OOP is much more than just "data and operations together".

It makes me curious how many people consider themselves "object-oriented experts", yet have only used C++, C#, or Java. No exposure to Smalltalk, Ruby, Python, etc. One might argue that it becomes quite difficult and brittle to write object-oriented code in a statically-typed language. But that's a different debate for a different time :).

BetaFisch
BetaFisch
03 Jun, 2009 01:22 AM @ version 0

It's as if you read my mind. I started with Fortran then to C. Once I hit C++ I have been trying to forget this procedural stuff and learn/embrace OO. Its not easy. All I can do is read as much as my mind can take and look into as many SOLID open source projects as I can digest. Let me know if you find a better way Neo!

No new comments are allowed on this post.