|
|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV SYS-CON.TV WEBCASTS |
POWERBUILDER LINKS YOU MUST CLICK ON All Things New
PowerBuilder Developer's Journal: Building a Working Application Shell
Design considerations
By: Steve Katz
Jan. 29, 2006 05:45 PM
Digg This!
Page 2 of 2
« previous page
Code promotion is the movement of code from a descendant class to an ancestor class accompanied by the necessary generalization of that code so it applies to the ancestor. When you build a simple base class library with limited functionality, as in our case, you may find that functionality is missing when you begin to actually build your application. The key is to be aware of what is being added to the application-specific classes and keep an eye out for features that become prime candidates for code promotion because they could be used across applications. You can think of those as non-application specific features. The importance of not duplicating code cannot be overstated. It is a bug waiting to wreak havoc on your system. In our application, there were two instances when I realized, after I coded an implementation, that the functionality could be easily generalized and moved to the application framework. The first instance was when I needed to implement the Close All menu item functionality. This fairly common item on many application menus allows all open windows to be closed with a single command. Because I know this feature is fairly common, I chose to place it on the framework's m_frame Window menu. However, I didn't code an implementation at the framework's menu level initially. My first implementation was in m_cs_frame, my application's descendant menu. The first implementation looked like this:
// Declare variable for active sheet Fairly straightforward...get the current active sheet, close it, get the next active sheet, close it...until all sheets are closed. I then took a second look and noticed that I had not one, but two application-specific references that I was sure I could generalize. If I could do that, I could also move this generic implementation to my framework and have code that could be executed as is probably 90% of the time. The first reference I wanted to generalize was my reference to w_cs_frame. Since w_cs_frame is inherited from w_frame, that was an easy change. The second reference I wanted to change was from w_cs_sheet to w_sheet. Again, another easy change. Or was it? When I ran this code, I encountered the dreaded null object reference error (see Figure 7). Why did I get this error? I took a closer look at line 4: lw_Sheet = w_frame.GetActiveSheet () The only object that could possibly be null on this line is w_frame. But w_cs_frame obviously exists and is active. Why would w_frame give a null object reference? After all, it's the ancestor class and if the descendant exists, then the ancestor must exist as well since I can execute functions and events from the ancestor. The answer is due to the fact that w_frame, as an object, does not, in fact, exist. My application does have an object of type w_cs_frame which does exist. It also has access to w_frame's functions, events, protected, and public instance variables. What I can do is use a variable of type w_frame to reference my existing w_cs_frame, but w_frame as an object just does not exist. Adding an extra line: w_frame = w_cs_frame gets me no closer to my goal of ensuring the code is generalized so it can reside in the ancestor class. How can I refer to the frame, then, without referring to it by name or type? The answer is the same as how we do it in our spoken languages: pronouns. If I don't want to refer to Mike by name when I'm speaking to Alice, I can use "he." When I don't want to specify whether it was my mom or dad who drove the car into the tree (didn't really happen, by the way - really!!), I can use "parent." In PowerBuilder, several pronouns are available that are useful in this same way. The list of pronouns can be found in the Help by searching for, what else but, "pronoun." (see Figure 8) In my particular case, the "pronoun" I need is ParentWindow, which is actually a menu object property, but looks and acts like a pronoun. So, the final version of the code became:
// Declare variable for active sheet Since GetActiveSheet() returns a reference to a window, shouldn't I use the even more generic "window" as the variable type? The short answer is yes, but there are tradeoffs. What are the tradeoffs of using w_sheet versus window? Using w_sheet makes it easier to change the code to use more framework-related functionality. Using window allows the code to work even when sheets are opened that are not descended from type w_sheet. While technically a no-no, there may be situations where this is acceptable. I prefer to use w_sheet in this case and to force the usage of the framework base sheet window in my application for all sheets. The second instance where I realized I could make a little change and promote code to the framework was in the default handling of the closequery event. I realized that my CloseAll functionality was not taking into account the possibility that the application would code a closequery event somewhere and prevent a window from closing. A quick look at the Close() function shows that the return code will be 1 or -1 where 1 indicates the close was successful and -1 indicates an error. -1 also indicates that a value of 1 was returned from the closequery event to prevent the close of the window. I had to make another change to the CloseAll functionality by handling the return value of the Close() function call:
if Close (lw_Sheet) = -1 then Namely, if there was a problem closing any open window, terminate the CloseAll loop. For the closequery event itself, I wanted to create a generic handler in my base application-level sheet asking if the user really wanted to close the window. I quickly realized that this code could be promoted to the framework because there was nothing application-specific about it. So, the w_sheet::closequery event became:
int li_Rc
Conclusion Page 2 of 2 « previous page
PBDJ LATEST STORIES . . .
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING POWERBUILDER / SYBASE NEWS
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||