The Joys of Reusable Code - The "O" Word

by Bruce Johnson

Published 1998-03-01    Printer-friendly version

As a development system, Clarion offers 3 powerful ways of reusing code. I covered the first, function libraries, in my first article (see Clarion Online, Volume 1, Issue 1). In this article and the next, we'll deal with a far scarier topic - Object Orientated Programming.

I doubt that any word in the history of programming has stirred as many emotions in the hearts of programmers as the phrase "Object Orientated Programming", commonly know as OOP. Bring up the topic of OOP in any user group and there'll be a range of opinions, and emotions - from skepticism to jubilation to outright fear. However, despite lots of publicity, we as programmers seem mostly to be against OOP. I believe this is due mostly to ignorance of the benefits of OOP. In this article I invite you to join me, a new convert to OOP programming, as I explore some complex issues of OOP.

And that is essentially the root of the problem. OOP is perceived to be complex. It uses new terminology, new syntax and requires new design skills. All this new, of course, implies lots of new learning for us programmers. A new learning curve! Moreover, because we're comfortable with the old, because we've reached a position where we're comfortable using procedural programming techniques, we resist the new. Often we hear OOP is better - but is it? And if so, why?

I've discovered recently that OOP isn't nearly as scary as it's made out to be. Sure OOP brings new terminology. Sure it brings some new syntax. But it brings benefits as well. And, in true Clarion fashion, you don't know how easy it is until you try.

Until recently, the benefits of OOP have been somewhat vague to me. The classic case for OOP is that it makes for more reusable code and, hence, fewer bugs. However, Clarion's templates have always provided us with the same benefits, and surely reusable libraries or DLLs are just as effective in reusing code and reducing bugs, aren't they? My answer to this would be almost. Indeed, traditional techniques, for want of a better phrase, deliver almost as much as OOP does. Considering the time and effort involved in learning OOP techniques, are the added benefits worth it?

There are some things that you can do in OOP that can't easily be done in traditional programming. While these new abilities are cool, they don't, in themselves, make all the effort worthwhile. However, I discovered that, in fact, OOP programming is easier than procedural methods. I kid you not. The reason it's easier is because more happens by magic. Let me explain.

Since the earliest days of programming, we've been striving to make programming easier. Why ? Because it means we can do more in less time. I could trot out the old comparisons of Pascal and the like to Assembly Language, or I could use the RAD example: Environments like Clarion make programming easier - and hence faster - than other languages, even visual languages like VB. The bottom line is that OOP, no matter how complicated it appears at first, is just an extension of this trend.

What about templates? Surely they provide a level of code reusability ? Certainly they do. They're one of Clarions strongest pillars, and I believe one of the most unrecognized advances in programming. But templates generate code, and the quality and readability of the code generated is still important. It's important when you try to add code to existing templates, and it's important when you write new ones.

Templates are hard to write. Well, they're not actually as hard to write as they seem, but there is certainly a learning curve involved. Though more people are learning the template language than ever before, it is still considered by many to be a black art. And, to a certain extent, that perception is correct.

Templates can generate OOP code as easily as procedural code (or for that matter, any code). Templates, on their own, are extremely powerful and, as we'll discover, Objects, on their own, are also extremely powerful. Put them together and they're dynamite! Moreover, crucially, OOP templates are easier to write than procedural templates. To push the theory a bit further: It's easier to write templates that write other templates that write OOP code, than to write templates that write other templates that write Procedural code. This is an important benefit I'll discuss more fully in a later article.

I spoke earlier about real benefits of OOP. One of the joys of OOP is discovering these benefits for yourself. However, let me try to point out some of them for you. Maybe it will encourage you to explore this area further.

First, OOP programming requires that you spend more time in the design stage and less in the programming stage. Why is this a good thing? Because you end up with code which is more structured. Not structured in the line-by-line sense, but structured in the what-gets-done-by-whom sense. A well-disciplined programmer will do this anyway, you say. Sure they will. However, the reality is, most of us don't. Rather, we adopt a style of adding. We add more and more functionality, usually by writing more functions. Rarely, if ever, can we make use of existing functions. Moreover, we are unable to meaningfully extend existing functions without breaking other code that relies on those functions. Note: I'm not saying that you can't have good discipline while writing procedural code, but rather that OOP forces this discipline on you.

Second, OOP insists that you document your code more. I mentioned before (and we'll see it again later) that OOP code seems to work a lot more by magic than procedural code. What this means is that it's more difficult to reuse objects unless you have a solid understanding of, or reference to, what they do.

When I was at university, they told us you can remember your own code for about 6 months. That is, if you return within 6 months to something you wrote, you'll be able to remember what it did without documentation. At the time, we felt like we would remember the code forever. With Clarion, because the productivity is so much greater, 6-week-old code is sometimes like a stranger to me. Often I find myself going through my own code, figuring out what I did (and writing lots of comments alongside). With objects, because of the way they work, this period of remembrance is shortened even more, so clear documentation becomes even more important.

When we first started packaging some of our in-house tools for sale as 3rd party products, we realised how next to no documentation existed on these products. And I'm not talking about just comments here - although those are important. What I mean is an up-to-date, written, printable, document, with a technical reference and examples. This is the single most important part of any reusable code but, sadly, it's also the part we did least. So a lot of potentially reusable code got rewritten over and over because first, we didn't know we had it already, and second, we weren't sure if the existing code did exactly what we wanted. When you start using Objects, you'll discover programming is impossible without clear and accurate documentation.

Third, OOP code is easier to extend without breaking the original code. If you look deeply in my Secwin product, you'll see there are in fact 3 login functions. The first was called Login, The second LoginEx and the third LoginText. Actually the first two are simple one liners; they call the third. So why are they still there? Because they make the DLL compatible with apps compiled using earlier versions of Clarion, without the requirement that the actual EXE be recompiled. However, because I'd used the obvious name (Login) first, the naming scheme became more obscure.

I don't want to drop too many buzzwords in this article, but one is appropriate here. By using a technique called inheritance, it's much easier to extend an object, yet retain compatibility. And unlike the Secwin example you don't have to change the existing stuff to call the new stuff; the new stuff incorporates what you want of the old stuff - with more added. This is a side effect of the first point, good design. What this means is that we can still add and extend our object, but the code we add is limited strictly to the change. This means less code, less to document, and thus it's easier to do. And of course, crucially, less chance for new bugs to creep in.

OOP is often touted as making it easier to create bug free code. I disagree; any code you write can introduce new bugs. But with OOP you write less new code, and you shouldn't need to change existing code. Therefore, as you fix the bugs, your product becomes more bug free, and because you can extend the code without hacking it, the risk of introducing bugs into existing programs is less.

Finally, I want to introduce a technique that OOP allows that can't be done in procedural code - at least not without some extreme hoop jumping! This is a really cool concept which seems to have, at least until you understand it, a completely arbitrary name. (Please wait ... disabling mouse so you can't skip this bit.) This is the concept of Virtual Methods. Whoohh - stop scrolling - I haven't finished!

Methods are the OOP equivalent of Procedures and Functions. That's all - nothing more or less. A procedure that's tied to an object is called a Method. And while we're on the topic, a Property is just a variable. No more, no less. Where you read "Property", you can substitute the phrase "Variable tied to an object". That, in a nutshell, is all Objects are - collections of properties (variables) and methods (procedures). Just like in an old function library or DLL - just better organised. And for some obscure reason I've yet to find, an object declaration is called a Class.

Now. Lets take a typical scenario as it might happen in a function library. For simplicity's sake, we'll say that the library only contains 2 functions. Lets call them Harry and Sue. Now Harry, as part of what it does, calls Sue.

Figure1.jpg

Now you'd like to make a new function which is exactly the same as Harry but, instead of calling Sue, it calls a new version of Sue, called Sueson. In our function library we'd have to either copy the Harry function, or make some subtle changes to its internals. Both of these methods open us up to future problems.

First, by duplicating Harry we also duplicate any bugs it may contain. If, later on, Harry gets fixed, then we need to remember to fix the duplicate as well. Ever tried to maintain 2 copies of the same code? Believe me, you don't want to! What about the second method? Well, we could simply modify Harry to be able to call Sueson OR Sue. But then how do we tell Harry which one to do? We could add a parameter, but that would break all the code currently using Harry. And another point: When we add 10 more variations of Sue the problems magnify.

So how does OOP help us? In OOP we would put the 2 functions, Harry and Sue, together in an Object. For simplicity's sake, I'm going to call the Object Father. With OOP, we can create a derivative of Father called, say, Harryson. Harryson, like any good son, inherits all of Father's properties and methods. He gets all of this without lifting a finger. The Harry method and the Sue method are his to inherit.

We can add new methods and properties to Harryson - that's what sons do - but if Sue is declared as a normal method, then the Harry method will always call Sue. Even if we override Sue and create a new Sue, the old Harry will carry on calling the old Sue. (As an aside, it is possible for the new Sue to call the old Sue, as well).

Figure2.jpg

But what if Sue is declared as a Virtual Method? Well, then, when we override Sue in the Harryson Object, we actually cause Harry to point to the new Sue, NOT the old Sue.

Figure3.jpg

So who cares, you say? Well actually, this little trick opens up a whole new realm of possibilities. By overriding Sue (when Sue is a virtual method) we've effectively taught Harry a new trick - but without changing Harry! So old programs carry on using Harry and the old Sue as before - but new programs can make use of the old Harry and the new Sue. This means our code is more reusable than before, without creating administrative overheads.

I hope this has helped you see the benefits of OOP, and maybe you're ready to start climbing the learning curve. Next month we'll start writing an Object. This is a very valuable exercise even if you don't intend to write Objects in the future, because a spin off of this is that the ABC classes become a lot easier to understand. After all, it's easier to understand what someone else is doing if you're capable of doing the task yourself. And in case you wondered - writing Objects in Clarion is as easy as writing anything else, perhaps even easier. See you next month....

Printer-friendly version

Reader Comments

To add a comment to this article you must log in.

 
 

Search

 

Advanced Search
Topical Index

Related Articles

Subscribe to
ClarionMag

One year: $189

(includes all back issues since '99)

Renewals from $139

Two years: $289

Renewals from $239

More Info

Subscribe Now!

ClarionMag Blog

RSS Feeds

Updates via Email

Enter your Email


Powered by FeedBlitz

Quick Links