When I started writing eXpress++ back in 1999, I too was much more comfortable with function based programming, but over the years I have evolved to realize the real power of object-oriented programming and especially the improvements in productivity.
There are some projects I have written in which writing in function based code would have been unsupportable. I could never have written my Snyffle game, or the IM (intstant messenger) any other way than object-oriented. And, of course, there are parts of eXpress++ that must be written using OOPS.
I was given the task of converting a small program which was written using all function calls to one that was fully object oriented.
Bobby Drakos wrote a program named PATHUTIL.PRG. I used this program as an example of how to convert to oops and still maintain the exact same look and functionality. I have included both programs in the attached file.
PATHUTIL.PRG is object oriented.
PATHUTIL_FUNC.PRG is function based.
You will see that all calls to STATIC FUNCTIONS have been changed to METHODS of a new class name PathUtil().
What makes OOPS more supportable and more productive is the fact that it is no longer necessary to pass a lot of parameters between functions. Here is an example:
Function based:
Code: Select all
_tabs(GetList, @aTabs, @aEnvStr, @aMultiObj, @oBrowse)
static function _Tabs(GetList, aTabs, aEnvStr, aMultiObj, oBrowse)
LOCAL cId, nColor, nTab, nSubTab, nEnv, cTitle
FOR nTab := TAB_PATH TO TAB_INCLUDE
nEnv := IIF( nTab = TAB_PATH, ENV_PATH, IIF( nTab = TAB_LIB, ENV_USER, ENV_CURRENT))
cId := IIF( nTab = TAB_PATH, "PATH_", IIF( nTab = TAB_LIB, "LIB_", "INCLUDE_"))
nColor := IIF( nTab = TAB_PATH, BD_OUTLOOKRIBLIGHT, IIF( nTab = TAB_LIB, BD_LEDGERGREEN1, BD_PALEYELLOW ))
_getEnvironmentStr(nEnv, aEnvStr)
FOR nSubTab := TAB_SYSTEM TO TAB_CURRENT
cTitle := IIF( nSubTab = TAB_SYSTEM, "System", IIF( nSubTab = TAB_USER, "User", "Current"))
IF nSubTab = TAB_SYSTEM
@ 1.00, 0.00 DCTABPAGE aTabs[nTab,nSubTab] PARENT aTabs[nTab,TAB_PARENT] ;
CAPTION cTitle ;
TABWIDTH 12 TABHEIGHT 20 SIZE 150.80,022.00 ANGLE 00 ;
GOTFOCUS AnchorFocus(cId, cTitle, @aMultiObj[nEnv,nSubTab-1], @oBrowse, GetList) ;
COLOR nColor ;
MAXIMIZEDCOLOR GRA_CLR_BLACK,BD_MICROSOFTGREY ;
ID cId+Upper(cTitle) ;
RESIZE DCGUI_RESIZE_RESIZEONLY
ELSE
@ 0.00, 0.00 DCTABPAGE aTabs[nTab,nSubTab] PARENT aTabs[nTab,TAB_PARENT] ;
CAPTION cTitle ;
RELATIVE aTabs[nTab, nSubTab-1] ;
;// RELATIVE bRel ;
;//GOTFOCUS {|| DC_GetRefresh(GetList,,,,'BUTTONS'), MarkText(oBrowse,aMultiObj[nEnv,i-1]), scFocus := cId+Upper(cTitle), (WTF scFocus COLOR GRA_CLR_RED)} ;
GOTFOCUS AnchorFocus(cId, cTitle, @aMultiObj[nEnv,nSubTab-1], @oBrowse, GetList) ;
COLOR nColor ;
MAXIMIZEDCOLOR GRA_CLR_BLACK,BD_MICROSOFTGREY ;
ID cId+Upper(cTitle) ;
RESIZE DCGUI_RESIZE_RESIZEONLY
ENDIF
@ 1.40, 1.10 DCMULTILINE aEnvStr[nEnv,nSubTab-1] SIZE 148.30, 20.20 ;
OBJECT aMultiObj[nEnv,nSubTab-1] PARENT aTabs[nTab,nSubTab] FONT "12.Courier New" TABSTOP ;
EVAL AnchorCargo(aEnvStr, nEnv, nSubTab, GetList)
;//EVAL {|o|DC_GetCargo(o,aEnvStr[nEnv,i-1])}
NEXT
NEXT
return nil
Code: Select all
::BuildTabs()
METHOD PathUtil:BuildTabs()
LOCAL cId, nColor, nTab, nSubTab, nEnv, cTitle, GetList := ::getList
FOR nTab := TAB_PATH TO TAB_INCLUDE
nEnv := IIF( nTab = TAB_PATH, ENV_PATH, IIF( nTab = TAB_LIB, ENV_USER, ENV_CURRENT))
cId := IIF( nTab = TAB_PATH, "PATH_", IIF( nTab = TAB_LIB, "LIB_", "INCLUDE_"))
nColor := IIF( nTab = TAB_PATH, BD_OUTLOOKRIBLIGHT, IIF( nTab = TAB_LIB, BD_LEDGERGREEN1, BD_PALEYELLOW ))
::GetEnvironmentStr(nEnv)
FOR nSubTab := TAB_SYSTEM TO TAB_CURRENT
cTitle := IIF( nSubTab = TAB_SYSTEM, "System", IIF( nSubTab = TAB_USER, "User", "Current"))
IF nSubTab = TAB_SYSTEM
@ 1.00, 0.00 DCTABPAGE ::tabArray[nTab,nSubTab] PARENT ::tabArray[nTab,TAB_PARENT] ;
CAPTION cTitle ;
TABWIDTH 12 TABHEIGHT 20 SIZE 150.80,022.00 ANGLE 00 ;
GOTFOCUS ::AnchorFocus(cId, cTitle, nEnv,nSubTab-1) ;
COLOR nColor ;
MAXIMIZEDCOLOR GRA_CLR_BLACK,BD_MICROSOFTGREY ;
ID cId+Upper(cTitle) ;
RESIZE DCGUI_RESIZE_RESIZEONLY
ELSE
@ 0.00, 0.00 DCTABPAGE ::tabArray[nTab,nSubTab] PARENT ::tabArray[nTab,TAB_PARENT] ;
CAPTION cTitle ;
RELATIVE ::tabArray[nTab, nSubTab-1] ;
GOTFOCUS ::AnchorFocus(cId, cTitle, nEnv,nSubTab-1) ;
COLOR nColor ;
MAXIMIZEDCOLOR GRA_CLR_BLACK,BD_MICROSOFTGREY ;
ID cId+Upper(cTitle) ;
RESIZE DCGUI_RESIZE_RESIZEONLY
ENDIF
@ 1.40, 1.10 DCMULTILINE ::envirArray[nEnv,nSubTab-1] SIZE 148.30, 20.20 ;
OBJECT ::multiObjArray[nEnv,nSubTab-1] PARENT ::tabArray[nTab,nSubTab] FONT "12.Courier New" TABSTOP ;
EVAL ::AnchorCargo(nEnv, nSubTab)
NEXT
NEXT
RETURN nil