TweetFollow Us on Twitter

Object-Oriented Programming with REALbasic

Volume Number: 20 (2004)
Issue Number: 4
Column Tag: Programming

REALBasic Best Practice

by Guyren G Howe

Object-Oriented Programming with REALbasic

Getting the most from a unique Object-Oriented paradigm

Welcome to the first issue of my regular REALbasic Best Practice column. Each month, I'll tackle the question of how one can get the most out of REALbasic. I'm going to mix things up: reviews, advice, adapting general programming techniques to REALbasic, but always with the theme of "best practice".

I'm going to start with something I touched on in last month's review: REALbasic's unique object-oriented programming feature, that I call the Event Model. This article assumes you are familiar with the basics of object-oriented programming.

A Little History

A little history will help us to understand where we are.

REALbasic's original designer, Andrew Barry (who sadly is no longer with REAL Software) came up with what I believe is an entirely novel, and powerful object-oriented programming model for the very first version of REALbasic, which he prosaically called Events. To distinguish this feature in general from particular events, I'll call the feature the Event Model.

Because it was too different from what folks were used to, and because it made porting code from other languages more difficult, Andrew bowed to pressure, and also provided support for basically the same OOP model that Java supports (single inheritance with interfaces).

Once Andrew left, the programmers and managers at REAL Software have, to my mind, quite reasonably focused on the many other ways in which they wanted to improve REALbasic, and they've done a bang-up job of that. But they have, in some ways unfortunately, lost focus on this cool language feature. It's still there, it still works just fine, but REAL doesn't correctly document it, they don't much talk about it, and they haven't extended it in a few obvious ways that would make it just about perfect.

Why You need events

You need the Events Model because it makes code development and maintenance easier, and because the result of code changes in a superclass under the Events Model is much more predictable than with traditional method overriding.

In fact, the Event Model brings such clarity, and maintainability benefits that, except for doing one particular thing, Events are superior in every way to traditional method overriding.

Events vs Method Overriding

I will now explain what the Event Model is, and provide an example to demonstrate the advantages I just mentioned.

What we're about here is the relationship between the code in a superclass, and the code in a subclass. In Object-Oriented Programming languages, one of the most interesting problems is how the language should support code re-use down through a class hierarchy. We want to be able to provide some code in a superclass, and then have code in a subclass somehow extend or modify that code -- and to perform further modification, and extension of behavior on down a class inheritance chain.

Every mainstream Object-Oriented language does this by allowing a subclass to override methods on its superclass, entirely replacing that code, and then allowing the subclass to invoke methods defined in the superclass, including quite often invoking the superclass's version of the overridden method. A common pattern will be a method on a superclass that provides code to complete some but not all of some task, with the expectation that a subclass will override the method, carry out the rest of the task, and at some point call the overridden method to do the common part.

Notice that in this scheme, the subclass is entirely in charge of the final carrying-out of the method. In particular, it is up to the subclass to determine when and how to invoke the code in the superclass as part of its design for the complete method. In an inheritance chain, control is usually passed in this way from the bottom up, with a subclass invoking the most immediate superclass's methods as it desires.

There are two serious problems with this model:

Good object-oriented design will push as much code as is reasonable toward the top of the class hierarchy, but that code has to be written without being able to rely on when and how it is being invoked by the subclasses. Even in code you're entirely writing yourself, you have to remember what conventions you intended to employ in this relationship, possibly when you come back to code six months after you wrote it; and

It is easy for a subclass to override a superclass in such a way that, although you want to make a change in behavior that is the superclass's responsibility, you can't do it without also having to change some or all of the subclasses' code as well.

The Events Model, on the other hand, turns this whole thing on its head, allowing the superclass to provide subclasses with explicit opportunities to act, and letting these opportunities pass down the inheritance chain rather than up it. This very neatly avoids both of the problems mentioned, as we will see.

An Example

Let's consider a simple example that clearly illustrates the advantage of the Events Model.

Assume we're writing an application with a non-standard user interface, so we use custom controls drawn using graphics primitives.

We create an abstract Control superclass, whose task it is to keep track of where the control is on the screen. We give it a Draw method.

Next, we have an abstract Button subclass of Control, with code to draw a common background color and some other graphic details shared by all the buttons in the program.

We then create a whole variety of button subclasses for various tasks.

So we have an inheritance hierarchy that looks like this:


Figure 1: A simple inheritance hierarchy

The Method Overriding Way

When we use method overriding as our means of extension, as we go up the chain, each class overrides its superclass's Draw method and invokes that method as part of its own draw process.

This means that a control at the bottom of the chain will have a Draw method that looks something like this:

Pseudo-code for a Draw method at the bottom of the inheritance chain

Sub Draw
   Super.Draw
   ... code to draw specifics on top of background provided by super
End Sub

Button.Draw, in turn, has code like this:

Pseudo-code for Button.Draw
Sub Draw
   Super.Draw //Work out where I'm drawing
   ... code to draw background
End Sub

Control.Draw has code like this:

Pseudo-code for Control.Draw
Sub Draw
   ... code to work out where to draw
End Sub

This is all fine. We get nice abstraction and code re-use, all the usual OOP goodness.

But a problem arises when we make changes to the superclasses. Let's say we now want to make all our buttons have an Aqua-style highlight: we want to take whatever the subclass produces, and run a graphic filter over that to make it look like it's sitting in a drop of liquid.

We simply can't do it without wholesale code rewriting. With this inheritance scheme, the superclass has no way to obtain another chance to act after the subclass is done calling on it. The only solution is to make changes to every bottom-level subclass, even though we really don't need the subclasses to do their part of the drawing task any differently. A change in the shared logic can't be implemented in the shared code.

The Event Model

An Event declaration is essentially a declaration of the interface for a method that subclasses can implement (this "method" is called an Event Handler), that can only be called from the declaring superclass. Once declared, the superclass can invoke the event handler just like a regular method or function.

When an event handler is called, the most immediate subclass implementing a handler for it gets to act. If no subclass implements a handler, the call is ignored (if the call is to a function, a "null" -- 0, Nil, False, the empty string, and so on -- value is returned).

Note that once a handler for an event exists in the hierarchy for a particular class, further subclasses don't even see the event. Frequently, the subclass will do whatever it needs in response to the event invocation, and then invokes a new event it has declared, having exactly the same name and arguments, providing further subclasses with the opportunity to act.

Note that rather than the ill-defined mess that is method overriding, the language is providing a well-defined protocol for superclasses to delegate specific responsibilities down to their subclasses.

A good example of this scheme is the REALbasic EditField control, which declares a KeyDown event as a function with a string argument, returning a Boolean value. The event indicates to a subclass that the user has tried to type something into the EditField. If the subclass provides a handler for KeyDown and returns True in that handler, the keystroke is ignored. Otherwise, it is displayed in the EditField normally.

This scheme makes it easy to extend the EditField to create a control that, say, only lets the user enter a number.

The Button Example, Using the Event Model

Back to our example of custom buttons.

Under the Event model, rather than each subclass overriding its superclass's version of Draw, only the top-level Control class has a Draw method. In addition, Control declares a new DrawEvent event. Each subclass will provide a handler for the event, and will also declare a new version of the event, calling it at the appropriate time. So now we have:

Control.Draw has code like this:

Pseudo-code for Control.Draw
Sub Draw
   ... code to work out where to draw
   DrawEvent //Ask subclass to now draw itself there
End Sub

Button's DrawEvent handler looks like this:

Pseudo-code for Button.Draw
Sub DrawEvent
   ... code to draw background
   DrawEvent //Ask subclass to draw its content atop the background
End Sub

Finally, the class at the bottom of the chain just does its part of the task.

Pseudo-code for a Draw method at the bottom of the inheritance chain
Sub DrawEvent
   ... code to draw specifics on top of background provided by super
End Sub

Now what happens when we want to add the new graphical tweak? We only have to change the code in one place, Button's DrawEvent handler, which now looks like this:

Pseudo-code for an extended Button.Draw

Sub DrawEvent
   ... code to draw background
   DrawEvent //Ask subclass to draw its content atop the background
   ... code to draw water on top
End Sub

Once you get the Event Model, you miss it in every other object-oriented language.

There are many advantages to the Event Model. For example, if you're working with a team of programmers, or you're shipping a framework for others to use, with method overriding, you need all sorts of tortuous documentation about how subclasses should interact with their superclasses. With the Event model, the language itself enforces the relationship. So not only does the Event Model make maintenance easier, but it better explicates the logic of the program.

The Exception that Proves the Rule

...except that there is one feature for which we still need overriding: functions for which the subclass should return a more specific type than the superclass does. The canonical example of this is a generic data structure. We can write, say, a generic data store base class that stores Objects. But this is needlessly difficult to use as it is, because we have to cast the objects we get from it to a more specific type in order to use them, every single time we use this class.

What we want is to extend the generic data structure to one storing objects of more specific types -- a list of controls, for example, where the casting to the correct return type is done for us. Unfortunately, the Events Model provides no way to do this, because the function that yields the objects must be declared to return values of type Object (or perhaps Variant).

The method overriding paradigm provides what we need here. We create a Protected function toward the top of the inheritance chain, then declare and invoke suitable events so that subclasses can carry out the function. Then we create a 'public face' on that function in the bottom-level class in the form of a function that returns the type we want, and have it just call up to the protected internal function, at the top of the class hierarchy, that provides the generic functionality.

So the call sequence goes like this:


Figure 2: Using Method Overriding to Create a More Restricted Type

We invoke the public Get() function on the bottom-level ControlStore class.

ControlStore invokes the protected GenericStore.GetInternal() function on the base GenericStore class.

GenericStore invokes its GetEvent.

The most immediate subclass declaring a handler is GenericList, which fetches the result, returning it to GenericStore.

GenericStore returns the result to ControlStore.Get().

ControlStore.Get() casts the result to a Control and returns it to the original caller.

Interestingly, notice that in a sense, we aren't actually extending the GenericList class's behavior: we're actually restricting it. All of this calling up, and back down the inheritance chain is a little weird when you first do it. Quite often, in the bottom class, you will be creating the public function, calling the protected version in the base class, then turning around and handling the event again the same bottom-level class. When I first started doing this, it felt a bit baroque, to be going up, and then down the inheritance chain like this, and having the public function actually fulfill its role in the event handler. But I'm quite comfortable with it now because I don't see overriding as an extension mechanism at all any more.

It might help to see that in fact, you could do this with just Events by creating a wrapper class that does the type casting. I just prefer to do it all within the same class hierarchy, because it's cleaner and clearer to do this rather than create the generic store, the wrapper class, and suitable Interface.

It would be nice if REALbasic had templates, or if some other mechanism could be found that let us stick entirely to the Events Model without any of that, but this constrained use of overriding is just fine for now.

Improvements Wanted

I'd like to see REAL Software emphasize the Events Model in their documentation. I'd also like to see them look into making some improvements to the Events Model to make it more powerful.

One obvious improvement would be to provide a compiler directive that could execute different code depending on whether an Event has a handler available or not. A common style of programming you'll want to do with Events is to provide default behavior at some point in the code for a class, but allow a subclass to extend or replace that behavior (as the EditField does with the KeyDown Event).

The only way to do that right now with Events is to call a function-style Event Handler, and do your default behavior if you get back the "null" response. But in some circumstances, you need to treat the null value as a result, rather than an indication that you didn't provide an event handler, and you wind up doing all sorts of gymnastics to work around the problem.

Conclusion

I hope I've convinced you of the virtue of the Events Model. Once you "get it", in my experience, you'll wonder how you ever lived without it.


Guyren G Howe works in artificial intelligence research, after years of work as a technical writer and developer. He is married with one child, is an Australian, and lives in Austin, Texas. Guyren has been working with REALbasic for several years. Most notably, he wrote the REALbasic Curriculum Project, an extensive computer science curriculum, for REAL Software (available from the REALbasic website).

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Adobe Dreamweaver CC 2018 18.0.0.10136 -...
Dreamweaver CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Dreamweaver customer). Adobe Dreamweaver CC 2018 allows you to... Read more
Adobe Lightroom 20170919-1412-ccb76bd] -...
Adobe Lightroom is available as part of Adobe Creative Cloud for as little as $9.99/month bundled with Photoshop CC as part of the photography package. Lightroom 6 is also available for purchase as a... Read more
Adobe Photoshop CC 2018 19.0.0 - Profess...
Photoshop CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Photoshop customer). Adobe Photoshop CC 2018, the industry standard... Read more
Adobe Muse CC 2017 2018.0.0 - Design and...
Muse CC 2018 is available as part of Adobe Creative Cloud for as little as $14.99/month (or $9.99/month if you're a previous Muse customer). Adobe Muse 2018 enables designers to create websites as... Read more
Adobe Animate CC 2017 18.0.0.107 - Anima...
Animate CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Flash Professional customer). Animate CC 2018 (was Flash CC) lets you... Read more
Hopper Disassembler 4.3.0- - Binary disa...
Hopper Disassembler is a binary disassembler, decompiler, and debugger for 32- and 64-bit executables. It will let you disassemble any binary you want, and provide you all the information about its... Read more
GraphicConverter 10.5.1 - $39.95
GraphicConverter is an all-purpose image-editing program that can import 200 different graphic-based formats, edit the image, and export it to any of 80 available file formats. The high-end editing... Read more
Delicious Library 3.7 - Import, browse a...
Delicious Library allows you to import, browse, and share all your books, movies, music, and video games with Delicious Library. Run your very own library from your home or office using our... Read more
Duet 1.6.7.0 - Use your iPad as an exter...
Duet is the first app that allows you to use your iDevice as an extra display for your Mac using the Lightning or 30-pin cable. Note: This app requires a $14.99 iOS companion app. Version 1.6.7.0:... Read more
iExplorer 4.1.5 - View and transfer file...
iExplorer is an iPhone browser for Mac lets you view the files on your iOS device. By using a drag and drop interface, you can quickly copy files and folders between your Mac and your iPhone or... Read more

Wheels of Aurelia (Games)
Wheels of Aurelia 1.0.1 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0.1 (iTunes) Description: | Read more »
Halcyon 6: Starbase Commander guide - ti...
Halcyon 6 is a well-loved indie RPG with stellar tactical combat and some pretty good writing, too. It's now landed on the App Store, so mobile fans, if you're itching for a good intergalactic adventure, here's your game. Being a strategy RPG, the... | Read more »
Game of Thrones: Conquest guide - how to...
Fans of base building games might be excited to know that yet another entry in the genre has materialized - Game of Thrones: Conquest. Yes, you can now join the many kingdoms of the famed book series, or create your own, as you try to conquer... | Read more »
Halcyon 6: Starbase Commander (Games)
Halcyon 6: Starbase Commander 1.4.2.0 Device: iOS Universal Category: Games Price: $6.99, Version: 1.4.2.0 (iTunes) Description: An epic space strategy RPG with base building, deep tactical combat, crew management, alien diplomacy,... | Read more »
Legacy of Discord celebrates its 1 year...
It’s been a thrilling first year for fans of Legacy of Discord, the stunning PvP dungeon-crawling ARPG from YOOZOO Games, and now it’s time to celebrate the game’s first anniversary. The developers are amping up the festivities with some exciting... | Read more »
3 reasons to play Thunder Armada - the n...
The bygone days of the Battleship board game might have past, but naval combat simulators still find an audience on mobile. Thunder Armada is Chinese developer Chyogames latest entry into the genre, drawing inspiration from the explosive exchanges... | Read more »
Experience a full 3D fantasy MMORPG, as...
Those hoping to sink their teeth into a meaty hack and slash RPG that encourages you to fight with others might want to check out EZFun’s new Eternity Guardians. Available to download for iOS and Android, Eternity Guardians is an MMORPG that lets... | Read more »
Warhammer Quest 2 (Games)
Warhammer Quest 2 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: Dungeon adventures in the Warhammer World are back! | Read more »
4 of the best Halloween updates for mobi...
Halloween is certainly one of our favorite times for mobile game updates. Many popular titles celebrate this spooky season with fun festivities that can stretch from one week to even the whole month. As we draw closer and closer to Halloween, we'... | Read more »
Fire Rides guide - how to swing to succe...
It's another day, which means another Voodoo game has come to glue our hands to our mobile phones. Yes, it's been an especially prolific month for this particular mobile publisher, but we're certainly not complaining. Fire Rides is yet another... | Read more »

Price Scanner via MacPrices.net

Apple restocks full line of refurbished 13″ M...
Apple has restocked a full line of Apple Certified Refurbished 2017 13″ MacBook Pros for $200-$300 off MSRP. A standard Apple one-year warranty is included with each MacBook, and shipping is free.... Read more
13″ 3.1GHz/256GB MacBook Pro on sale for $167...
Amazon has the 2017 13″ 3.1GHz/256GB Space Gray MacBook Pro on sale today for $121 off MSRP including free shipping: – 13″ 3.1GHz/256GB Space Gray MacBook Pro (MPXV2LL/A): $1678 $121 off MSRP Keep an... Read more
13″ MacBook Pros on sale for up to $120 off M...
B&H Photo has 2017 13″ MacBook Pros in stock today and on sale for up to $120 off MSRP, each including free shipping plus NY & NJ sales tax only: – 13-inch 2.3GHz/128GB Space Gray MacBook... Read more
15″ MacBook Pros on sale for up to $200 off M...
B&H Photo has 15″ MacBook Pros on sale for up to $200 off MSRP. Shipping is free, and B&H charges sales tax in NY & NJ only: – 15″ 2.8GHz MacBook Pro Space Gray (MPTR2LL/A): $2249, $150... Read more
Roundup of Apple Certified Refurbished iMacs,...
Apple has a full line of Certified Refurbished 2017 21″ and 27″ iMacs available starting at $1019 and ranging up to $350 off original MSRP. Apple’s one-year warranty is standard, and shipping is free... Read more
Sale! 27″ 3.8GHz 5K iMac for $2098, save $201...
Amazon has the 27″ 3.8GHz 5K iMac (MNED2LL/A) on sale today for $2098 including free shipping. Their price is $201 off MSRP, and it’s the lowest price available for this model (Apple’s $1949... Read more
Sale! 10″ Apple WiFi iPad Pros for up to $100...
B&H Photo has 10.5″ WiFi iPad Pros in stock today and on sale for $50-$100 off MSRP. Each iPad includes free shipping, and B&H charges sales tax in NY & NJ only: – 10.5″ 64GB iPad Pro: $... Read more
Apple iMacs on sale for up to $130 off MSRP w...
B&H Photo has 21-inch and 27-inch iMacs in stock and on sale for up to $130 off MSRP including free shipping. B&H charges sales tax in NY & NJ only: – 27″ 3.8GHz iMac (MNED2LL/A): $2179 $... Read more
2017 3.5GHz 6-Core Mac Pro on sale for $2799,...
B&H Photo has the 2017 3.5GHz 6-Core Mac Pro (MD878LL/A) on sale today for $2799 including free shipping plus NY & NJ sales tax only . Their price is $200 off MSRP. Read more
12″ 1.2GHz Space Gray MacBook on sale for $11...
Amazon has the 2017 12″ 1.2GHz Space Gray Retina MacBook on sale for $100 off MSRP. Shipping is free: 12″ 1.2GHz Space Gray MacBook: $1199.99 $100 off MSRP Read more

Jobs Board

Commerce Engineer, *Apple* Media Products -...
Commerce Engineer, Apple Media Products (New York City) Job Number: 113028813New York City, New York, United StatesPosted: Sep. 20, 2017Weekly Hours: 40.00 Job Read more
US- *Apple* Store Leader Program - Apple (Un...
US- Apple Store Leader Program Job Number: VariousUnited StatesPosted: Oct. 19, 2017Retail Store Job Summary Learn and grow as you explore the art of leadership at Read more
Product Manager - *Apple* Pay on the *Appl...
Job Summary Apple is looking for a talented product manager to drive the expansion of Apple Pay on the Apple Online Store. This position includes a unique Read more
*Apple* Retail - Multiple Positions - Farmin...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Frameworks Engineer, *Apple* Watch - Apple...
Job Summary Join the team that is shaping the future of software development for Apple Watch! As a software engineer on the Apple Watch Frameworks team you will Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.