Re: OO Factory(1)



[I've set follow ups to comp.lang.cobol only]

"James J. Gavan" <jgavandeletethis@xxxxxxx> wrote in message
news:yxOhf.624473$tl2.405040@xxxxxxxxxxx
>
>> Are you essentially saying "This is how I've implemented the Factory
>> pattern in my COBOL program. Is this the correct approach?" ?
>
> Your question is 'almost' there. Yes that is my Factory 'pattern'
> (although I hate the underlying nonsense about the word 'pattern'). No
> not, "Is this the correct approach ?". If I totally ignore Factory,
> which I am able to do - am I missing features in Factory which 'enhance'
> usage, rather than restrict myself solely to instances. Is that any
> clearer.

After reading this post, and Pete's post, I'm fairly confident that what
COBOL calls "FACTORY" has nothing (or, at most, very little) to do with the
"Factory pattern" from the Gang of Four. Instead, it seems to be
representing some sort of concept of "meta-object". That is, the factory
object of object A is the object that created object A.

It's sometimes useful to define methods and properties on the factory
object, because all objects of the same class will have the same factory
object, and so if they wish to share data with each other, factories seem
like the obvious way to do it.

In this context, the factory acts like the "static" keyword in Java (but
there isn't any one to one correspondance between the factory concept and
some concept in Java; rather factory overlaps with several concepts in Java,
including the static keyword and the class Object, but don't fully cover
them either).

Using the "static" keyword is generally frowned upon except as a last
resort. It's just a sort of rule of thumb, like declaring everything with
visibility "public" is also considered a bad practice in Java. One poster in
a Java newsgroup (I forget which one) went so far as to say that you should
never use the static keyword at all, and showed alternate implementations
for every situation that traditionally called for the usage of the keyword.

So in summary, by default, you probably shouldn't use FACTORY. If you
get stuck and the most elegant solution involves using FACTORY, then go
ahead and use it, but don't lose any sleep from "under-using" it.

> No specific project in mind, but the approach is intended for any
> project. As regards UML as one of the whiz kids at Micro Focus wrote
> when I quizzed, just another interesting tool, which he learned from a
> course. Same goes for Rational Rose
>
> Frankly I am a doer. If I want to do something, I'll think it through in
> my head, establishing my own 'pattern' or using really old terminology,
> a FLOWCHART showing the programs ins and outs. Does the reasoning feel
> right.

Agreed, with some reservations. When I'm trying to come up with a design
for myself, I'll usually use my own notation, because I don't want to get
bogged down in syntactic detail when the ideas are flowing. However, UML is
an effective *communication* tool: Because my diagrams are in my own
notation, no one can be expected to understand what they mean. By converting
my diagram to UML notation, anyone else who knows UML will be able to
understand the design, thus speeding up communication.

> Now can I translate that into code - and by hook or by crook - if my idea
> has merit I'll code to make the language, whichever it is, fit my ideas -
> not become subservient to some preconceived design patterns.

Two things here:

1) If you're fighting the language, you should probably consider writing
the program in a different language (unless the language is some sort of
client requirement, in which case you're SOL).

2) The concept behind design patterns is "learn from the experience of
others". The book "Design Patterns" from the GoF essentially says "Here's a
bunch of problems we've had to solve umpteen times. Each time we tried to
solve these problems, our solution got better and better, because of our
past experiences. Here's the are the solutions which we've found to have
matured enough that we don't expect them to change significantly from here
on."

Each design pattern is accompanied with instructions on its usage, but
these instructions aren't explicit like the instructions for assembling IKEA
furniture; rather, they are much more loose, like instructions in a
parenting book. Occasionally, I'll apply a pattern exactly as like the
example implementation in the book, but very often I'll also apply it with
some variations due to the unique situation or problem that my software has
to solve. The book also sometimes lists possible variants along with their
examples.

> So back to Factory usage it is a 'blind' method if you like. invoke
> ThisClass "new" from the INVOKER class then the INVOKEE class
> understands, even if Factory is not present, that it must 'climb' the
> hierarchy up to class Base which does the initial cookie cutting based
> on the Class you are referencing.

This behaviour of climbinging the tree to look for a method is
traditionally called "method inheritance", and it's a very standard feature
to have in object oriented languages (I don't know of any OO language which
doesn't have it, but it's conceivable that such a language could exist).

>> Are you saying that the "new" method is defined in the Base class? Do
>> you know if in OO COBOL, all methods eventually extend Base if you go up
>> the hiearchy (i.e. this is a single-root Object hiearchy), or if there
>> might possibly be multiple different roots?
>
> Base - "The buck stops here". If you make a typo on the name of an
> invoked method, obviously the runtime goes searching, and on failing you
> arrive at Base which will generate a runtime error "Class MyCustomerDialog
> does not understand message OllieWong", when there is only a method for
> 'OliverWong'.
>
> Please remember specifically, I'm talking about Micro Focus support
> classes. Yes, there are sub-roots, and an obvious one, GUI classes for
> the individual controls report to Class Dependent; that in turn reports
> to Base. Dictionaries/Collections, along with some character/array
> classes are in a sub-group also reporting to Base. I haven't used them
> but I also have a subset on Java, which allows for inter-language
> communication. That is in my Version 3.1. If you upgrade to the current
> V4.0 compiler - inter-communicatin with any language using dotNet.

Yes, it sounds like COBOL has a single root object hiearchy (and Pete
confirms it too in his post) in that every object in COBOL eventually (if
you go far enough) extends from Base. Java and C# also have a single root,
but C++ has multiple roots.

> The next is an M/F extension and not part of COBOL 2002 :
>
> "SELFCLASS enables an instance object to send a message to the factory
> object which created it. The method invoked is a method in the factory
> object. If you use SELFCLASS from a factory method, it points to the
> metaclass for this class, which is an instance of Behavior".
>
> Oops ! Behavior. A class which is immediately subordinate to Class Base
> - they more or less work as a pair.

I think this is essentially saying that every object has a class (which
is normal in OO). Classes themselves are objects, so they have classes too
(also normal in OO). The class of every class object is called "Behaviour",
and Behaviour extends Base (everything eventually extends Base, so this
isn't too surprising).

For what it's worth, in Java, the class of every class object is called
"Class". And the class that every class eventually extends (i.e. the root of
the object hiearchy) is called "Object".

>
> I could try and wade my way through the legalese jargon in the Standard,
> but let's see how M/F put it in their on-line manual. Well, having read
> the following before copying/pasting, and I'm not claiming a victory, it
> does appear to give a resounding 'YES you don't need Factory' to my query.
> Do you agree. Or is there somebody out there who would disagree ? I think
> it worth quoting in full :-
>
> -------------------------------------------------------------------------
[snip]
> ---------------------------------------------------------------------------
>
> I think at this point I could pack it in. Above indicates what I'm doing
> is perfectly acceptable and nothing really in what they say about using
> FACTORY turns me that I should think "I MUST use Factory".

You are correct in understanding that you don't need to use FACTORY if
you don't want to. It's usefulness, as mentioned in the explanation which
I've snipped, lies in that all instances have access to the factory that
created it (via SELFCLASS), and that there exists only one such factory
object for every class. So again, it's mainly useful for sharing or
communicating data among all objects of a given class.

>
> For certain what you mentioned above gets up their noses, and in fact gets
> up mine. It starts with your phrase above, "Where it becomes more useful
> is when you're not sure yet what kind of object you want to create.
> Imagine you have a class hiearchy such that you have a abstract class
> "Person" and you have a class "Man" which extends etc....".
>
> I recall years ago a COBOLer commenting, having read some text on OO, and
> the example was obviously talking about hierarchical structures with
> reference to animals, he commented "What have giraffes, elephants and
> camels got to do with business programming ?". I sympathized with his
> thoughts. Might be useful if I was a zoo keeper and had to feed the
> animals at Calgary Zoo.
>
> I think you can get positively esoteric and go off into space about
> formulating abstract objects. Still if that's your scene, go for it. I for
> one know exactly which objects I want to create, a COBOL file, an SQL
> Table, a Dialog, EditProgram or PrintProgram etc.

Fair enough. I think the tradition of using examples with no real
business value comes from academia. The concept of not knowing what kind of
object you have is central to "polymorphism", and generally speaking, if
when you start using polymorphism in real production code, you're probably
doing something at least of medium complexity. Since teachers don't want to
actually bog students down with a "real business problem" when the problem
they're trying to address right now is getting students to grasp
polymorphism, the teachers will usually use a much simpler (though
unrealistic) example, such as "Person, Man, Woman" and "Animal, Giraffe,
Lion", etc.

Here's a more "real life" example of using the Factory pattern (lifted
from the GoF book):

Imagine you want to write a program which is supposed to run on multiple
platforms (Windows, Mac, Linux, etc.) and which supports graphical user
interfaces. Because of the latter, it has would probably have classes like
"Button", "Window", "Label", "TextField", etc. Because of the former, these
are all abstract classes, and there would exists "MsWindowsXPButton",
"MsWindows9xButton", "AppleOSXButton", "AppleOS9Button", "LinuxKDEButton",
"LinuxGnomeButton", etc. The reason being that each OS has a very different
interface for using their native GUI widgets, and so the code often has to
be very different. For example, perhaps on Windows, labels and text fields
are completely different things, whereas on Mac, labels are simply text
fields which cannot be edited (I'm just making this up as an example, I have
no idea how labels or textfields are actually implemented on those OSes).

But as a programmer, I don't want to write code like:

Button myButton;
if (System.getOperatingSystem() == "Microsoft Windows") {
if (System.getOperatingSystem().getVersion() == "XP") {
myButton = new MsWindowsXPButton();
} else if (System.getOperatingSystem().getVersion() == "98") {
myButton = new MsWindows9xButton();
} else if (System.getOperatingSystem().getVersion() == "95") {
myButton = new MsWindows9xButton();
} else if (System.getOperatingSystem().getVersion() == "3.1") {
myButton = new MsWindows16BitButton();
}
} else if (System.getOperatingSystem() == "Linux" {
....

And so on every time I want to create a button. Imagine one day
Microsoft decides to release a new operating system called "Windows Vista".
Then every location I've written the above code, I need to add a new if
statement to check the version string against "Vista", and create a new
MsWindowsVistaButton.

Instead, you could create a "WidgetFactory" where you place all that
code once. Outside of that factory, all you know is that you're getting a
"Button". You don't know specifically what kind of Button you're getting,
but in this case, not knowing is actually a good thing: It relieves you some
of the burden of responsibility.

- Oliver


.


Quantcast