Lol,
Yes, Charles refactored this much better than I did... Without being
closer to the problem, I could not quickly figure out what would seem to
be a reasonable hierarchy for this example... Nice work. ;-)
-Eric
-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Charles Wilt
Sent: Thursday, June 25, 2009 12:05 PM
To: RPG programming on the IBM i / System i
Subject: Module Hierarchies (Was: Procedure naming conventions)
Eric has a good point, I considered making it myself...but decided not
too
as that was a whole other can of worms...
However, since Eric brought it up :)
As Eric said, AcquireClientsWifesSistersDogsName() is a bit narrow to be
in
service program.
However, the problem with dog_acquireNameByRelation( aRelative ) is that
now
the DOG has to understand relations. I'd propose something along the
lines
of
if client_isMale(client) and client_isMarried(client);
spouse = client_getSpouse(client);
if person_hasSister(spouse);
sister = person_getSister(spouse);
if dog_forOwnerExists(sister);
dog = dog_getByOwner(sister);
clientsWifesSistersDogsName = dog_getName(dog);
endif;
endif;
endif;
Now the above is pretty simplified, consider how to handle more than one
dog, more than one sister, ect...
Add in the code for that and things get pretty complex :)
That being the case, assuming you really need it, having a
GetClientWifesSistersDogsName() isn't a bad idea and if you need to call
it
from more than one place then placing it into a service program _is_ a
good
idea.
However, you wouldn't want it in the DOG, CLIENT, or PERSON modules;
those
are low level probably corresponding to actual entities (tables) in your
application. Instead you'd want it in a module a step above those, call
it
FAMILY (since I can't think of anything better.) FAMILY will make use
of
the lower level modules and contain the complex (business) logic that
encapsulates the processes and rules for your application. So you might
have
FAMILY_getDogsNameForRelation(client:WIFE:SISTER);
You could, through the use of binder source, make the procedures in DOG
and
PERSON protected, and only available within the service program that
contains them. Thus your UI and batch programs would never directly
access
DOG_getName(). Though you might make visible a FAMILY_getDogsName()
As another example I've used before, lets say you have an INVENTORY
service
program made up of the following modules:
INVENTORY - The publicly accessable procedures
INVMAST - protected I/O Procedures for the Inventory Master file
INVTRANS - protected I/O Procedures for the Inventory Transaction
History
file
You UI or batch applications may call INVENTORY_Receive(), which in turn
would call INVMAST_Receipt() and INVTRANS_LogReceipt() for instance.
HTH,
Charles Wilt
On Thu, Jun 25, 2009 at 10:30 AM, DeLong, Eric
<EDeLong@xxxxxxxxxxxxxxx>wrote:
David,
I understand your point, but I might counter with another. To me, a
procedure as described below (wifesSistersDog) is too narrow to be
included
in a service module. One could presume that there are also procedures
for
WifesBrothersDog, WifesMothersDog, WifesFathersDog, and so on.... As
a
whole, having dozens of clones of a procedure to support a series of
related
test cases could be simplified with a better design. Perhaps you only
need
dog_acquireNameByRelation( aRelative ), then within your code, you can
support any number of associations.
A rule of thumb, if you can't describe the effects of a procedure
efficiently, then perhaps the design should be reviewed.
Jmo,
-Eric DeLong
As an Amazon Associate we earn from qualifying purchases.