The ramblings of a yorkshire tyke

Life, Rants and Programming In A Blog

Browsing Posts in CLR

Continuing my series on design patterns for the COBOL, the next one on my list is the “Factory method” pattern.

The pattern is useful, as it helps you hide the real implementation/creation mechanism of your classes. I you are fond of uml… here is the actual uml (from wikipedia).

Factory Method Pattern from Wikipedia!

So… lets see the COBOL code…

       interface-id. "Base".
         method-id. "DoIt".
         end method "DoIt".
       end interface "Base".

       class-id. "Derived1Impl".
       object. implements type "Base".
        method-id. "DoIt" public.
         display "Derived1Impl from DoIt".
        end method "DoIt".
       end object.
       end class "Derived1Impl".

       class-id. "Derived2Impl".
       object. implements type "Base".
        method-id. "DoIt" public.
         display "Derived2Impl from DoIt".
        end method "DoIt".
       end object.
       end class "Derived2Impl".

       class-id. "Factory".
       object.
         method-id. "GetObject".
         linkage section.
         01 obj-base type "Base".
         procedure division using by value oType as binary-long
               returning obj-base.
         
           evaluate oType
              when 1
                 set obj-base to new type "Derived1Impl"()
              when 2
                 set obj-base to new type "Derived2Impl"()
              when other
                 set obj-base to null
         end method "GetObject".
       end object.
       end class "Factory".


       class-id. "FactoryDemo".

       method-id. "Main" static.
       local-storage section.
       01 obj-factory type "Factory".
       01 base-obj type "Base".

       linkage section.
       01 args string occurs any.
       procedure division using by value args.
          set obj-factory to new type "Factory"()

          set base-obj to obj-factory::"GetObject"(1)
          invoke base-obj::"DoIt"()

          set base-obj to obj-factory::"GetObject"(2)
          invoke base-obj::"DoIt"()

       end method "Main".
       end class "FactoryDemo".

That was pretty straight forward… not too much pain…

And finally the code produces…

d:\> FactoryDemo.exe
Derived1Impl from DoIt
Derived2Impl from DoIt
Hello world

Time to sign off for today.. but if you would like me to continue the series on code patterns or have a particular pattern you need… drop us a line!

As part of my working life I happy to say I use COBOL and for better or worse it is here to stay. With this in mind it annoys me I here/see saying things such as

COBOL is a old language that naturally prohibits you from using modern design patterns.

rubbish I say… COBOL can be used in good ways and bad ways.

I will try and show you that COBOL can be used in a good way… lets take the “Singleton pattern“, as the first example.

First.. lets start off my creating a singleton class in csharp… so here it is:

using System.Collections;

public sealed class MySingleton {
    private static readonly Hashtable sharedHashtable = new Hashtable();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static MySingleton() {
    }

    private MySingleton() {
    }

    public static Hashtable Singleton {
        get {
            return sharedHashtable;
        }
    }
}

Not too shabby.. but lets see what we can do in COBOL…

      $set ilusing"System.Collections"
       class-id.  "MySingleton".

       01 shared-hashtable  type "Hashtable"
            static property as "Singleton" with no set.

       method-id. "New" static.
          set shared-hashtable to new type "Hashtable"
       end method "New".

What… COBOL is smaller… that can’t be true… sorry but it is…

To complete the example… lets use it…

      *> Add two items to the single hashtable
         invoke type "MySingleton"::"Singleton"::
                "Add"("01234567","Ian")

         invoke type "MySingleton"::"Singleton"::
                "Add"("987654321","Stephen")

      *> Now get one of the items of the singleton
         display "Account 01234567 - Contains: "
             type "MySingleton"::"Singleton"::"Item"("01234567")

And I am sure some people… will say sure… this is really true… it is… here is it running..

c:\temp> cobol MySingleton.cbl ilgen(sub);
c:\temp> cobol UseSingleton.cbl ilgen ilref"MySingleton.dll";
c:\temp> UseSingleton.exe
Account 01234567 - Contains: Ian
c:\temp> csc MySingleton.cs /target:library
c:\temp> UseSingleton.exe
Account 01234567 - Contains: Ian

Now it seems to me that COBOL is being under rated… perhaps someone should shout about it! :-)

Having read a recent bog about COBOL and type-safety, I though I would jot down some comments.

ANS85 COBOL is naturally is type-unsafe due as every data item being part of one memory region (or storage area), because of this it can make is difficult to talk to type-safe language such as Java or the CLR.

However, just like any computer language it does not stay still. Object oriented features were added to COBOL, at this point in time you we were given the verbs to create 100% type safe application.

The key to writing type safe code is the use OBJECT-REFERENCE will a TYPE and using them on in your methods and using the INVOKE verb.

For example:

      IDENTIFICATION DIVISION.
       PROGRAM-ID.   "TypeSafeExample".
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       REPOSITORY.
              CLASS SYS-STRING AS "System.String".
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 hello-world-string    OBJECT REFERENCE SYS-STRING.
       
       PROCEDURE DIVISION.    
          SET hello-world-string TO "Hello World"
          DISPLAY hello-world-string
          STOP RUN.

The use of COBOL pictures can still be used, however for easy interop with other type-safe languages you really have to stick to the right types for your target environment when exposing your COBOL program to the other languages, this means if you are creating classes, the method to be consumed by other languages should use standard types, for .Net/CLR applications the use of CLS-COMPLIANT types is the right approach. For JVM applications, keep to the “core” java.lang types.

Keep to these simple rules and COBOL will happy interop with type-safe languages. :-)

Continuing the series of blogs about COBOL and the .Net base class library…

The .Net base class library has a wealth classes and an huge of amount of methods/properties.

The .Net base class library has a key handy namespace that contains are the lovely classes, which is System.Collections.

As you can see from the above link, it does have quite a lot, so for this blob entry I will look at:

  • arrays of numbers
  • queues
  • stacks
  • Lets start the first example by using an array of numbers… just to demonstrate its not just strings you can assign to the arrays using “values”.

           01 numbers  binary-long occurs 10
              values 10 20 30 40 50 10 20 30 40 50.

           01 num       binary-long value 0.
           01 average   binary-double value 0.

           procedure division.
              perform varying num through numbers
                add num to average
              end-perform
              divide average by numbers::"Length" giving average
              display "Average is : " average

    Running the above code gives us:

    Average is : +00000000000000000030

    The next class that is helpful, is the Queue class, this allows us to “Enqueue” and “Dequeue” item using the same methods, the queue is again displayed using the “perform through” syntax.

          $set ilusing"System"
          $set ilusing"System.Collections"

           01 alphabetQueue     type "Queue".
           01 item              object reference.

           set alphabetQueue to new type "Queue"()
           invoke alphabetQueue::"Enqueue"("A item")
           invoke alphabetQueue::"Enqueue"("B item")
           invoke alphabetQueue::"Enqueue"("C item")

           display "The initial queue is: "
           perform varying item through alphabetQueue
             display " " item
           end-perform

           display "".
           display "De-Queue an item: " alphabetQueue::"Dequeue"()

           display "".
           display "Afterwards is: "
           perform varying item through alphabetQueue
             display " " item
           end-perform

    Running the above queue example gives:

    The initial queue is:
     A item
     B item
     C item

    De-Queue an item: A item

    Afterwards is:
     B item
     C item

    Next, lets look at the ‘Stack’ class, this is very similar, expect it uses the “Push”, “Pop” methods and we iterate through the Stack using the ‘perform through’ syntax.

          $set ilusing"System"
          $set ilusing"System.Collections"

           01 alphabetStack     type "Stack".
           01 item              object reference.

           set alphabetStack to new type "Stack"()
           invoke alphabetStack::"Push"("A item")
           invoke alphabetStack::"Push"("B item")
           invoke alphabetStack::"Push"("C item")

           display "The initial stack is: "
           perform varying item through alphabetStack
             display " " item
           end-perform

           display "".
           display "Pop item: " alphabetStack::"Pop"()

           display "".
           display "Afterwards is: "
           perform varying item through alphabetStack
             display " " item
           end-perform

    Running the above stack example gives:

    The initial stack is:
     C item
     B item
     A item

    De-Stack an item: C item

    Afterwards is:
     B item
     A item

    As you can see using the base class library collection classes with COBOL is just as easy as using C#… so if you are already using COBOL… continue and try out the .Net base class library.. it really is very easy to use and it will make you more productive.. so please explore and enjoy .Net and its Base Class library.

    While developing something that could be used on Mono on Windows, Mono on Unix and on Windows with Microsoft’s CLR, I needed to be sensitive to the environment but didn’t want to conditionally compile my code different. So I put together a quick class to help.. Below is the C# code with pics of it running on Windows/Mac…

    using System;
    using System.Reflection;

    namespace Gennard.Net
    {
        public class CLRUtils
        {
            private static readonly bool isMono= Type.GetType("Mono.Runtime") == null ? false : true;

            private static readonly int eOSp = (int)Environment.OSVersion.Platform;
            private static readonly bool isUnix =  (eOSp == 4) || (eOSp == 128);

            /* Class Properties */
            public static bool IsMono { get { return isMono; } }
            public static bool IsUnix { get { return isUnix; } }

            public static void Main()
            {
                Console.WriteLine("Are we using Mono? : "+IsMono);
                Console.WriteLine("Are we using Unix? : "+IsUnix);
            }
        }
    }

    The taste of the pudding mix.. is in the eating.. so lets see it working…

    On Windows....

    On the Mac, we get....

    Powered by WordPress Web Design by SRS Solutions © 2010 The ramblings of a yorkshire tyke Design by SRS Solutions
    AWSOM Powered