What's in a package if one has layers?

Posted by Thomas Mercer-Hursh on 27-Aug-2013 13:42

I'm interested in some philosophical feedback since I have found that I can argue this both ways.

Assume that one is developing for an OERA architecture of some sort so that, at a minimum, one is going to have BL and DA layers.  I am inclined to leave the UI out of this discussion since that may not be ABL, but if someone feels they have wise words, particularly with respect to UI interface, i.e., the server side piece that communicates with a remote non-ABL UI.

Assume also that one is putting everything (ABL) related to an application under a given root directory (com/cintegrity/src in my case) but the name for that root is irrelevant in the current context because it is in the PROPATH, not the code.

And let's assume that we want to organize code into "applications" like AR, AP, GL, OP etc and packages of related functions within those application, so that customer related code might be in AR/Customer (or AR.Customer in the code).

There seem to be two ways to combine the package with the layer classification.

One is to make a top level split into layers.  I.e., the Customer object itself might be in BL/AR/Customer and the Customer data access object might be in DA/AR/Customer.  If one did this, one might name both classes Customer.cls since the package would make the purpose clear.

The other is to include all layers in the package.  I.e., AR/Customer (directly in the root) would contain Customer.cls or CustomerEnt.cls *and* CustomerDA.cls.

If one had a property class for Customer data, this might be Msg/AR/Customer/Customer.cls in the first case and AR/Customer/CustomerMsg.cls in the second.

If one had a class for external interfaces such as UI, this might be Ext/AR/Customer/Customer.cls in the first case and AR/Customer/CustomerExt.cls in the second.

It seems to me that the first emphasizes the layer separation and certainly would facilitate deploying the layers in different sessions or machines, were that appropriate.  Whereas, the second emphasizes putting related code with related code, i.e., so that a change to Customer.cls which implied a need to change CustomerMsg.cls and CustomerDA.cls would be conveniently recognized.

Opinions?  Reasons?

All Replies

Posted by Peter Judge on 27-Aug-2013 13:54

Some of this discussion was had in http://communities.progress.com/pcom/thread/39429?tstart=0

-- peter

Posted by Thomas Mercer-Hursh on 27-Aug-2013 14:46

As well as another naming issue ....

I take it this is your endorsement of putting the layer at the top of the naming stack.  Obviously, at the time that seemed to me like a good idea and it certainly facilitates deployment, but does it bother you that you have to go three different places to make a change, e.g., adding a new field?

Posted by Stefan Drissen on 27-Aug-2013 17:46

tamhas wrote:

I take it this is your endorsement of putting the layer at the top of the naming stack.  Obviously, at the time that seemed to me like a good idea and it certainly facilitates deployment, but does it bother you that you have to go three different places to make a change, e.g., adding a new field?

If using Progress Developer Studio - I recomment the AnyEdit plug in - it allows you to open anything that looks like a resource in any part of your source (also comments / strings) using CTRL+ALT+R (as default). This gets over the hurdle that PDS will only open include file declarations using F3 and takes away the pain of multiple locations - you only need to name the other layer resources in the comments.

Posted by Thomas Mercer-Hursh on 28-Aug-2013 10:09

While that looks like it has some useful features, I'm not sure how it addresses the issue.  The components in various layers are not necessarily calling each other, they merely have some parallels which one would want to maintain.   Maybe this is less of a real problem than I imagine since, if one has parallels throughout, then one is going to know to look in each of the logical buckets.

Posted by Peter Judge on 28-Aug-2013 15:45

tamhas wrote:

As well as another naming issue ....

I take it this is your endorsement of putting the layer at the top of the naming stack.  Obviously, at the time that seemed to me like a good idea and it certainly facilitates deployment, but does it bother you that you have to go three different places to make a change, e.g., adding a new field?

In the notes in my post I talk about (for certain packages that span the client/server divide) having a *.Client.* package, a *.Server.* Package and a *.Common.* package.  The latter is deployed to both client and server and contains stuff that is shared between the client and server.You can use a similar approach here:I would think that if you have a Customer object you would have N+1 packages, where N is the number of implementing packages pluse a common/shared package.

So, App.Base.Customer is a (possibly) abstract class that contains the shared/common data and behaviour. The App.AR.Customer class inherits from this and provides its own specialisations, as do the App.AP.Customer and the App.CRM.Customer classes. If you have to add a new field that's common, then there's only one place to change.If you think your inheritance tree is likely to get very complicated, the use the Decorator pattern to add the AR and/or AP and/or CRM behaviour on to the Base.Customer type.

-- peter

Posted by Thomas Mercer-Hursh on 28-Aug-2013 16:03

Well, I would never define program groups by the target platform, because architectural changes could alter that.  I am much more comfortable naming by subsystem, where a different layer is a subsystem, but what is in a layer in OERA could be multiple subsystems, e.g., ABL BL code in one and BRM in another.

Inheritance doesn't really address the issue I am concerned with.   E.g., imagine a data access object for Customer in the DA subsystem, a business entity Customer in the BL subsystem, and a message object in the Communications subsystem.  They all need the same attributes, but have nothing else in common and could even implement those attributes in different ways, e.g., a TT in the DA object to utilize before image handling.

Posted by Stefan Drissen on 28-Aug-2013 16:51

tamhas wrote:

While that looks like it has some useful features, I'm not sure how it addresses the issue.  The components in various layers are not necessarily calling each other, they merely have some parallels which one would want to maintain.   Maybe this is less of a real problem than I imagine since, if one has parallels throughout, then one is going to know to look in each of the logical buckets.


If you add the names of the sources that are in other locations in the header comments you can easily open these files without having to browse to the other locations in the resource tree to get all the files that belong together.

For example the source header of the BL component could be:

/*
  business logic: BL/AR/Customer.cls
  data access: DA/AR/Customer.cls
*/


AnyEdit will allow you to open either .cls by selecting the text and pressing the hotkey.

Posted by Thomas Mercer-Hursh on 30-Aug-2013 09:59

I am not very confident in a system that requires manual maintenance like that.

Posted by Stefan Drissen on 30-Aug-2013 10:17

tamhas wrote:

I am not very confident in a system that requires manual maintenance like that.

And you are confident that you will remember to open three files in three completely different locations? Interesting.

It's simply an aid, not a system.

Posted by Thomas Mercer-Hursh on 30-Aug-2013 10:29

I like systems!

Posted by Thomas Mercer-Hursh on 14-Sep-2013 11:45

I have been discussing this elsewhere in the context of the specific tool involved and have come to a couple of interesting twists on the subject.

One of them is that this tool provides a separation of the model from deployment, i.e., patterns of deployment are specified separately from the specification of the functionality.   This is, of course, very attractive since it means that the deployment can be flexible.  E.g., one set of components can be used if utilizing a remote AppServer as the data layer and another set used if the database is local to the session, e.g., a component running on an AppServer.  To me, this suggests that while "Layer" is presented in the OERA as conceptual stratification, is nevertheless ultimately a deployment issue.  In particular, a data access component running in the same session instance as a business component is really deployed with the BC while one running in a remote AppServer agent is not.   The separation of the "layers" is important to give one that deployment flexibility as well as to provide the separation of concerns which is a hallmark of any good OO.

Of course, this assumes that one has the deployment tool, so those without it might feel that it is necessary to provide separation in the naming hierarchy in order to facilitate deployment, but making the separation in the naming hierarchy is going to be inherently less flexible since any changes will also produce changes in names.   The exception to this could be to have multiple base directories in the PROPATH to reflect expected deployment categories since one could then move a component from one category to another without any name changes.  That doesn't appeal to me particularly, however, as it seems a fairly crude way to make the separation.

The other twist, which is less clear, is that there is an interesting distinction between package and domain.   In UML, every grouping at any level is ultimately a package.  But, package also has special meaning in some programming languages because they provide package-level security (see note below).  Whereas, domain is typically used to indicate a coherent subject matter, i.e., a conceptual division in the problem space.  From that perspective, even the lowest level grouping is also a domain, it is just a particularly tight clustering of subject matter.  By extension, there is no particular magic in the number of levels of groups.  For smaller applications A.B might be a sufficient structure to provide a manageable number of A level domains and a manageable level of B level domains or packages within each A.  But, for an ERP suite, one might need A.B.C or even A.B.C.D to provide a happy number in each category.  It is simply a tradeoff between the manageability of the number in each category and the length of the names, ultimately judged by the naturalness of the subject matter divisions which are implied and the coherency of each division.  This suggests that one need not be uniform in depth across all domains since not all domains encompass the same level of complexity.  One might well have some domains which encompass only a limited breadth of subject matter and thus require little breakdown, while other domains encompass a great deal of complexity and require further breakdown.

Apropos package-level security, one of the observations which came up again in this discussion is that concern over security is largely based on keeping programmers from shooting themselves in the foot ... along with concerns by publishers of software over the consumers shooting the support staff in the foot.  In the context of Model-Based Development, security becomes virtually unimportant because the relationship between the components is the relationship expressed in the model so if two things need to connect, they do, and if they don't need to connect they don't and there is no need for a mechanism to keep them from doing so.

This thread is closed