Namespace standards

Posted by Phillip Magnay on 16-Nov-2006 08:30

OO features in the ABL include the ability to define namespaces which raises the challenge or opportunity (depending on how you see things) to establish namespace standards.

For those new to OO, namespaces are analogous to a hierarchy of folders that most contemporary operating systems like MS Windows, Unix, Linux, etc use to organize files on disk. Namespaces are used in a similar way by OO programming languages such as Java and C# to to organize classes/programs into a hierarchical structure.

Java uses the "package" keyword to add a one or more classes to a particular namespace. C# uses the "namespace" keyword with a block structure to add one or more classes to a namespace.

Now when defining classes in OpenEdge ABL, the OpenEdge developer also has the option of defining such classes to belong to a specific namespace. All references to a particular class must then do so in consideration of what namespace that class belongs to. The logical namespace structure may match the physical folder and file organization of the classes, but not necessarily so. And at runtime, the OpenEdge ABL uses the Propath and the namespaces to resolve a reference to a particular class.

An example namespace might be: USA.MA.Cambridge.14ElmSt.Apt6.Kitchen.LowerRightCabinet. In this namespace is my FryingPan.

So as you can see, namespaces are not rocket science. But they do need to be used with some thought. Like a PC hard drive, the namespace hierarchy can be well organized according to some well defined standards or be a complete mess that follows no standards at all. The Java community generally follow a well defined set of namespace standards. In an attempt to make namespaces globally unique, the Java community have borrowed from internet domain name standards. So a Java developer would generally define namespaces something like: com.progress.openedge.proaccounting.ap.businessobjects, in which he/she might add a class called InvoiceBO. Notice there is a certain schema to the namespace, ie, com.<company-name>.<division-name>.<application-name>.<module-name>.<layer-name>.<class-name>.

The immediate benefit to the coder of namespaces is through the "using" keyword. Instead of typing out com.progress.openedge.proaccounting.ap.businessobjects.InvoiceBO every time he/she wants to reference the InvoiceBO class, he/she simply has to insert

"using com.progress.openedge.proaccounting.ap.businessobject.*.", and every reference to InvoiceBO is simply InvoiceBO. In the ABL, the Propath and namespace also determine how a class reference is resolved at runtime.

But the larger longer-term benefit is well organized applications and components which able to work together without conflict and a familiar approach to that organization which transcends any individual development environment.

So what would be suitable standard namespace approach for OpenEdge ABL applications? Well, the Java approach is quite good but we could also take a cue from the OERA. So something as simple as:

com.<company-name>.<division-name>.<application-name>.<module-name>.PL

com.<company-name>.<division-name>.<application-name>.<module-name>.BLL

com.<company-name>.<division-name>.<application-name>.<module-name>.DAL

...for Presentation Layer, Business Logic Layer, and Data Access respectively. There are probably some further child namespaces to these, eg,

com.<company-name>.<division-name>.<application-name>.<module-name>.PL.Controller or,

com.<company-name>.<division-name>.<application-name>.<module-name>.BLL.BusinessObject

Anyway, I believe a standard namespace approach for all OpenEdge ABL applications is a no-brainer and would provide immense benefits. It is very important but should simple to define and follow.

I would be interested to hear other people's thoughts and their recommendations for OpenEdge application namespace standards.

Phil

All Replies

Posted by Thomas Mercer-Hursh on 16-Nov-2006 11:21

This general pattern is one I have been using since the 10.1A beta. My current versions is a bit abbreviated from the full version you present because I don't feel a need for division and I haven't felt a need for application, although the latter does seem like a sensible idea. So, what I am actually using at this point is

com. is to some extent open to local practice.

I think there are two issues which we might consider in association with this question. One of these is the breakdown in the AutoEdge application between server, ui, shared, etc. components. I understand the motivation, but have mixed feelings about it. If one is going to have this structure, where does it occur? Is it a branch above the level of com so that the whole directory tree is replicated under each one? Or, does it perhaps come above the level of , i.e., one of the modules is lib and another is server?

A related question is standards for PROPATH. I strongly object to the usage in AutoEdge where both server and server/oeri are on the PROPATH. Per this namespace proposal, com.progress.openedge.autoedge.server at most should be on the Propath ... and I would argue that, actually, only com.progress.openedge.autoedge should be on the Propath and that path references in the code should include server and server/oeri . Of course, with this USING construct of which you speak, much of the pain of that pathing can be avoided in classes.

One other minor question is whether we should stick to all lower case, as per the AutoEdge standards, or whether we have grown up enough now to use mixed case. My own standard has been to use lower case for the com.cintegrity part, but to allow mixed case below that. I find being able to see CustomerFinder.cls in the directory tree easier to deal with than customerfinder.cls.

Posted by Phillip Magnay on 16-Nov-2006 13:38

Just to be clear for everybody, the "using" keyword is available in 10.1B.

I disagree with the idea of making the subdirectories

based on layers. I would much rather have all

classes related to Customer in one place that to have

all data access objects in one place. The Customer

classes relate to each other, the layer classes only

sometimes do ... not to mention that one ends up with

too many of them in one place.

That's good feedback. I believe there might be some who would like to see the OERA layers represented in any namespace guidelines. But you are right to challenge whether doing so truly adds value.

Phil

Posted by Thomas Mercer-Hursh on 16-Nov-2006 13:59

That's good feedback. I believe there might be some who would like to see the OERA layers represented in any namespace guidelines. But you are right to challenge whether doing so truly adds value.

I think the choice is in whether we gain more value by grouping all of the aspects of data access together or whether we gain more by group all aspects of Car together. To me, it seems likely that when one is working on the Car domain object, one might also like to look at the Car data access objects, e.g., to add a new field. With all Car classes in one directly, this is very direct. With them scattered according to layer, then one has to navigate all over the place.

Also, I don't believe that layers are entirely unambiguous. If, for example, I created a CarValidation class which I intended to be used both by the domain object for validating new and changed information and by the Mapper object to insure that everything was fine prior to storing the data, then which layer does it belong to? It's own? And, using Fowler's Finder and Mapper structure, the Finder is really a sort of facade to the data access layer ... so, does one put it with the domain classes or with the data access classes? There are some possible ambiguities grouping by component as well, but I think they are not frequent and are more inherent to the complexity of the model.

Posted by jtownsen on 20-Nov-2006 02:37

com....

Generally, I think this is a good approach. I would like to be able to keep my framework components separate from my application, so if we were to formally document the above, I'd like to define as: the name of the application or framework.

Something to consider: com. is a good way of uniquely defining a company (ie. based on their internet address), so long as you're only talking about North American companies. Many of the customer and partners that I'm working with don't have a .com internet address. Should they be using namesspaces like au.com. or ch., based on the local internet naming standards? Can anyone tell me what Java developers do in such cases?

Posted by Tim Kuehn on 20-Nov-2006 11:34

OO features in the ABL include the ability to define

namespaces which raises the challenge or opportunity

(depending on how you see things) to establish

namespace standards.

com....

.PL

com....

.BLL

com....

.DAL

I'd be cautious about embedding company and application name into an object's name, because

a) company names can change

b) application names can change

c) what happens when you want to take an object from one application and put it in another?

"a" and "b" may not happen that often, but it does happen. Having to carry an application's name in an objet over to another application to me would be a non-starter.

Posted by Thomas Mercer-Hursh on 20-Nov-2006 11:43

"a" and "b" may not happen that often, but it does happen. Having to carry an application's name in an objet over to another application to me would be a non-starter.

And, when it does happen, then one ends up installing Progress in the DLC directory!

Frankly, I think there is less of an issue here than you think ... especially since Phil has already leaked the presence of USING in 10.1B. With a USING at the start of the class, the references within the object are all simple and short, so any change in company and application name that one wishes to make is really a matter of a fairly simple piece of refactoring the USING statements.

Likewise, moving a class is again just a matter of changing the USING statement. And, for re-using the class in more than one application, one doesn't even need to do that.

Posted by Tim Kuehn on 20-Nov-2006 11:58

Is it?

All the references I recall seeing in the OO stuff required you to specifiy the object's entire path for every declaration.

Even if you put "using" in the top of the file, you still have to visit every file where the object's used / referenced and change it.

Unless - heaven-forbid - you put the class /use declaration headers in include files.

Posted by Thomas Mercer-Hursh on 20-Nov-2006 12:10

Is it?

Is what?

All the references I recall seeing in the OO stuff required you to specifiy the object's entire path for every declaration.

In 10.1A, that is true. With USING, however, one creates a namespace within the class in which the leading part of the string is assumed. This can be all the way down to the level of the directory containing the class, or it can be at some higher level.

No, I certainly wouldn't use include files ... all the more so because one would need many, many of them for all the possible directories. But, any bulk substitution tool can roar through changing all references to "com.datalanguagecorp" to "com.progress" with ease, even without a proper refactoring tool.

This thread is closed