MainframeMaster

COBOL Tutorial

Object-Oriented COBOL

Progress0 of 0 lessons

Introduction to Object-Oriented COBOL

Object-Oriented COBOL (OO COBOL) represents a significant evolution in COBOL programming, bringing object-oriented principles to this long-established language. This extension allows COBOL programmers to leverage the benefits of object-oriented programming while maintaining compatibility with traditional procedural COBOL code.

What is Object-Oriented Programming?

Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects," which can contain data and code. The key principles include:

  • Encapsulation: Bundling data and methods that operate on that data into a single unit (class)
  • Inheritance: Creating new classes that inherit properties and behaviors from existing classes
  • Polymorphism: Allowing methods to do different things based on the object they are acting upon
  • Abstraction: Hiding complex implementation details behind simple interfaces

Historical Context of OO COBOL

The evolution of Object-Oriented COBOL followed these key developments:

YearDevelopmentSignificance
1997OO features proposed for COBOL standardInitial recognition of OOP importance for COBOL's future
2002OO features included in COBOL 2002 standardFirst official OO support in the COBOL language standard
Early 2000sVendor implementations of OO COBOLIBM, Micro Focus, and others add OOP capabilities
2014COBOL 2014 standard refines OO featuresImproved standard based on implementation experience
2010s-PresentIntegration with Java, .NET, and web servicesOO COBOL used as bridge between legacy and modern systems

Comparing Procedural and Object-Oriented COBOL

AspectProcedural COBOLObject-Oriented COBOL
Program StructureBased on divisions, sections, paragraphsBased on classes, methods, objects
Data OrganizationData separate from proceduresData encapsulated with methods in classes
Code ReuseThrough copybooks and subprogramsThrough inheritance and composition
Runtime BehaviorStatic structure determined at compile timeDynamic object creation and method dispatch
SyntaxTraditional COBOL syntaxExtended with CLASS-ID, METHOD-ID, etc.
Interface with Modern SystemsRequires additional mapping layersMore natural integration with OO systems

Benefits of Object-Oriented COBOL

Improved Maintainability

Encapsulation and modular design make OO COBOL code easier to understand and maintain, with changes localized to specific classes.

Enhanced Reusability

Classes can be reused across applications, reducing duplication and promoting consistent implementation.

Better Integration

OO COBOL integrates more naturally with Java, C#, and other object-oriented systems, simplifying interoperability.

Skills Transferability

Developers familiar with other OO languages can more easily transition to COBOL when it follows OO principles.

Gradual Migration Path

Organizations can incrementally update legacy systems by introducing OO components while maintaining procedural code.

More Natural Modeling

Business entities can be modeled as objects, creating a closer match between real-world concepts and code.

When to Use Object-Oriented COBOL

OO COBOL is particularly valuable in these scenarios:

  • New Development: For new systems where OO design makes sense from the start
  • Modernization: When updating legacy systems to modern architectures
  • Integration: For components that interact with Java, .NET, or web services
  • Complex Domain Models: When working with rich business domains with complex relationships
  • Team Diversity: In teams with developers familiar with other OO languages
  • Framework Development: When building reusable components for multiple applications

OO COBOL Fundamentals

Object-Oriented COBOL introduces several fundamental concepts and syntax elements that create the foundation for object-oriented programming in the COBOL language. Understanding these fundamentals is essential for developing effective OO COBOL applications.

Basic OO COBOL Structure

An Object-Oriented COBOL program typically consists of one or more class definitions that encapsulate data and behavior:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
***************************************************************** * Basic class definition structure in OO COBOL ***************************************************************** Identification Division. Class-Id. Customer. Environment Division. Configuration Section. Repository. Class Address As "Address" Class Transaction As "Transaction" Class Base Inherits From "BaseEntity". Data Division. Working-Storage Section. 01 Customer-ID Pic 9(10). 01 Customer-Name Pic X(50). 01 Customer-Email Pic X(100). 01 Customer-Status Pic X. 88 Customer-Active Value "A". 88 Customer-Inactive Value "I". 88 Customer-Suspended Value "S". ***************************************************************** * Object section defines instance data ***************************************************************** Object Section. Object-Storage Section. 01 Billing-Address Object Reference Address. 01 Shipping-Address Object Reference Address. 01 Recent-Transactions Object Reference Transaction Occurs 10 Times. 01 Transaction-Count Pic 9(2) Value Zero. ***************************************************************** * Instance methods define behavior for objects ***************************************************************** Procedure Division. Method-Id. "New". Procedure Division Using Customer-ID As Pic 9(10) Customer-Name As Pic X(50). Move Customer-ID To Self::Customer-ID Move Customer-Name To Self::Customer-Name Set Customer-Active To True Exit Method. End Method "New". Method-Id. "GetName". Procedure Division Returning Customer-Name As Pic X(50). Move Self::Customer-Name To Customer-Name Exit Method. End Method "GetName". Method-Id. "AddTransaction". Procedure Division Using Transaction-Obj As Object Reference Transaction. If Transaction-Count < 10 Add 1 To Transaction-Count Set Recent-Transactions(Transaction-Count) To Transaction-Obj End-If Exit Method. End Method "AddTransaction". End Object. ***************************************************************** * Factory section defines class-level (static) behavior ***************************************************************** Factory Section. Factory-Storage Section. 01 Total-Customers Pic 9(5) Value Zero. Procedure Division. Method-Id. "GetCustomerCount". Procedure Division Returning Count As Pic 9(5). Move Total-Customers To Count Exit Method. End Method "GetCustomerCount". Method-Id. "CreateCustomer". Procedure Division Using ID As Pic 9(10) Name As Pic X(50) Returning Customer-Obj As Object Reference Customer. Invoke Self::New Using ID, Name Returning Customer-Obj Add 1 To Total-Customers Exit Method. End Method "CreateCustomer". End Factory. End Class Customer.

Key OO COBOL Elements

ElementPurposeExample
CLASS-IDDefines a classClass-Id. Customer.
REPOSITORYDefines external class referencesClass Address As "Address"
INHERITS FROMEstablishes inheritance relationshipClass Base Inherits From "BaseEntity"
OBJECT SECTIONContains instance data and methodsObject Section.
FACTORY SECTIONContains class data and methodsFactory Section.
METHOD-IDDefines a methodMethod-Id. "GetName".
OBJECT REFERENCEDeclares an object referenceObject Reference Customer
SELFReferences the current objectSelf::Customer-Name
INVOKECalls a method on an objectInvoke Customer-Obj "GetName"
SUPERReferences parent class methodsInvoke Super "Initialize"

Understanding Classes and Objects

In OO COBOL, classes and objects follow these principles:

  • Class Definition: A class in COBOL is a template that defines the properties and behaviors of a particular type of object. It's defined using the CLASS-ID division.
  • Object Instantiation: Objects are instances of classes created at runtime using methods, typically through a factory method or constructor.
    cobol
    1
    2
    3
    4
    5
    * Creating an object Declare WS-Customer As Object Reference Customer Invoke Customer "CreateCustomer" Using 1234567890, "John Smith" Returning WS-Customer
  • Instance Data: Each object has its own copy of instance data defined in the OBJECT-STORAGE SECTION.
  • Class Data: Data shared across all instances of a class is defined in the FACTORY-STORAGE SECTION.
  • Method Invocation: Methods are invoked on objects using the INVOKE statement, which can pass parameters and receive return values.
    cobol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    * Invoking methods on an object Declare WS-Name As Pic X(50) Invoke WS-Customer "GetName" Returning WS-Name Declare WS-Transaction As Object Reference Transaction Invoke Transaction "CreateTransaction" Using 500.00, "Purchase" Returning WS-Transaction Invoke WS-Customer "AddTransaction" Using WS-Transaction

Object References and Memory Management

Object-Oriented COBOL uses object references to work with objects:

  • Object References: Variables that refer to objects (not the objects themselves)
  • NULL References: Object references can be NULL when they don't refer to any object
  • Reference Assignment: Use SET statement to assign references
  • Comparison: Use "=" or "NOT =" to compare references
  • Automatic Memory Management: Many OO COBOL implementations include garbage collection
  • Explicit Release: Some implementations allow manual release of object references
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
* Object reference management Working-Storage Section. 01 Customer-Ref Object Reference Customer. 01 Another-Ref Object Reference Customer. 01 Generic-Ref Object Reference. Procedure Division. * Initialize reference to NULL Set Customer-Ref To Null * Create a new object Invoke Customer "CreateCustomer" Using 1234567890, "Jane Doe" Returning Customer-Ref * Assign one reference to another Set Another-Ref To Customer-Ref * Check for NULL reference If Customer-Ref = Null Display "No customer object" End-If * Compare references If Customer-Ref = Another-Ref Display "Same object" End-If * Set to NULL to release reference (if no garbage collection) Set Customer-Ref To Null Set Another-Ref To Null

Factory vs. Object Methods

Understanding the difference between factory and object methods is crucial in OO COBOL:

CharacteristicFactory MethodsObject Methods
Definition LocationFACTORY SECTIONOBJECT SECTION
Associated WithThe class as a wholeIndividual object instances
InvocationOn the classOn an object
Data AccessFactory-Storage dataObject-Storage data
Common UsesConstructors, utilities, countersObject behavior, data manipulation
ExampleInvoke Customer "CreateCustomer"Invoke Customer-Obj "GetName"

Inheritance and Polymorphism

Inheritance and polymorphism are core concepts in object-oriented programming that allow for code reuse and flexibility. OO COBOL implements these concepts with its own syntax while maintaining the fundamental principles found in other object-oriented languages.

Implementing Inheritance in COBOL

Inheritance in OO COBOL is established in the CLASS-ID paragraph using the INHERITS clause:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
***************************************************************** * Account class - base class for different account types ***************************************************************** Identification Division. Class-Id. Account. Environment Division. Configuration Section. Repository. Class Customer As "Customer". Object Section. Object-Storage Section. 01 Account-Number Pic X(10). 01 Account-Balance Pic S9(9)V99. 01 Account-Owner Object Reference Customer. Procedure Division. Method-Id. "GetBalance". Procedure Division Returning Balance As Pic S9(9)V99. Move Account-Balance To Balance Exit Method. End Method "GetBalance". Method-Id. "Deposit". Procedure Division Using Amount As Pic S9(9)V99. Add Amount To Account-Balance Exit Method. End Method "Deposit". Method-Id. "Withdraw". Procedure Division Using Amount As Pic S9(9)V99 Returning Success As Pic 9 Value 0. If Amount <= Account-Balance Subtract Amount From Account-Balance Move 1 To Success End-If Exit Method. End Method "Withdraw". End Object. End Class Account. ***************************************************************** * CheckingAccount class - inherits from Account ***************************************************************** Identification Division. Class-Id. CheckingAccount Inherits From Account. Environment Division. Configuration Section. Repository. Class Customer As "Customer". Object Section. Object-Storage Section. 01 Overdraft-Limit Pic S9(7)V99 Value 500. 01 Monthly-Fee Pic S9(3)V99 Value 10. Procedure Division. * Override the Withdraw method to allow overdrafts Method-Id. "Withdraw". Procedure Division Using Amount As Pic S9(9)V99 Returning Success As Pic 9 Value 0. Declare Balance As Pic S9(9)V99 * Call the GetBalance method to get current balance Invoke Self "GetBalance" Returning Balance * Check if withdrawal is within overdraft limit If Amount <= (Balance + Overdraft-Limit) * Call parent's (superclass) method to update balance Invoke Super "Withdraw" Using Amount Returning Success * If parent method failed (insufficient regular balance), * but we have overdraft available, handle it here If Success = 0 Subtract Amount From Self::Account-Balance Move 1 To Success End-If End-If Exit Method. End Method "Withdraw". Method-Id. "ApplyMonthlyFee". Procedure Division. Subtract Monthly-Fee From Self::Account-Balance Exit Method. End Method "ApplyMonthlyFee". End Object. End Class CheckingAccount.

Key Inheritance Concepts

  • Single Inheritance: OO COBOL supports single inheritance only—a class can inherit from only one parent class.
  • Method Inheritance: A subclass automatically inherits all methods from its parent class.
  • Method Overriding: A subclass can override a parent's method by defining a method with the same name.
    cobol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    * Parent class method Method-Id. "Withdraw". Procedure Division Using Amount As Pic S9(9)V99 Returning Success As Pic 9 Value 0. If Amount <= Account-Balance Subtract Amount From Account-Balance Move 1 To Success End-If Exit Method. End Method "Withdraw". * Child class overriding the method Method-Id. "Withdraw". Procedure Division Using Amount As Pic S9(9)V99 Returning Success As Pic 9 Value 0. If Amount <= (Balance + Overdraft-Limit) * Different implementation allowing overdraft Subtract Amount From Self::Account-Balance Move 1 To Success End-If Exit Method. End Method "Withdraw".
  • The SUPER Reference: Use the SUPER reference to invoke a parent class's method from within an overriding method.
    cobol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    * Using SUPER to call parent's method Method-Id. "Withdraw". Procedure Division Using Amount As Pic S9(9)V99 Returning Success As Pic 9 Value 0. * Try the standard withdrawal first Invoke Super "Withdraw" Using Amount Returning Success * Add custom logic if parent's method fails If Success = 0 If Amount <= Overdraft-Limit * Apply overdraft logic Subtract Amount From Self::Account-Balance Move 1 To Success End-If End-If Exit Method. End Method "Withdraw".
  • Constructors in Inheritance: Subclass constructors often need to invoke the parent's constructor.
    cobol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    * Parent class constructor Method-Id. "New". Procedure Division Using Acct-Number As Pic X(10) Owner As Object Reference Customer. Move Acct-Number To Account-Number Set Account-Owner To Owner Move Zero To Account-Balance Exit Method. End Method "New". * Subclass constructor calling parent constructor Method-Id. "New". Procedure Division Using Acct-Number As Pic X(10) Owner As Object Reference Customer Initial-Overdraft As Pic S9(7)V99. * Call parent constructor first Invoke Super "New" Using Acct-Number, Owner * Then initialize subclass-specific data Move Initial-Overdraft To Overdraft-Limit Exit Method. End Method "New".

Polymorphism in OO COBOL

Polymorphism allows different objects to respond differently to the same method call. In OO COBOL, this is accomplished through method overriding and using parent class references to refer to objects of any subclass.

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
* Polymorphic behavior example Working-Storage Section. 01 Account-Ref Object Reference Account. 01 Checking-Ref Object Reference CheckingAccount. 01 Savings-Ref Object Reference SavingsAccount. 01 Customer-Ref Object Reference Customer. 01 Success-Flag Pic 9 Value 0. Procedure Division. * Create a customer object Invoke Customer "CreateCustomer" Using 1234567890, "John Smith" Returning Customer-Ref * Create different account objects Invoke CheckingAccount "New" Using "CHK1000001", Customer-Ref, 1000 Returning Checking-Ref Invoke SavingsAccount "New" Using "SAV2000001", Customer-Ref, 2.5 Returning Savings-Ref * Polymorphic assignment - parent reference to child object Set Account-Ref To Checking-Ref * Deposit the same way regardless of account type Invoke Account-Ref "Deposit" Using 500 * The actual method executed depends on the object type * This will use CheckingAccount's Withdraw implementation Invoke Account-Ref "Withdraw" Using 700 Returning Success-Flag * Now reference a different account type Set Account-Ref To Savings-Ref * Same method call but different behavior * This will use SavingsAccount's Withdraw implementation Invoke Account-Ref "Withdraw" Using 300 Returning Success-Flag * Process a collection of accounts polymorphically Perform Process-Monthly-Accounts Stop Run. Process-Monthly-Accounts. * This demonstrates processing different account types uniformly * All accounts can handle these methods, but each type behaves differently Perform Varying Acct-Index From 1 By 1 Until Acct-Index > Acct-Count * Common operations for all account types Invoke Account-Array(Acct-Index) "CalculateInterest" * CheckingAccount-specific operation - handled with a type check Invoke Account-Array(Acct-Index) "GetAccountType" Returning Acct-Type If Acct-Type = "CHECKING" Invoke Account-Array(Acct-Index) "ApplyMonthlyFee" End-If End-Perform.

Type Checking and Casting

Sometimes you need to check the actual type of an object or convert between types:

  • Universal Base Class: OO COBOL often includes a base class (like "Universal" or "Object") from which all classes inherit.
  • Type Checking: The "INVOKE class-name::TYPEOF" method can be used to check an object's type in some implementations.
    cobol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    * Type checking example Invoke Universal "TypeOf" Using By Value Account-Ref Returning Type-Name If Type-Name = "CheckingAccount" * Type-specific operations Invoke Account-Ref "ApplyMonthlyFee" End-If
  • Type Casting: To access subclass-specific methods, you may need to cast a reference from a parent type to a child type.
    cobol
    1
    2
    3
    4
    5
    6
    7
    8
    * Type casting example If Universal "TypeOf" Account-Ref = "CheckingAccount" * Cast parent class reference to more specific type Set Checking-Ref To Account-Ref * Now we can call CheckingAccount-specific methods Invoke Checking-Ref "SetOverdraftLimit" Using 2000 End-If

Object-Oriented Design Patterns

Common OO design patterns can be implemented in COBOL to solve recurring design problems:

PatternUse CasesImplementation Approach
Factory MethodObject creation with specific initializationFactory methods in the FACTORY SECTION
SingletonSingle instance of a service classFactory method with instance tracking
StrategyDifferent algorithms for a taskClasses with common interface methods
ObserverEvent notification between objectsListener objects that implement update methods
AdapterCompatible interfaces between systemsWrapper classes around existing functionality

Practical Examples

Let's examine complete, practical examples of Object-Oriented COBOL to demonstrate how these concepts can be applied in real-world scenarios. These examples illustrate common patterns and implementation techniques.

Example 1: Customer Management System

A simple but complete example of a customer management system showing multiple classes with relationships:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
***************************************************************** * Address class ***************************************************************** Identification Division. Class-Id. Address. Object Section. Object-Storage Section. 01 Street Pic X(50). 01 City Pic X(30). 01 State Pic X(2). 01 Zip-Code Pic X(10). Procedure Division. Method-Id. "New". Procedure Division Using Street-In As Pic X(50) City-In As Pic X(30) State-In As Pic X(2) Zip-In As Pic X(10). Move Street-In To Street Move City-In To City Move State-In To State Move Zip-In To Zip-Code Exit Method. End Method "New". Method-Id. "FormatFullAddress". Procedure Division Returning Full-Address As Pic X(100). String Street Delimited By Space ", " Delimited By Size City Delimited By Space ", " Delimited By Size State Delimited By Space " " Delimited By Size Zip-Code Delimited By Space Into Full-Address Exit Method. End Method "FormatFullAddress". End Object. End Class Address. ***************************************************************** * Person class - base class for customer types ***************************************************************** Identification Division. Class-Id. Person. Environment Division. Configuration Section. Repository. Class Address As "Address". Object Section. Object-Storage Section. 01 Person-ID Pic 9(10). 01 First-Name Pic X(30). 01 Last-Name Pic X(30). 01 Home-Address Object Reference Address. Procedure Division. Method-Id. "New". Procedure Division Using ID As Pic 9(10) First As Pic X(30) Last As Pic X(30). Move ID To Person-ID Move First To First-Name Move Last To Last-Name Exit Method. End Method "New". Method-Id. "SetAddress". Procedure Division Using Addr As Object Reference Address. Set Home-Address To Addr Exit Method. End Method "SetAddress". Method-Id. "GetFullName". Procedure Division Returning Name As Pic X(61). String First-Name Delimited By Space " " Delimited By Size Last-Name Delimited By Space Into Name Exit Method. End Method "GetFullName". End Object. End Class Person. ***************************************************************** * Customer class - inherits from Person with added functionality ***************************************************************** Identification Division. Class-Id. Customer Inherits From Person. Environment Division. Configuration Section. Repository. Class Address As "Address" Class Order As "Order". Object Section. Object-Storage Section. 01 Customer-Type Pic X Value "R". 88 Regular-Customer Value "R". 88 Premium-Customer Value "P". 88 Wholesale-Customer Value "W". 01 Credit-Limit Pic 9(7)V99 Value 1000. 01 Orders Object Reference Order Occurs 0 To 100 Times Depending On Order-Count. 01 Order-Count Pic 9(3) Value Zero. Procedure Division. Method-Id. "New". Procedure Division Using ID As Pic 9(10) First As Pic X(30) Last As Pic X(30) Cust-Type As Pic X. * Call parent constructor Invoke Super "New" Using ID, First, Last * Initialize customer-specific data Move Cust-Type To Customer-Type * Set credit limit based on customer type Evaluate Customer-Type When "R" Move 1000 To Credit-Limit When "P" Move 5000 To Credit-Limit When "W" Move 10000 To Credit-Limit End-Evaluate Exit Method. End Method "New". Method-Id. "AddOrder". Procedure Division Using New-Order As Object Reference Order Returning Success As Pic 9 Value 0. If Order-Count < 100 Add 1 To Order-Count Set Orders(Order-Count) To New-Order Move 1 To Success End-If Exit Method. End Method "AddOrder". Method-Id. "UpgradeCustomerType". Procedure Division. Evaluate Customer-Type When "R" Move "P" To Customer-Type Move 5000 To Credit-Limit When "P" Move "W" To Customer-Type Move 10000 To Credit-Limit End-Evaluate Exit Method. End Method "UpgradeCustomerType". Method-Id. "GetTotalOrderValue". Procedure Division Returning Total As Pic 9(10)V99. Declare Order-Ref As Object Reference Order Declare Order-Total As Pic 9(8)V99 Move Zero To Total Perform Varying I From 1 By 1 Until I > Order-Count Set Order-Ref To Orders(I) Invoke Order-Ref "GetTotal" Returning Order-Total Add Order-Total To Total End-Perform Exit Method. End Method "GetTotalOrderValue". End Object. Factory Section. Factory-Storage Section. 01 Next-Customer-ID Pic 9(10) Value 1000000001. 01 Total-Customers Pic 9(5) Value Zero. Procedure Division. Method-Id. "CreateCustomer". Procedure Division Using First As Pic X(30) Last As Pic X(30) Cust-Type As Pic X Returning Cust As Object Reference Customer. Invoke Self "New" Using Next-Customer-ID, First, Last, Cust-Type Returning Cust Add 1 To Next-Customer-ID Add 1 To Total-Customers Exit Method. End Method "CreateCustomer". Method-Id. "GetCustomerCount". Procedure Division Returning Count As Pic 9(5). Move Total-Customers To Count Exit Method. End Method "GetCustomerCount". End Factory. End Class Customer. ***************************************************************** * Order class ***************************************************************** Identification Division. Class-Id. Order. Object Section. Object-Storage Section. 01 Order-ID Pic 9(8). 01 Order-Date Pic X(8). *> YYYYMMDD format 01 Order-Total Pic 9(8)V99. 01 Order-Status Pic X. 88 Order-Pending Value "P". 88 Order-Shipped Value "S". 88 Order-Completed Value "C". 88 Order-Cancelled Value "X". Procedure Division. Method-Id. "New". Procedure Division Using ID As Pic 9(8) Date As Pic X(8) Total As Pic 9(8)V99. Move ID To Order-ID Move Date To Order-Date Move Total To Order-Total Set Order-Pending To True Exit Method. End Method "New". Method-Id. "GetTotal". Procedure Division Returning Total As Pic 9(8)V99. Move Order-Total To Total Exit Method. End Method "GetTotal". Method-Id. "ShipOrder". Procedure Division. If Order-Pending Set Order-Shipped To True End-If Exit Method. End Method "ShipOrder". Method-Id. "CompleteOrder". Procedure Division. If Order-Shipped Set Order-Completed To True End-If Exit Method. End Method "CompleteOrder". Method-Id. "CancelOrder". Procedure Division Returning Success As Pic 9 Value 0. If Order-Pending Set Order-Cancelled To True Move 1 To Success End-If Exit Method. End Method "CancelOrder". End Object. Factory Section. Factory-Storage Section. 01 Next-Order-ID Pic 9(8) Value 10000001. Procedure Division. Method-Id. "CreateOrder". Procedure Division Using Date As Pic X(8) Total As Pic 9(8)V99 Returning Ord As Object Reference Order. Invoke Self "New" Using Next-Order-ID, Date, Total Returning Ord Add 1 To Next-Order-ID Exit Method. End Method "CreateOrder". End Factory. End Class Order. ***************************************************************** * Main program using the classes ***************************************************************** Identification Division. Program-Id. "CustomerOrderDemo". Environment Division. Configuration Section. Repository. Class Customer As "Customer" Class Order As "Order" Class Address As "Address". Data Division. Working-Storage Section. 01 Customer1 Object Reference Customer. 01 Customer2 Object Reference Customer. 01 New-Order Object Reference Order. 01 Home-Address Object Reference Address. 01 Customer-Name Pic X(61). 01 Order-Total Pic 9(8)V99. 01 Customer-Total Pic 9(10)V99. 01 Customer-Count Pic 9(5). 01 Success-Flag Pic 9. 01 Current-Date Pic X(8). Procedure Division. * Get current date for orders Accept Current-Date From Date Yyyymmdd * Create customers Invoke Customer "CreateCustomer" Using "John", "Smith", "R" Returning Customer1 Invoke Customer "CreateCustomer" Using "Jane", "Doe", "P" Returning Customer2 * Create and assign addresses Invoke Address "New" Using "123 Main St", "Anytown", "CA", "90001" Returning Home-Address Invoke Customer1 "SetAddress" Using Home-Address Invoke Address "New" Using "456 Oak Ave", "Somewhere", "NY", "10001" Returning Home-Address Invoke Customer2 "SetAddress" Using Home-Address * Create orders for Customer1 Invoke Order "CreateOrder" Using Current-Date, 125.99 Returning New-Order Invoke Customer1 "AddOrder" Using New-Order Returning Success-Flag Invoke Order "CreateOrder" Using Current-Date, 499.95 Returning New-Order Invoke Customer1 "AddOrder" Using New-Order Returning Success-Flag * Create orders for Customer2 Invoke Order "CreateOrder" Using Current-Date, 1299.99 Returning New-Order Invoke Customer2 "AddOrder" Using New-Order Returning Success-Flag * Get customer information Invoke Customer1 "GetFullName" Returning Customer-Name Display "Customer: " Customer-Name Invoke Customer1 "GetTotalOrderValue" Returning Customer-Total Display "Total orders: $" Customer-Total * Upgrade Customer1 to premium status Invoke Customer1 "UpgradeCustomerType" * Get total customer count Invoke Customer "GetCustomerCount" Returning Customer-Count Display "Total customers: " Customer-Count Stop Run. End Program "CustomerOrderDemo".

Example 2: Implementing a Design Pattern - Singleton Factory

This example demonstrates a Singleton pattern implementation in OO COBOL:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
***************************************************************** * DatabaseConnection class using the Singleton pattern ***************************************************************** Identification Division. Class-Id. DatabaseConnection. Object Section. Object-Storage Section. 01 Connection-String Pic X(100). 01 Connection-Status Pic X. 88 Connected Value "C". 88 Disconnected Value "D". 01 Last-Error Pic X(100). Procedure Division. * Private constructor - can only be called from the factory Method-Id. "New". Procedure Division Using Conn-String As Pic X(100). Move Conn-String To Connection-String Set Disconnected To True Move Spaces To Last-Error Exit Method. End Method "New". Method-Id. "Connect". Procedure Division Returning Result As Pic 9 Value 0. * In a real application, this would contain actual database connection logic Display "Connecting to database: " Connection-String * Simulate connection success Set Connected To True Move 1 To Result Exit Method. End Method "Connect". Method-Id. "Disconnect". Procedure Division. * In a real application, this would contain actual disconnect logic If Connected Display "Disconnecting from database" Set Disconnected To True End-If Exit Method. End Method "Disconnect". Method-Id. "ExecuteQuery". Procedure Division Using Query As Pic X(500) Returning Success As Pic 9 Value 0. * In a real application, this would execute the SQL query If Connected Display "Executing query: " Query Move 1 To Success Else Move "Not connected to database" To Last-Error End-If Exit Method. End Method "ExecuteQuery". Method-Id. "GetLastError". Procedure Division Returning Error As Pic X(100). Move Last-Error To Error Exit Method. End Method "GetLastError". End Object. Factory Section. Factory-Storage Section. * Single instance of the connection - core of the Singleton pattern 01 The-Instance Object Reference DatabaseConnection. Procedure Division. Method-Id. "GetInstance". Procedure Division Using Conn-String As Pic X(100) Optional Returning Instance As Object Reference DatabaseConnection. * If instance doesn't exist, create it If The-Instance = Null * Check if connection string is provided If Conn-String Not = Spaces Invoke Self "New" Using Conn-String Returning The-Instance Else * Use default connection if none provided Invoke Self "New" Using "Server=localhost;Database=MainDB;User=admin;Password=******" Returning The-Instance End-If End-If * Return the single instance Set Instance To The-Instance Exit Method. End Method "GetInstance". End Factory. End Class DatabaseConnection. ***************************************************************** * Program demonstrating Singleton usage ***************************************************************** Identification Division. Program-Id. "SingletonDemo". Environment Division. Configuration Section. Repository. Class DatabaseConnection As "DatabaseConnection". Data Division. Working-Storage Section. 01 DB-Connection Object Reference DatabaseConnection. 01 Another-Connection Object Reference DatabaseConnection. 01 Success-Flag Pic 9 Value 0. 01 Error-Text Pic X(100). Procedure Division. * Get the database connection instance Invoke DatabaseConnection "GetInstance" Using "Server=proddb;Database=Inventory;User=app_user;Password=******" Returning DB-Connection * Connect to the database Invoke DB-Connection "Connect" Returning Success-Flag If Success-Flag = 1 * Execute a query Invoke DB-Connection "ExecuteQuery" Using "SELECT * FROM products WHERE stock < 10" Returning Success-Flag * Get another reference to the same connection Invoke DatabaseConnection "GetInstance" Returning Another-Connection * Both references point to the same object (Singleton pattern) If DB-Connection = Another-Connection Display "Singleton pattern confirmed - both references point to the same object" End-If * We can use either reference to work with the connection Invoke Another-Connection "ExecuteQuery" Using "UPDATE products SET reorder = 'Y' WHERE stock < 10" Returning Success-Flag * Disconnect when done Invoke DB-Connection "Disconnect" Else Invoke DB-Connection "GetLastError" Returning Error-Text Display "Connection error: " Error-Text End-If Stop Run. End Program "SingletonDemo".

OO Design in COBOL

Effective Object-Oriented COBOL requires thoughtful design approaches. This section covers best practices, common pitfalls, and strategies for successful OO COBOL development.

OO Design Principles for COBOL

PrincipleDescriptionCOBOL Application
Single ResponsibilityA class should have only one reason to changeCreate focused classes for specific business entities or functions
Open/ClosedOpen for extension, closed for modificationUse inheritance instead of modifying existing classes
Liskov SubstitutionSubtypes must be substitutable for their base typesDesign consistent method behaviors across inheritance hierarchies
Interface SegregationNo client should depend on methods it doesn't useCreate cohesive classes with focused method sets
Dependency InversionDepend on abstractions, not concretionsUse parent class references to refer to objects

Designing Class Hierarchies

Effective class hierarchies are central to OO COBOL development:

  • Identify Common Behaviors: Find shared functionality to place in parent classes
  • Use "Is-A" Relationships: Only inherit when a true "is-a" relationship exists
  • Keep Hierarchies Shallow: Avoid deep inheritance chains that become difficult to maintain
  • Design for Extension: Consider how classes might be extended in the future
  • Favor Composition: Use "has-a" relationships through object references when appropriate
  • Consider Interfaces: Design for polymorphism by focusing on method contracts
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
* Example of a well-designed class hierarchy * Base class for all financial instruments Class-Id. FinancialInstrument. * Specific types of financial instruments Class-Id. BankAccount Inherits From FinancialInstrument. Class-Id. Investment Inherits From FinancialInstrument. * Further specialization Class-Id. CheckingAccount Inherits From BankAccount. Class-Id. SavingsAccount Inherits From BankAccount. Class-Id. Stock Inherits From Investment. Class-Id. Bond Inherits From Investment. * Composition example - Customer has accounts rather than inheriting Class-Id. Customer. Object-Storage Section. 01 Accounts Object Reference FinancialInstrument Occurs 0 To 20 Times Depending On Account-Count.

Common OO COBOL Challenges and Solutions

ChallengeSolution
Performance Overhead
  • Limit object creation in performance-critical paths
  • Use object pooling for frequently created objects
  • Optimize method calls in tight loops
Legacy Code Integration
  • Create wrapper classes around legacy functionality
  • Use adapter pattern for integrating procedural code
  • Gradually refactor rather than rewrite
Memory Management
  • Explicitly set references to NULL when done
  • Understand implementation's garbage collection approach
  • Avoid circular references if possible
Deep Hierarchies
  • Favor composition over inheritance for complex structures
  • Consider redesigning to flatten hierarchies
  • Use helper classes for shared functionality
Testing Challenges
  • Create mock objects for testing dependencies
  • Implement factory methods that can be overridden for tests
  • Design for testability with injectable dependencies

Migration Strategies

Transitioning from procedural to Object-Oriented COBOL:

  1. Analysis Phase: Identify components that would benefit most from OO conversion.
    • Look for related data structures and procedures
    • Focus on areas with frequent changes
    • Consider interfaces with other systems
  2. Incremental Approach: Gradually convert components rather than all at once.
    • Start with less critical, well-isolated components
    • Create wrapper classes for existing functionality
    • Build new features using OO techniques
  3. Hybrid Design: Allow procedural and OO code to coexist and interoperate.
    • Create callable interfaces between paradigms
    • Use procedural entry points for OO components
    • Maintain consistent data representations
  4. Testing Strategy: Ensure behavior remains consistent during migration.
    • Create comprehensive test cases before conversion
    • Verify identical outputs after conversion
    • Implement regression testing automation
  5. Training and Documentation: Prepare team for the paradigm shift.
    • Provide OO concepts and COBOL-specific OO training
    • Develop internal standards and patterns
    • Document design decisions and class relationships

Interoperability with Other Technologies

OO COBOL can interface with other technologies:

  • Java Integration: Many OO COBOL implementations provide direct interfaces to Java.
    cobol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    * Example of COBOL calling Java Environment Division. Configuration Section. Repository. Class JString As "java.lang.String" Class JMath As "java.lang.Math". Working-Storage Section. 01 Java-String Object Reference JString. 01 Result Object Reference JString. 01 Pi-Value Float-Long. Procedure Division. * Create a Java String Invoke JString "new" Using "COBOL calling Java" Returning Java-String * Call Java String method Invoke Java-String "toUpperCase" Returning Result * Get PI from Java Math class Invoke JMath "PI" Returning Pi-Value Display Pi-Value
  • .NET Integration: Some OO COBOL products integrate with .NET Framework.
    cobol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    * Example of COBOL using .NET Environment Division. Configuration Section. Repository. Class NETConsole As "System.Console" Class NETList As "System.Collections.Generic.List". Working-Storage Section. 01 String-List Object Reference NETList. Procedure Division. * Create a .NET Generic List Invoke NETList "new" Returning String-List * Add items to the list Invoke String-List "Add" Using "COBOL" Invoke String-List "Add" Using ".NET" Invoke String-List "Add" Using "Integration" * Use .NET Console class to write output Invoke NETConsole "WriteLine" Using "List count: {0}", String-List::Count
  • Web Services: OO COBOL can expose functionality as web services.
  • XML and JSON: OO techniques simplify working with these formats.
  • Database Access: OO approaches can simplify database interactions.

Best Practices for OO COBOL

  • Follow Naming Conventions: Adopt clear, consistent naming for classes and methods
  • Document Class Relationships: Create UML diagrams or other documentation of class hierarchies
  • Use Factory Methods: Implement factory methods for object creation
  • Validate Parameters: Include parameter validation in methods
  • Manage Resources: Properly initialize and clean up resources
  • Limit Accessibility: Restrict access to implementation details
  • Keep Methods Focused: Follow single responsibility principle for methods
  • Design for Extensibility: Consider future extensions when designing classes
  • Consider Performance: Be aware of the performance implications of OO techniques
  • Use Consistent Error Handling: Implement a consistent approach to error reporting

Test Your Knowledge

1. Which statement correctly identifies a key difference between procedural COBOL and Object-Oriented COBOL?

  • Object-Oriented COBOL cannot access traditional COBOL file structures
  • Object-Oriented COBOL requires a completely different compiler
  • Procedural COBOL separates data and procedures, while OO COBOL encapsulates them together
  • Object-Oriented COBOL can only run on distributed platforms, not mainframes

2. Which of the following COBOL divisions is specifically introduced for Object-Oriented COBOL?

  • OBJECT DIVISION
  • CLASS-ID DIVISION
  • METHOD DIVISION
  • INHERITANCE DIVISION

3. How is inheritance implemented in Object-Oriented COBOL?

  • Using the INHERITS clause in the CLASS-ID paragraph
  • Using the EXTENDS keyword in the PROCEDURE DIVISION
  • Using the INHERITANCE section in the DATA DIVISION
  • Using the CHILD-OF statement in the METHOD-ID paragraph

4. What is the primary purpose of a factory section in an Object-Oriented COBOL class?

  • To define the physical storage layout for objects
  • To implement class-level (static) methods and data
  • To create new instances of objects automatically
  • To connect to external databases and factories

5. When designing an Object-Oriented COBOL application, which of the following is the most significant advantage compared to traditional procedural COBOL?

  • Object-Oriented COBOL always executes faster than procedural COBOL
  • Object-Oriented COBOL automatically converts legacy data formats
  • Object-Oriented COBOL promotes code reusability and easier maintenance
  • Object-Oriented COBOL eliminates the need for testing