| |||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||
Print This Article REALbasic University: Column 099
OOP University: Part Twenty-ThreeWe've spent the last few lessons exploring the challenges of object-oriented program design -- specifically designing OO data structures. To do this we designed a fictitious weblog program called RBlog and came up with an ideal data structure for that program. But what if your program is different? There are many kinds of problems to solve, and many object-oriented solutions. Over the next few lessons we're going to explore some of these and in the process learn more about OO design. We're going to begin with a couple real-world example problems that RBU readers have submitted. The first is the problem Markus Winter described in the letter which inspired this series on program design.
Adding a Progress DialogIf you remember from lesson 096, Markus wrote:
There really are several problems within this single problem. And threads are just one way to solve the problem. Let's begin by looking at what a progress dialog does. It is a modal window (a window that the user can't close or send behind other windows) and within that window is a text description of the state of what is currently happening as well as a progress bar (usually a bar graph), which graphically depicts what percent of the task at hand is complete. While that sounds simple, there are numerous problems within that description. For example, does a progress graph depict the time remaining to complete a task or the number of steps left in the task? Those are very different things. Next, how does one go about estimating the amount of time left in a task? Some computers are faster than others -- you cannot use your own computer as the standard. Most complicated of all, what is considered a "task?" A task could be made up of multiple parts. For instance, "bake a cake" could be all the steps of measuring and mixing ingredients, pouring batter into a pan, and placing it in a hot oven for the appropriate length of time. Yet is that it? Couldn't it begin with purchasing the ingredients at the grocery store and finish with adding frosting and decorating the cake? Or couldn't "baking" be limited to just putting the cake into the hot oven for the right amount of time? As you can see, just defining what aspect of a task will have a progress dialog is tough. Another problem with a multiple-task task is that the individual pieces may take different amounts of time, so if you want to give the user an idea of the amount of time left you cannot just indicate the steps left to do. Then there's the complex problem of the user stopping action. If the progress dialog includes a cancel button, you must be able to stop the task in mid-action. While that sounds easy, it's not. Think about most programming tasks: if a file is the middle of being written to disk and the user cancels it, you must not only stop saving the file but clean up stuff (like not leaving a half-saved file on the disk). Sometimes the clean-up portion can take more time than finishing the original action! For some complex tasks with a lot of setup time, it might even be prudent to ask the user for confirmation before terminating the task, since there's always the possibility that the user didn't mean to press cancel. RBlog RevisitedAs an example of a program in need of a progress dialog, let's look at RBlog again. RBlog will generate pages of a weblog from an internal database of entries. Because older entries are published in archive pages, as the archive grows, there could be hundreds of HTML pages. Depending on the new entries added, potentially dozens of pages could be generated each time the Publish button is pressed. We might also want to add an option to RBlog to automatically upload the changed pages to our website via FTP. Obviously, it'd be appropriate to display a progress dialog to indicate to the user how long this will take. That's when things start to get complicated. The "build pages" portion of RBlog has multiple steps. For instance, it builds the main page, the archive index page (links to the archive pages), and a collection of archives pages sorted alphabetically, by month, and by subject. This means our "task" is made up of multiple parts. Each of those parts varies in the time and number of steps it takes to complete it. For example, if only entries for the current month have changed, we only need to update the current month's archive, but if several months have changed, we must generate new files for multiple months. The first question we must answer is whether or not to display progress based on time or steps. For the user, time is usually the best option. After all, the user would like to know if there's a two minute wait or a quarter of an hour. However, time to completion is difficult to calculate. Anyone who's watched the Finder's estimated time for copying files is aware that it's not very accurate. Even if you come up with a way to generate an accurate initial estimate (usually by performing a small task and timing it to gauge the speed of the current machine), on a multi-tasking operating system (like Mac OS X) the user could launch other tasks that steal CPU time from yours and slow your task down. That means your estimating system must be dynamic, which adds calculations that actually makes the task take longer! Some tasks, like FTP uploading, are dependent on variables that change constantly, such as the amount of bandwidth available or the status of another machine. Thus FTP upload programs are rarely accurate in their estimated times since the times change according to the current state of the connection. It's important to remember that some tasks are indeterminate -- there's no way of knowing how long they'll take to complete. For instance, a program that's waiting for a second machine to reply cannot predict how long it will take that machine to respond. In other cases, data must be generated by the first portion of the task before the second can estimate the time to completition. RBlog falls into this category. While we can estimate how long 26,211 characters will take to write to disk or upload to a file server, we first need to generate the data to know there are exactly 26,211 in the file! Since the data generating portion is lumped into our "task," we cannot accurately predict in advance the size of the data and the amount of time it will take to upload. In the case of indeterminate or complex tasks, it might be better to display a different kind of progress bar. Instead of indicating the time left, you can indicate the steps left. If the steps are of relatively uniform length, this is extremely effective at indicating the time to completion. However, if some steps are dramatically longer than others -- for instance, in RBlog the generate pages portion is much quicker than the FTP upload portion -- you might consider a dual-progress bar dialog like this: ![]() In a dual-progress bar dialog, there are twin progress bars. The outer one indicates the length of the overall task. The inner one indicates the time for the current sub-task, i.e., time to upload the current file to the FTP site. One important thing to remember about progress dialogs is that they serve two key functions. The first is to indicate to the user an approximate amount of time left in the task. But the second is just as important but is often forgotten: that's to give the user feedback so he or she doesn't think the program has stalled. Keep this in mind when designing a progress bar system. If you have sub-tasks that each take considerable times (i.e., minutes, not seconds), you might consider using a dual-progress bar dialog or some other way of indicating progress to the user (like a static text showing numeric progress) so they don't think your program has crashed. Next, you need to decide if having a Cancel button is appropriate or not. That might sound surprising: shouldn't you always give the user a chance to cancel a long task? But there are many times when it's inappropriate to cancel a task. For instance, actions that will leave the computer in a bad state if incomplete shouldn't be cancelable. Examples of this include drive formatting (a half-formatted drive is no good), operating system installation (stopping halfway could be disastrous), file moving (you don't want partial moves), database rebuilding, etc. There are often destructive behaviors that will leave things in a bad way if incomplete. For example, overwriting an old file with a new one, if canceled, could leave the user without either file, a potentially problematic situation (especially for a website where you'd leave the user with an incomplete nonexistent HTML file). Other times giving the user the option of stopping might be more work than you'd want to do. For instance, if the task is a complicated, multi-part action, undoing it to restore things to the way they were before the user cancelled could be difficult. Depending on the nature of the action and the length, it may be okay to not offer a cancel button. For example, most programs don't let you cancel the saving of a file. That's partly because file saving is relatively quick, but also because it's difficult to undo. Long tasks, however, should almost always have a cancel option. If you can't cancel the action for some reason, and yet it may take some time to complete, it is a good idea to warn the user before beginning the action. For instance, "This action will take a while to complete and cannot be cancelled. Are you sure you want to continue?" If you choose to give the user the ability to cancel the action, then you must decide how to handle the cancel. There are different ways to do this, including threads as mentioned by Markus. We'll look at that next time and I'll give you my solution to this problem. Next WeekWe create a reusable Progress Dialog box project.
NewsREALbasic Developer 1.6 AvailableThe next issue of REALbasic Developer is being printed right now and it's packed with some terrific articles. In fact, there's so much stuff we had to leave out the interview feature! (Don't worry: it'll be back next issue.) Here's a sneak preview of what's coming up in the June/July 2003 issue: First up, Erick Tejkowski is back with another excellent QuickTime article. He explains how you can manipulate QuickTime video and audio tracks within REALbasic. It's a must read for anyone interested in multimedia. Next, Charles Yeomans explains one of REALbasic's best kept secrets, control binding. Control binding lets RB do the programming for you. With control binding you can link two controls -- a listBox to an editField, for instance -- without writing a single line of code! Unfortunately control binding hasn't been documented very well, but Charles has fixed that with this excellent article. Finally, Joe Strout writes about getting the most out of Quesa, the 3D library, by using declares to push it beyond the norm. In this issue, I wrote the Postmortem myself, detailing writing and selling my Z-Write word processor. I made plenty of mistakes, so please learn from my experience! Of course we've also got all our regular columnists, reviews of cool products, and more. If you haven't subscribed yet, what are you waiting for?
REALbasic for Windows Special OfferDo you own a Mac version of REALbasic but would like a copy of the Windows version? Well, REAL Software has a special limited time offer for you to grab a copy of the Windows edition at up to $240 off the normal price. Check out the offer and save a bundle. This expires at the end of June so don't delay!
LettersHere's an interesting question from Jayson on whether or not he should upgrade to REALbasic Professional Edition. He writes:
That's a tough question, Jayson! But if you are definitely planning on getting the Pro version at some point, you might go ahead and get it now. However, if you think it might be a while -- say a year -- before you need the Pro features, you could wait. Even though the upgrade is a good deal now, usually when there's a new version of RB the "Standard X to Pro X+1" (where X is a version number, like 5) is usually a good price (cheaper than upgrading "Standard X to Standard X+1" and later upgrading "Standard X+1 to Pro X+1"). One really nice thing about RB is even the Standard version will let you try the Pro features. You can use it to do databases, for instance, but it will only work with the first 50 records. You can build Windows apps, but they'll expire after 5 minutes. Those limitations mean you can't create a sellable app with those features, but you can at least test things. Remember, it can take a long time to finish a real application (especially if you're developing it as a hobby or part-time), so even if you're wanting to create an app that uses Pro features, it might be a year before you really need the unlimited Pro features. I used the Standard for years before I upgraded. Keep in mind that Pro-to-Pro upgrades cost more than Standard-to-Standard upgrades, so if you buy Pro a year or two before you really use those features, you're paying extra money for upgrades in between. About the Column REALbasic University is a weekly instructional column on programming with REALbasic and is brought to you by REALbasic Developer, the magazine for REALbasic programmers. Each week we answer select reader questions, and we're always open to ideas for future columns. Send your questions to . (Keep your questions simple and specific. General queries like "How do I write my own web browser?" will be neglected.) Your question won't be answered immediately, but will be answered in a future column. (If you don't want your correspondence published, just be sure to indicate that when you write. Otherwise it's fair game.) About the Author See the REALbasic University Archives
REALbasic University contents ©2001-2004 by Marc Zeedar and REALbasic Developer. All Rights Reserved.
| |||||||||||||||||||||||||||