Title: Inheritance Using PowerBuilder 5.0
1IA353Using Custom Class Objects in PowerBuilder
Fred Grau Systems Architect - VIPS fgrau_at_chesint.n
et
2Using Custom Class Objects in PowerBuilder
- Skill level Beginning to intermediate
- Agenda-OOP Basics-NVO Basics-NVO
Usage-Service Based Architecture (SBA)
3Shameless Pitch
- Certified PowerBuilder Developer
- Former Consultant - Woodfield Technical Services,
Inc. - Current Position Systems Architect - VIPS
- E-mail fgrau_at_chesint.net
4IMPORTANT!!!
- If you want to leverage your PowerBuilder code
for the Internet, you must use Custom Class
Objects (Also called Non-Visual Objects or
NVOs). - If you want to use a good framework (including
the PFC), you must learn how to use NVOs.
5OOP Basics
- Purpose To maintain code in one place.
- Avoid code duplication
6Objects
- Object - A combination of data and behaviors.
- Object consists of-Attributes What do I know
about?-Functions What things can I do?-Events
What can happen to me?
7Attributes
- Pre-defined attributes-window.title-window.heig
ht-sle_1.text - User-defined attributes-customer.name-n_cst_appm
anager.is_userid
8Functions
- Declare methods or functions to access and
manipulate attributes. - Examples-w_employee.hide()-w_employee.wf_calcul
ate_balance()-dw_1.reset()
9Events
- Predefined mapped - Directly mapped to the
operating system. Example WindowOpen - Predefined not mapped - Predefined in PB, but not
mapped to an object. Example sle_1ue_changed
(mapped to pbm_enchange) - User defined mapped to pbm_customXX - PB 4.0 and
before. Example ue_save (mapped to
pbm_custom01) - User defined not mapped to any MessageID -
Programmer has control over the parameters and
return types. Example ue_save (unmapped)
10Classes
- An abstraction of an object.
- The definition of an object.
- In PowerBuilder, classes are stored in PBLs.
- All windows created are in the same class of
Window.
11Instantiation
- An object never exists until runtime.
- At runtime, a class is instantiated into an
object. - Example A window is opened.
- Note The same object can be instatiated more
than once.
12Inheritance
- One class gets its definition from another
class. - A real-time template - When the parent (ancestor)
object changes, so does the descendant. - Eliminates the copy-paste method of code reuse.
13PowerBuilder Uses Inheritance
- Any Root of all objects and data
typesPowerObject Remenber Message.PowerObjectParm
? NonVisualObject Transaction, Message
GraphicObject Menu Window
WindowObject DragObject
Datawindow, Commandbutton, ListBox, etc.
DrawObject Rectangle, line, etc.
14Inheriting From System Classes
- When you click New, you are inheriting from a
PowerBuilder system class. - Why not inherit from your own customized class
instead?
15What Gets Inherited
- Attributes
- Events
- Functions
16How Does Inheritance Work
- Events Extending scripts-This is the default
behavior of an event script.-When an event is
triggered (i.e. a windows open event), the
ancestors script is executed before the
descendants script.
17Inherited Event Flow - Open(w_desc2)
- w_ancestoropenABC
- w_desc1openDEF
- w_desc2openGHI
- Statements executed ABC DEF GHI
18How PowerBuilder Extends a Script
- w_ancestoropenABC
- w_desc1openCALL w_ancestoropenDEF
- w_desc2openCALL w_desc1openGHI
An implicit Call to the ancestor is automatically
coded in each extended descendant.
19Overriding Scripts
- Enabled on an event-by-event basis by setting the
Design/Override Ancestor Script menu option in
the descendants event script. - When an event occurs, only the descendants
script is executed. - If necessary, you can still call an ancestor
script by using the CALL ltancestor_name or
SUPERgtEvent ltevent_namegt syntax.
20Overriding Events
- w_ancestoropenABC
- w_desc1openCALL w_ancestoropenDEF
- w_desc2open OVERRIDDENGHI
Statements executed GHI
21Overriding Events - Continued
- w_ancestoropenABC
- w_desc1open OVERRIDDEN DEF
- w_desc2open CALL w_desc1openGHI
Statements executed DEF GHI
22How does Inheritance Work for Functions?
- The ancestor and descendant object each have a
function with the same name and same argument
list. - If a descendant script calls the function name,
the descendants function gets executed and the
ancestors function is ignored.
23Overriding Functions - Call wf_calc() in w_desc2
- w_ancestor.wf_calc()ABC
- w_desc1.wf_calc()DEF
- w_desc2.wf_calc()GHI
Statements executed GHI
24Overriding Functions - Call wf_calc() in w_desc2
- w_ancestor.wf_calc()ABC
- w_desc1.wf_calc()DEF
- w_desc2.wf_calc() does not exist
Statements executed DEF
25Overloading Functions
- Ancestor and descendant object each have a
function with the same name but a different
argument list. - If a descendant script calls a function, the
function with the same argument list gets
executed and any other functions with the same
name are ignored. - You can overload a function without using
inheritance.
26PowerBuilder Example of Function Overloading
- MessageBox-MessageBox("Greeting", "Hello
User")-MessageBox (Delete, Delete Error,
Exclamation!)-MessageBox (Delete, Are you
deleting?, Exclamation!, YesNoCancel!, 2)
27Polymorphism
- Provides the ability to hide different
implementations of a method behind a common
interface. - The same function call performed on different
objects produces different results. - Shifts responsibility of correct functionality
from the sender (client) to the receiver (server).
28Polymorphism Examples
- Example 1inv_sybase.of_get_return_code()inv_ora
cle.of_get_return_code()inv_informix.of_get_retur
n_code() - Example 2basketball.bounce()football.bounce()b
owlingball.bounce()
29How Objects Talk To Each Other
- Objects communicate to each other by passing
messages (via a public interface).-You any pass
the information the object needs. - This allows you to develop single-purpose
methods. - In PowerBuilder you can call functions or trigger
events.
30Ways to Pass Arguments to a Method
- By Value You pass a copy of the value to the
method. - By Reference You pass a reference (a pointer or
memory location) to the method. - By ReadOnly You pass a reference, but it cannot
change.
31Remember
- When passing a simple data type (i.e. String,
Int, Boolean) by value, you are passing a copy of
the value. - When passing a complex data type (i.e.
DataWindow, Window, User Object) it is
automatically passed by reference.
32Non-Visual Objects
- PowerBuilder calls them Custom Class User Objects.
33Defining Custom Class User Objects
34Non-Visual Objects
- Once defined, you can add1. Functions2.
Events3. Attributes (e.g. Instance Variables) - They exist only in memory.
35Instantiating Objects DECLARE
- Window w_logon lw_logon
- NVO n_cst_count lnv_count
- Declaring an object merely creates a reference
variable (pointer). This pointer is initialized
to null (invalid). It hasnt been created in
memory (instantiated). - The compiler uses this declaration to validate
the existence of its methods and attributes.
36Instantiating Objects Instantiate
- Window Open (lw_logon)
- NVO lnv_count CREATE n_cst_count
- Instantiating an object tells PowerBuilder to
create an object in memory and make the reference
variable point to the object. - NOTE You can create the declared object or a
descendant of the declared object.
Examples lnv_count CREATE
n_cst_count_win16 lnv_count CREATE
n_cst_count_win32
37Differences Between OPEN and CREATE
- OPEN is for visual objects-If the reference
variable points to an instantiated object
(IsValid) then a new object is NOT created.-OPEN
returns a -1 if the object cannot be
instantiated. - CREATE is for Non-visual objects.-CREATE always
creates a new object.-If the reference variable
points to an instantiated object, then the old
object is orphaned.
38CREATE USING
- Can now CREATE objects dynamically without hard
coding the object names. - Example n_cst_deptxxx are descendants of
n_cst_dept.n_cst_dept lnv_deptString ls_dept_nvo
Integer li_dept_numls_dept_nvo
n_cst_dept String(li_dept_num)lnv_dept
CREATE USING ls_dept_nvo - If the classname referenced in CREATE USING is
not found, a runtime error is generated.
39Instantiating Objects USE
- Window lw_logon.Hide()
- NVO lnv_count.of_get_count()
- Can use an objects Attributes Events Function
s
40Instantiating Objects DESTROY
- Window Close (lw_logon)
- NVO Destroy lnv_count
- Destroying an object removes it from memory and
frees up resources. The variable will still
exist and is set to null (invalid). - Not destroying NVOs can cause memory leaks.
- PowerBuilder 6.0 has automatic garbage
collection which will reduce memory leaks.
41Encapsulate Your NVO
- Allows you to change the implementation of an
object without breaking other parts of the
system. - One object should not directly access the
attributes of another object. Only public
methods (functions or events) can access these
attributes. - To prevent direct manipulation, declare your
instance variables as private or protected. - Create Get and Set functions to access the
attributes. Examples gnv_app.of_SetUserID
(ls_userid) ls_userid gnv_app.of_GetUserID()
42Access Modifiers
- Public (Default) Open to all other objects.
- Protected Open to the current object and its
descendants. - Private Open to the current object only.
- ProtectedRead Only the current object and its
descendants can read this attribute. - ProtectedWrite Only the current object and its
descendants can write to this attribute. - PrivateRead Only the current object can read
this attribute. - PrivateWrite Only the current object can write
to this attribute.
43AutoInstantiation of User Objects
- NVOs can now be set to AutoInstantiate when the
object is declared. - Object is automatically destroyed when it goes
out of scope. - To AutoInstantiate-Right-click on the user
object when it is defined.-Select the
AutoInstantiate menu item - CREATE causes a compile error.CREATE USING
causes a runtime error.
44AutoInstantiated NVO Example
- Assume n_cst_employee is AutoInstantiatedn_cst_e
mployee inv_emp // Instance or Local
VariableInteger li_rcString ls_ssnli_rc
inv_emp.of_edit_ssn(ls_ssn) - Object is destroyed when it goes out of scope.
45Using AutoInstantiated NVOs
- Even with AutoInstantiation and PowerBuilders
garbage collection, still use the CREATE and
DESTROY. - AutoInstantiation is very useful when using NVOs
as structures. - Use AutoInstantiation when an object does not
reference any other objects.
46Some Uses for NVOs
- Hold Global variables.
- Storage for constants.
- Business rules.
- EAServer and the Web.
- Add GUI functionality.
- Database independence.
- Placeholder for external DLL functions.
47NVO Uses Hold Global variables
- Lets you easily transport globals to new
applications.No need to duplicate globals in
each application. - Allows for the easy add or change of new
attributes. - Lets you protect against invalid changes of
attributes through encapsulation.
48NVO Uses Storage for Constants
- Return values should be constants.
- Remember Constants do not use storage during
runtime. - Any changes to a constants value only has to be
made in one place. After making the change, just
simply regenerate the necessary objects. - To use-Create an NVO that holds nothing but
constants (e.g. n_cst_constants)-Create a global
variable n_cst_constants gc-Reference
constants using dot notation IF SQLCA.SQLCode
gc.NOT_FOUND Then
49NVO Uses Business Rules
- Place as many edits and updates as possible in
NVOs. - Business rules NVOs then become reusable in your
application. - They also become reusable in future applications.
50NVO Uses EAServer and the Web
- NVOs can be moved to an application server
(EAServer). - Web pages can then be incorporated to have HTML
interface with NVOs running on an application
server.
51NVO Uses Add GUI Functionality
- The PFC uses a Service Based Architecture (NVOs)
to handle Multiple Inheritance. - Objects are loosely coupled - Less dependency on
other objects. - Objects (e.g. Windows and DataWindow controls)
delegate work to the NVOs. - Only the required services are placed into
memory. - PFC examplesu_dw - Ancestor datawindow control
(Standard visual user object of type datawindow.
n_cst_dwsrv_rowselection - Can single or
multi-select rows.n_cst_dwsrv_sort - Sort
service.
52NVO Uses Database Independence
- Use NVOs to encapsulate database interaction.
- Inherit a transaction object by performing the
following-Create a Standard class user object
(NVO) of type transaction (e.g. n_tr).-Add
database-related methods (e.g. Commit, Rollback,
Connect, status checking, etc.)-Edit the
application object, edit its properties, click
the variable types tab, and under SQLCA change
Transaction to n_tr.-Access n_trs methods
(e.g. SQLCA.of_commit() )
53NVO Uses Placeholder for external DLL functions.
Remember The CREATE statement can instantiate
either the ancestor or one of its descendants.
54NVO Uses Placeholder for external DLL functions
(Continued).
- Create a variable n_cst_platform lnv_platform
- Call function f_SetPlatform (lnv_platform, TRUE)
to instantiate either the 16-bit or 32-bit
version of the external DLL NVO. - Call the desired function with lnv_platform.
Examplels_directory lnv_platform.of_GetSyste
mDirectory() - Destroy the NVO f_SetPlatform (lnv_platform,
FALSE)
55NVO Uses Placeholder for external DLL functions
(Continued).
- f_SetPlatform(anv_platform, ab_switch)
ScriptEnvironment lenvGetEnvironment (lenv)IF
ab_switch TRUE // Create the NVO
IF lenv.win16 THEN anv_platform
CREATE n_cst_platformwin16 ELSE
anv_platform CREATE n_cst_platformwin32
END IFELSE // Destroy the NVO
Destroy anv_platformEND IF
56Service Based Architecture
- Introduced to the masses in PowerBuilder 5.0 with
the PFC (PowerBuilder Foundation Classes).
571st Generation of Coding PowerBuilder
582nd Generation of Coding PowerBuilder
59Problems
- What if you want a tab with master/detail
datawindows? - What if you want your DataWindow to have Sort and
Multi-row Selection capabilities? - What if you change the GUI to now include tab
folders? - You need multiple-inheritance, but PowerBuilder
doesnt provide it.
60Problem Example
- u_dw_singleselect
- u_dw_singleselect_filtersimple
- u_dw_singleselect_filtertab
- u_dw_multiselect_multi
- u_dw_multiselect_multi_filtersimple
- u_dw_multiselect_multi_filtertab
- u_dw_multiselect_extended
- u_dw_multiselect_extended_filtersimple
- u_dw_multiselect_extended_filtertab
- u_dw_filtersimple
- u_dw_filtertab
61Wrong Solution
- Create fat ancestors. -Ancestor objects have
all the required functionality.-Results in
fewer ancestors.-Uses IF/Case throughout to
determine functionality.
62Wrong Solution
- Problems with fat ancestors-Slow performance.
What if your window has multiple
datawindows?-Maintenance (bug fixes and
enhancements) is more difficult. Related code is
spread throughout the object.
633rd Generation of Coding PowerBuilder
- Use a Service Based Architecture
Client Objects
Service Objects
Services are usually NVOs
The client objects can be Windows, DataWindows,
buttons, etc
64Service Based Architecture
- Definition The delegation of client object
common behavior to another service class. - Common functionality is divided into smaller
units. - These service classes are instantiated as they
are needed. This allows for thinner client
classes. - Each client class is pre-wired to use the
services.
65SBA Benefits
- Faster loading of objects.
- Better defined objects (via encapsulation).
- Easier to maintain. Additional services are
easily added. - Promotes reusable code.
- Handles the multiple-inheritance problem.
66SBA Drawbacks
- Learning curve. This is a new way of thinking.
- Existing libraries (pre-PFC) will not be easy to
convert. It is not a cost-effective short term
solution.
67SBA Example
- You want your DataWindow to single-select rows,
you want to sort on the column headers, and you
want to filter the results.
68SBA (PFC) Exampleu_dw Constructor Event
- This.of_SetRowSelect (TRUE)
- inv_rowselect.of_SetStyle (inv_rowselect.SINGLE)
- This.of_SetSort (TRUE)
- inv_sort.of_SetColumnDisplayNameStyle
(inv_sort.HEADER) - This.of_SetFilter (TRUE)
- inv_filter.of_SetStyle (inv_filter.SIMPLE)
69Creating a New DataWindow Service in the PFC
- Create a Custom Class Object (NVO) inherited from
n_cst_dwsrv (i.e. n_cst_dwsrv_unique). - The datawindow name used in all scripts must be
call idw_requestor. - In u_dw (or the corporate layers u_dw), add an
instance variable. Example n_cst_dwsrv_unique i
nv_unique - Create a new function in u_dw (i.e.
of_setunique(ab_switch)) which will look almost
identical to pfc_u_dw.of_setfind(). - In the destructor event, destroy the NVO to
prevent memory leaks. Example This.of_setunique(
FALSE) - When you place u_dw on your window, you can now
enable this service in the Constructor event.
Example This.of_setunique(TRUE). - Call scripts within the NVO as needed.
Example dw_1.inv_unique.of_generate_number()
70Summary
- Using NVOs can provide your application and
future applications with reusable code. - To ensure reusability, encapsulate your NVOs.
- There are many uses for NVOs. Only some of these
uses were described in this presentation. - The PFC heavily uses NVOs.
- EAServer is primarily based on NVOs.
- If your want to leverage your existing
PowerBuilder code for the Internet, place as much
code as possible in NVOs.
71Summary
- Questions/Comments??
- E-mail fgrau_at_chesint.net
- Baltimore Area PowerBuilder Users
Groupwww.geocities.com/bapbug