Converting Functions to Methods

This forum is for posting of useful information
Post Reply
Message
Author
User avatar
rdonnay
Site Admin
Posts: 4283
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Converting Functions to Methods

#1 Post by rdonnay »

At the eXpress++ devcon in 2015, there were many eXpress++ users who were still not comfortable with programming using Object Oriented methodology. They especially were not convinced that OOPS programming was better or more productive than Function based programming.

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
OOPS based:

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
Attachments
pathutil.zip
(37.35 KiB) Downloaded 613 times
The eXpress train is coming - and it has more cars.

User avatar
SbDrakos
Posts: 140
Joined: Thu Jan 28, 2010 10:27 am
Location: NYC

Re: Converting Functions to Methods

#2 Post by SbDrakos »

Roger,

Good job. :clap:

Bobby

Post Reply