Thinking in an OOP way
April 6, 1998
by Pat McClellan
Dear Multimedia Handyman,
I keep hearing people talk about Object Oriented Programming, and I've read some of the articles on DOUG about OOP. But I'm a designer with no computer science training. I can do a lot of things in Lingo handlers already but I get lost with the whole parent/child script stuff. Can't I just continue to use handlers?
Pat Sullivan
Dear Pat,
Thanks for your question... it's an important one. It's very easy for beginner and intermediate users to get lost in the OOP conversation because OOP is a higher level of abstraction for your programming. I promise that I won't try to convince you to use parent scripts -- at least not until you want to. I'm also not going to launch into a big analogy of OOP, because Paul Hemmer wrote an excellent and detailed article about this recently, which you can find in the Using Director section (or archive) of this site.
The first thing that you need to understand it that OOP is not just parent scripts. OOP exists in many other computer languages that don't use anything called a "parent script". Object Oriented Programming is simply an approach to organizing your program (and programming) design. It is a mindset, or as Paul Hemmer called it, a paradigm. There are many ways you can work toward this without ever writing a parent script. Let's look at some simple ways of organizing your program which will put you on the right path.
What are the ways that you can organize your program? What are the practices you can exercise to make your program more "elegant"? How can you move toward this OOP mindset?
If you're in the practice of creating one huge dir file, you may want to think about breaking your program into logical "chunks" -- separate dir files that link to each other. Create one movie that is just the intro.dir. That movie goes to the menu.dir. If there are 5 choices on the menu, then you'd have 5 dir files to go to. Why do this? It's simply easier to plan, execute, test, debug and revise the program if it is broken up into smaller, isolated pieces. Also, this is a first step toward the OOP mindset: you now have created, in a sense, an "intro object", a "menu object", and 5 "section objects".
Next level of the hierarchy: casts. As far as Director is concerned, it doesn't care where your cast members are located. It doesn't care if you have one huge internal cast or ten small external casts. So why did they give you this option? Organization. Think of your casts as filing drawers -- okay, not the filing drawer full of junk you gleefully maintain, but the kind of filing drawers you'd want in a big office with important records. There are many ways to file things... by topic, by date, by size, by alphabetical order, by data type, etc. Typically, I might have one cast for my art, one cast for my text and field members, one cast with all my Lingo scripts and behaviors, and one cast for all my digital video or sound. Within the casts, I tend to group things that are associated with each other. This is really up to you and the logic of your project. The important point here is that you are isolating and encapulating your data -- in this case your media. These are key concepts for OOP.
Now, let's talk about Lingo. How can you organize your Lingo? When I started using Director, like you, I had no formal computer science training. So my handlers started small and were very specific. I kept running into the situation where I was writing handlers that were very similar to others in the program -- duplicating my code and my writing effort. What I needed to do was make a step up in the level of abstraction. For example, let's assume that everytime I hit one of eight choices on a menu, I want to change the cast member, log that the user hit that button, play a puppetSound and go to a particular frame. Instead of writing 8 repetitive handlers which differ only in their specifics, I wrote one handler, menuChoice. Whenever a button is selected, menuChoice is called and parameters such as which sound and which frame are supplied in the call. Here again, no parent script, but conceptually, we have created a "menuChoice object".
Over time, as I learned how to use lists, if-then-else statements, parsing strings and such, my handlers got longer and longer. I was very proud of all the stuff I could make happen in a single handler. But again, I noticed some repetitive coding. I realized that handlers can call other handlers, and in this way, I could segment these handlers into discreet operations. For example, let's say that you've got a spreadsheet in your program. You could have one long handler which retrieves the data from the user input fields, does all the necessary calculations and then plugs the correct values into the necessary field. But, elsewhere in the program, you might want to use those same functions for a spreadsheet in a different format or with different calculations. Why not create some isolated handlers that can be called and executed as necessary? Seems easy enough... and guess what: that's another characteristic of OOP.
Since Director 6 came out, I have been using and writing a lot of behaviors. Be sure to check out the library of behaviors that came with D6, as well as the Lingo Behavior Database that Ren Feinstein maintains (in our Resources section). Behaviors are wonderful, because they allow you to drag and drop amazing functionality onto sprites. They're modular, reusable and allow values to be entered for key parameters. And they're also objects. That's right, real live OOP objects. Behaviors are special objects which are sprite specific. So what do they do better than ordinary sprite scripts?
Behaviors are a good example of encapulating data, which, I've come to understand, is one of the characteristics of an object. So what's this mean? All of the information about a sprite can be accessed, monitored and controlled from within a behavior, without using any global variables. That way, you can have several instances of the same behavior applied to and operating on multiple sprites, without any communications problems or mixing up of variables or sprite properties.
Behaviors are a great way to begin understanding and writing your own object scripts. This is what got me really started into OOP. The Behavior Library and the Lingo Behavior Database are full of well-written, well-documented behaviors from which you can learn how to write your own. Start my making simple modifications to copies of existing behaviors. Pretty soon, you'll be writing your own.
Finally, I'll say a few words about parent scripts. If you're comfortable with the concept of what a Behavior is, then think of parent scripts as behaviors that don't have to have a sprite in order to exist. When you attach a Behavior to a sprite, that object -- with all of its functionality -- exists for the duration of the sprite, then disposes of itself so that it is not filling up the memory. Think of a parent script as a behavior that gets attached to a global variable instead of attaching to a sprite. The benefit of this is that the object can continue to exist as sprites come and go, and even as you move from Director movie to movie. So you can use objects created from parent scripts (called "child objects") to watch what the user does, or keep score in the background, or monitor downloads from the internet, or anything else Director can do. These are all functions which don't really have to directly relate to what's going on onstage. They're just "higher-level" functions running in the background.
So now, back to the concept of OOP as a mindset. As I became more comfortable with objects, my Lingo tended to be a mix of objects for high-level stuff and ordinary handlers for the simple stuff. Pretty soon, you start to realize that that approach is like having a very organized drawer in an otherwise messy office. Paul Hemmer addresses this concept very well in his article, so I won't wear it out. Ultimately, it all boils down to planning and organization. Trying to figure out the best *overall* approach to your project and planning your Lingo functionality and communications before you ever write a line of code. Realistically, I know that this will rarely happen. Coming up with the *perfect design* and then executing it is almost impossible. But the value is in the planning.
Wherever you are in the continuum between newbie and guru, the important lesson is that you should always strive to improve the way you work. You can always create more elegant code. You can always document your code better. You can always find a way to improve performance. It's a process that we're all going through. Don't give up.
Copyright 1997-2024, Director Online. Article content copyright by respective authors.