Code Comments
Programming Forum and web based access to our favorite programming groups.Frank Swarbrick wrote: Do about 12 Page Downs to get to my comments, finishing with a question on Components for PECD :- > Oliver Wong<owong@castortech.com> 03/06/06 8:24 AM >>> > > > > Could be. I "learned" OO with C++, which also doesn't have the "factory" > descriptor, so I had never heard of it. And the books I read (err, skimme d) > on OO-COBOL didn't do a very good job explaining it. Of course I don't > recall > I just did a Google search on "OO COBOL FACTORY" and found the following i n > the docs for COBOL for AIX: > "COBOL factory methods are equivalent to public static methods in Java" an d > "COBOL factory data is equivalent to private static data in Java" > Interesting! > One other thing I find confusing about COBOL factories is the position of > the keyword within the code. I would like it to be nearer to the, umm, > object that is a factory. Here's an example from that same manual (how it > actually is): > > -------------------------------------------------------------------------- -- > ---------- > Identification Division. > Class-id. Account inherits Base. > Environment Division. > Configuration section. > Repository. > Class Base is "java.lang.Object" > Class Account is "Account". > * > Identification division. > Factory. > Data division. > Working-storage section. > 01 NumberOfAccounts pic 9(6) value zero. > * > Procedure Division. > * > * createAccount method to create a new Account > * instance, then invoke the OBJECT paragraph's init > * method on the instance to initialize its instance data: > Identification Division. > Method-id. "createAccount". > Data division. > Linkage section. > 01 inAccountNumber pic S9(6) binary. > 01 outAccount object reference Account. > * Facilitate access to JNI services: > Copy JNI. > Procedure Division using by value inAccountNumber > returning outAccount. > * Establish addressability to JNI environment structure: > Set address of JNIEnv to JNIEnvPtr > Set address of JNINativeInterface to JNIEnv > Invoke Account New returning outAccount > Invoke outAccount "init" using by value inAccountNumber > Add 1 to NumberOfAccounts. > End method "createAccount". > * > End Factory. > * > Identification division. > Object. > Data division. > Working-storage section. > 01 AccountNumber pic 9(6). > 01 AccountBalance pic S9(9) value zero. > * > Procedure Division. > * > * init method to initialize the account: > Identification Division. > Method-id. "init". > Data division. > Linkage section. > 01 inAccountNumber pic S9(9) binary. > Procedure Division using by value inAccountNumber. > Move inAccountNumber to AccountNumber. > End method "init". > * > * getBalance method to return the account balance: > Identification Division. > Method-id. "getBalance". > Data division. > Linkage section. > 01 outBalance pic S9(9) binary. > Procedure Division returning outBalance. > Move AccountBalance to outBalance. > End method "getBalance". > * > * credit method to deposit to the account: > Identification Division. > Method-id. "credit". > Data division. > Linkage section. > 01 inCredit pic S9(9) binary. > Procedure Division using by value inCredit. > Add inCredit to AccountBalance. > End method "credit". > * > * debit method to withdraw from the account: > Identification Division. > Method-id. "debit". > Data division. > Linkage section. > 01 inDebit pic S9(9) binary. > Procedure Division using by value inDebit. > Subtract inDebit from AccountBalance. > End method "debit". > * > * print method to display formatted account number and balance: > Identification Division. > Method-id. "print". > Data division. > Local-storage section. > 01 PrintableAccountNumber pic ZZZZZZ999999. > 01 PrintableAccountBalance pic $$$$,$$$,$$9CR. > Procedure Division. > Move AccountNumber to PrintableAccountNumber > Move AccountBalance to PrintableAccountBalance > Display " Account: " PrintableAccountNumber > Display " Balance: " PrintableAccountBalance. > End method "print". > * > End Object. > * > End class Account. > -------------------------------------------------------------------------- -- > ---------- > > But I would prefer something like this: > > -------------------------------------------------------------------------- -- > ---------- > Class-id. Account inherits Base. > Class Base is "java.lang.Object" > Class Account is "Account". > > 01 NumberOfAccounts pic 9(6) FACTORY value zero. > > 01 AccountNumber pic 9(6). > 01 AccountBalance pic S9(9) value zero. > > * createAccount method to create a new Account > * instance, then invoke the OBJECT paragraph's init > * method on the instance to initialize its instance data: > > Method-id. "createAccount" is FACTORY > using by value inAccountNumber > returning outAccount. > 01 inAccountNumber pic S9(6) binary. > 01 outAccount object reference Account. > Copy JNI. > > * Establish addressability to JNI environment structure: > Set address of JNIEnv to JNIEnvPtr > Set address of JNINativeInterface to JNIEnv > set outAccount to Account::New > outAccount::"init" ([value] inAccountNumber) > Add 1 to NumberOfAccounts. > End method. > > * init method to initialize the account: > Method-id. "init" using inAccountNumber. > 01 inAccountNumber pic S9(9) binary. > > Move inAccountNumber to AccountNumber. > End method. > > * getBalance method to return the account balance: > Method-id. "getBalance" returning outBalance. > 01 outBalance pic S9(9) binary. > > Move AccountBalance to outBalance. > End method. > > * credit method to deposit to the account: > Method-id. "credit" using by value inCredit. > 01 inCredit pic S9(9) binary. > > Add inCredit to AccountBalance. > End method. > * > * debit method to withdraw from the account: > Method-id. "debit" using by value inDebit. > 01 inDebit pic S9(9) binary. > > Subtract inDebit from AccountBalance. > End method. > > * print method to display formatted account number and balance: > Method-id. "print". > 01 PrintableAccountNumber pic ZZZZZZ999999. > 01 PrintableAccountBalance pic $$$$,$$$,$$9CR. > > Move AccountNumber to PrintableAccountNumber > Move AccountBalance to PrintableAccountBalance > Display " Account: " PrintableAccountNumber > Display " Balance: " PrintableAccountBalance. > End method. > * > End class Account. > -------------------------------------------------------------------------- -- > > I did several things. I eliminiated all of the DIVISIONS. I attached the > "using" that was specified in the PROCEDURE DIVISION statement and moved i t > to the METHOD-ID statement. I put the FACTORY keyword next to the method or > data element that it is referring to. And probably a few other things tha t > I've already forgotten... > > The resulting code is about 50% smaller (in number of lines, anyway). One > thing I don't have is how to declare "linkage section" items that are not in > a method's "USING/RETURNING" statement. Ah well... Not sure that I understood that last bit - are you thinking of how you store variables related solely to the method - if so, then that's the method's Local-Storage Section. Method-id. "doSomething". *>---------------------- Local-Storage section. 01 ls-TempKounter pic s9(6)v9(05). Procedure Division. compute ls-TempKounter = GlobalKounter1 * 2 compute GlobalKounter2 = ls-TempKounter * 6 End Method "doSomething". *>--------------------------- The two GlobalKounters are in Working-Storage. Above using 'ignore red tape' could be written in M/F as :- Method-id. "doSomething". 01 ls-TempKounter pic s9(6)v9(05). compute ls-TempKounter = GlobalKounter * 2 compute GlobalKounter2 = ls-TempKounter * 6 End Method "doSomething". Your revision certainly has appeal to me. Just using the Micro Focus feature 'ignore red tape' I left out lines where the compiler can currently automatically recognize what's coming up next. Your revised source was roughly 69 lines, mine below some 87 lines. There's no way this will compile in Net Express V 3.1 - Most of it would compile in V 4.0 onwards, although it would hiccup at your copyfile entries. Not having the V 4 compiler it *might* accept some of your references to Java. Here's your example modified to leave out the red tape junk. (I'll leave the comment lines in, just so I don't cheat ) *>--------------------------------------------------------------- Class-id. Account inherits Base. Repository. Class Base is "java.lang.Object" Class Account is "Account". * Factory. Working-storage section. 01 NumberOfAccounts pic 9(6) value zero. * * createAccount method to create a new Account * instance, then invoke the OBJECT paragraph's init * method on the instance to initialize its instance data: Method-id. "createAccount". Linkage section. 01 inAccountNumber pic S9(6) binary. 01 outAccount object reference Account. * Facilitate access to JNI services: Copy JNI. Procedure Division using by value inAccountNumber returning outAccount. * Establish addressability to JNI environment structure: Set address of JNIEnv to JNIEnvPtr Set address of JNINativeInterface to JNIEnv Invoke Account New returning outAccount Invoke outAccount "init" using by value inAccountNumber Add 1 to NumberOfAccounts. End method "createAccount". * End Factory. * Object. Working-storage section. 01 AccountNumber pic 9(6). 01 AccountBalance pic S9(9) value zero. * * init method to initialize the account: Method-id. "init". Linkage section. 01 inAccountNumber pic S9(9) binary. Procedure Division using by value inAccountNumber. Move inAccountNumber to AccountNumber. End method "init". * * getBalance method to return the account balance: Method-id. "getBalance". Linkage section. 01 outBalance pic S9(9) binary. Procedure Division returning outBalance. Move AccountBalance to outBalance. End method "getBalance". * * credit method to deposit to the account: Method-id. "credit". Linkage section. 01 inCredit pic S9(9) binary. Procedure Division using by value inCredit. Add inCredit to AccountBalance. End method "credit". * * debit method to withdraw from the account: Method-id. "debit". Linkage section. 01 inDebit pic S9(9) binary. Procedure Division using by value inDebit. Subtract inDebit from AccountBalance. End method "debit". * * print method to display formatted account number and balance: Method-id. "print". Data division. Local-storage section. 01 PrintableAccountNumber pic ZZZZZZ999999. 01 PrintableAccountBalance pic $$$$,$$$,$$9CR. Procedure Division. Move AccountNumber to PrintableAccountNumber Move AccountBalance to PrintableAccountBalance Display " Account: " PrintableAccountNumber Display " Balance: " PrintableAccountBalance. End method "print". * End Object. * End class Account. --------------------------------------------------------------- Initially liked your idea of shuffling the Linkage syntax to the Method-name line - but it really is shuffling. Look at the following, where having used a class AppHouse(keeping) to create a Cheese Treeview, it returns values to AppDriver. (Having got back to AppDriver I can destroy/finalize AppHouse which is no longer required :- *>------------------------------------------------------------- Method-id. "begin". *>------------------------------------------------------------ Local-storage section. *> <---- could have left this out copy "\copylib\sqlResult.cpy" replacing==(tag)== by ==01 ws==. 01 n pic x(4) comp-5. Linkage section. 01 lnk-Caller object reference. 01 lnk-MakeAstring object reference. 01 lnk-Parent object reference. 01 lnk-Resource object reference. 01 lnk-Objects. 05 lnk-ChoiceDialog object reference. 05 lnk-DBI occurs MaxLevels object reference. 05 lnk-TvControl object reference. 05 lnk-TvDialog object reference. 05 lnk-TvPopup object reference. Procedure Division using lnk-Caller lnk-MakeAstring lnk-Parent lnk-Resource returning lnk-Objects. *> This class performs initial 'housekeepng' and then *> passes control back to AppDrive.cbl :- ETC........... Now it's not often that you want to move a bunch of stuff like above. Possibly 90% plus of your methods have only ONE parameter (an object, pic x or a pic 9). But the above does make it clear what is happening. STATIC DATA : Seeing as I think both you, Oliver and Pete (with reference to his Components), have mentioned it. Went looking in the N/E V 4.0 OO on-line manual - no reference to static, so didn't help much. Now take the example you have shown us. My contention is that the FACTORY method could be in the OBJECT, like so :- The calling program/class which contains in its Repository :- Class Account is "Account". then invokes :- invoke Account "new" returning os-AccountObj invoke os-AccountObj "createAcccount" using thisAccountNumber(binary) returning thisAccount(object) and "createAccount" and the invoked "init" are part and parcel of one method in the OBJECT Section. Then of course you are incrementing the NumberOfAccounts. Real world - we may perhaps statistically want to know the total number of new Accounts we have opened to-day. Now I'll put my wife behind a cash register at the Bay (Hudson's Bay Company). Marketing - "Get as many customers as you can to open a Bay credit card account and we'll give you a voucher for $5". Want to keep tabs on how many accounts Eileen has managed to 'sell' ? You need Number of Accounts but in the the INSTANCE that she is using :- 'z' instances x numberOfAccounts = TotalAccounts at this store which is a pass-back from the individual instances to the Control Program when the cash register is shut down. Same I'm sure would apply with tellers in banks with any promotional schemes you have. Similarly I can't see your Java code would hiccup if it was part of an INSTANCE (OBJECT) method as opposed to a FACTORY method. Java is after all in the example being used to control object creation/destruction. The nearest I came in relevance to FACTORY from my OO Manual was :- ---------------------------------------------------------------------- Data Inheritance A factory object inherits all the factory data of its superclass, and an instance object inherits all the instance data of its superclass. The inherited data of a subclass includes any data that the superclass itself inherited from a class higher up the hierarchy. The inherited object data is initialized when an object is created. The inherited factory data is allocated independently from the factory data of the inherited class or classes when the factory of the subclass is created. A subclass can only access inherited data through the methods it inherited from the same class. For example, if the class Manager inherits from the class Employee, and Employee defines the data item: employeeNumber PIC 999 The Manager class cannot store a value in its inherited employeeNumber data item by using a statement such as: move 100 to employeeNumber Instead it must use a method declared in the Employee class, for example: invoke self "setEmployeeNumber" using 100 The object reference SELF is a reserved name which always refers to the object in which it occurs (see the section .... ------------------------------------------------------------------------- The Factory Object Source Element The factory object source element defines the data and methods for the factory object. It is nested within the class source element, immediately following the class source element's Data Division (if there is one). It looks like this: factory. working-storage section. * factory data . .. * factory methods end factory. The factory object data is defined in the Working-Storage Section. ***The factory object data can only be accessed from the factory methods*** - my Asterisks. ---------------------------------------------------------------------------- Factory Methods Each factory method is a nested source element. The code below shows an outline for a "new" method for Stopwatch. method-id. "new". .. linkage section. 01 lnkWatch object reference. procedure division returning lnkWatch. * code to create and initialize a Stopwatch object. exit method. end method "new". As with the class source element itself, you can declare different types of data in the Data Division of the method. The DATA DIVISION header itself is optional. Data declared here is only accessible to the code in this method. The Data Division can contain any of the following sections: * Local-Storage Section Data items that are local to the current invocation of a method. The method uses local storage for all its temporary working data. This has the advantage of supporting recursion. * Linkage Section Variables passed as parameters to and from the method. The Procedure Division contains the code for the method. You terminate processing of the method with an EXIT METHOD statement. This returns processing to the program which invoked the method. To see the "new" method, use the Editor to locate the "new" method, below tag S015. This method uses a Linkage Section to return data from the method. The Instance Object Source Element The instance object source element defines the data and methods for instances of the class. It is nested within the class source element. It looks like this: object. working-storage section. * instance data for the object. .. * Instance methods end object. The only Data Division section that has any meaning in an object source element is the Working-Storage Section. You can create other data sections, but the run-time behavior if you try to access the data in these sections is undefined. Any data you declare in the Working-Storage Section is accessible to all the instance methods, and may be inherited by instances of subclasses of the class. There is no Procedure Division in an object source element, only methods. To write an initialization method for instances, write a method called "initialize", and then invoke it from the "new" method for the class after you have created an instance. To see the object source element and data declarations paragraph for Stopwatch, use the Editor to locate the OBJECT header. The OBJECT header and Working-Storage Sections are located below tags S030 and S035. Instance Methods Instance methods are nested inside the object source element. Writing an instance method is exactly like writing a factory method, with the only difference being the scope of data which the instance method can access. The instance method can access data: * Declared in the Data Division of the instance method source element * Declared in the Working-Storage Section of the object source element ---------------------------------------------------------------------------- Now just tracking to N/E sample on 'Bank Accounts' - what else; that's what they all use. They do use FACTORY similar to above to create a new account. But is that just doing it by rote because that's the perceived way that everybody does it, regardless of language. Or are FACTORY methods irrelevant and they could be contained in the OBJECT ? You Java boys convey how static gets used in Java, to counter what I've written above. Pete, above is not complete references. However where it says, "***The factory object data can only be accessed from the factory methods*** ". If you are passing parameters/properties for Components to FACTORY how do they get referenced from Instance/Object methods ? Jimmy
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.