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.
Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects," which can contain data and code. The key principles include:
The evolution of Object-Oriented COBOL followed these key developments:
Year | Development | Significance |
---|---|---|
1997 | OO features proposed for COBOL standard | Initial recognition of OOP importance for COBOL's future |
2002 | OO features included in COBOL 2002 standard | First official OO support in the COBOL language standard |
Early 2000s | Vendor implementations of OO COBOL | IBM, Micro Focus, and others add OOP capabilities |
2014 | COBOL 2014 standard refines OO features | Improved standard based on implementation experience |
2010s-Present | Integration with Java, .NET, and web services | OO COBOL used as bridge between legacy and modern systems |
Aspect | Procedural COBOL | Object-Oriented COBOL |
---|---|---|
Program Structure | Based on divisions, sections, paragraphs | Based on classes, methods, objects |
Data Organization | Data separate from procedures | Data encapsulated with methods in classes |
Code Reuse | Through copybooks and subprograms | Through inheritance and composition |
Runtime Behavior | Static structure determined at compile time | Dynamic object creation and method dispatch |
Syntax | Traditional COBOL syntax | Extended with CLASS-ID, METHOD-ID, etc. |
Interface with Modern Systems | Requires additional mapping layers | More natural integration with OO systems |
Encapsulation and modular design make OO COBOL code easier to understand and maintain, with changes localized to specific classes.
Classes can be reused across applications, reducing duplication and promoting consistent implementation.
OO COBOL integrates more naturally with Java, C#, and other object-oriented systems, simplifying interoperability.
Developers familiar with other OO languages can more easily transition to COBOL when it follows OO principles.
Organizations can incrementally update legacy systems by introducing OO components while maintaining procedural code.
Business entities can be modeled as objects, creating a closer match between real-world concepts and code.
OO COBOL is particularly valuable in these scenarios:
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.
An Object-Oriented COBOL program typically consists of one or more class definitions that encapsulate data and behavior:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293***************************************************************** * 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.
Element | Purpose | Example |
---|---|---|
CLASS-ID | Defines a class | Class-Id. Customer. |
REPOSITORY | Defines external class references | Class Address As "Address" |
INHERITS FROM | Establishes inheritance relationship | Class Base Inherits From "BaseEntity" |
OBJECT SECTION | Contains instance data and methods | Object Section. |
FACTORY SECTION | Contains class data and methods | Factory Section. |
METHOD-ID | Defines a method | Method-Id. "GetName". |
OBJECT REFERENCE | Declares an object reference | Object Reference Customer |
SELF | References the current object | Self::Customer-Name |
INVOKE | Calls a method on an object | Invoke Customer-Obj "GetName" |
SUPER | References parent class methods | Invoke Super "Initialize" |
In OO COBOL, classes and objects follow these principles:
12345* Creating an object Declare WS-Customer As Object Reference Customer Invoke Customer "CreateCustomer" Using 1234567890, "John Smith" Returning WS-Customer
1234567891011* 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-Oriented COBOL uses object references to work with objects:
12345678910111213141516171819202122232425262728293031* 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
Understanding the difference between factory and object methods is crucial in OO COBOL:
Characteristic | Factory Methods | Object Methods |
---|---|---|
Definition Location | FACTORY SECTION | OBJECT SECTION |
Associated With | The class as a whole | Individual object instances |
Invocation | On the class | On an object |
Data Access | Factory-Storage data | Object-Storage data |
Common Uses | Constructors, utilities, counters | Object behavior, data manipulation |
Example | Invoke Customer "CreateCustomer" | Invoke Customer-Obj "GetName" |
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.
Inheritance in OO COBOL is established in the CLASS-ID paragraph using the INHERITS clause:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697***************************************************************** * 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.
12345678910111213141516171819202122* 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".
1234567891011121314151617* 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".
12345678910111213141516171819202122* 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 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.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859* 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.
Sometimes you need to check the actual type of an object or convert between types:
123456789* 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
12345678* 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
Common OO design patterns can be implemented in COBOL to solve recurring design problems:
Pattern | Use Cases | Implementation Approach |
---|---|---|
Factory Method | Object creation with specific initialization | Factory methods in the FACTORY SECTION |
Singleton | Single instance of a service class | Factory method with instance tracking |
Strategy | Different algorithms for a task | Classes with common interface methods |
Observer | Event notification between objects | Listener objects that implement update methods |
Adapter | Compatible interfaces between systems | Wrapper classes around existing functionality |
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.
A simple but complete example of a customer management system showing multiple classes with relationships:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390***************************************************************** * 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".
This example demonstrates a Singleton pattern implementation in OO COBOL:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159***************************************************************** * 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".
Effective Object-Oriented COBOL requires thoughtful design approaches. This section covers best practices, common pitfalls, and strategies for successful OO COBOL development.
Principle | Description | COBOL Application |
---|---|---|
Single Responsibility | A class should have only one reason to change | Create focused classes for specific business entities or functions |
Open/Closed | Open for extension, closed for modification | Use inheritance instead of modifying existing classes |
Liskov Substitution | Subtypes must be substitutable for their base types | Design consistent method behaviors across inheritance hierarchies |
Interface Segregation | No client should depend on methods it doesn't use | Create cohesive classes with focused method sets |
Dependency Inversion | Depend on abstractions, not concretions | Use parent class references to refer to objects |
Effective class hierarchies are central to OO COBOL development:
12345678910111213141516171819202122* 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.
Challenge | Solution |
---|---|
Performance Overhead |
|
Legacy Code Integration |
|
Memory Management |
|
Deep Hierarchies |
|
Testing Challenges |
|
Transitioning from procedural to Object-Oriented COBOL:
OO COBOL can interface with other technologies:
1234567891011121314151617181920212223* 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
12345678910111213141516171819202122* 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
1. Which statement correctly identifies a key difference between procedural COBOL and Object-Oriented COBOL?
2. Which of the following COBOL divisions is specifically introduced for Object-Oriented COBOL?
3. How is inheritance implemented in Object-Oriented COBOL?
4. What is the primary purpose of a factory section in an Object-Oriented COBOL class?
5. When designing an Object-Oriented COBOL application, which of the following is the most significant advantage compared to traditional procedural COBOL?
Learn about COBOL program documentation and maintenance practices.
Explore modular programming techniques in COBOL.
Learn how to optimize COBOL program performance.
Discover best practices for testing COBOL applications.