Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: Jordan Marr <jnmarr@xxxxxxxxxxx>
- Date: 25 Apr 2007 06:43:05 -0700
On> I model a different set of object graphs for each use
case, so that if one use case changes, I can modify it without
affecting my other use cases.
Your solution almost sounds like a P/R solution then. It is possible
to wrap a procedural approach in classes and use "dot" notation, but
it is not really "OO" then.
It's true that dot notation alone does not make a solution "OO". The
reason I consider my solutions OO is that I take advantage of all the
tenets of OOP: abstraction modeling, encapsulation, inheritance,
polymorphism, delegation, etc.
Or store them in a ShoppingCart table so that I perhaps don't have to
create an extra method/function (if done in only one place). The user
usually wants to see their "draft" features list before they are
finalized.
Saving your shopping cart in a DB is one way to do it, although that
would mean lots of temporary / abandoned carts in your table that
would need to be maintained. Cookies or session state are better
alternatives, imo -- depending on what the requirements of the app
are, of course.
I agree with you. I load only the data I need for the current use
case, and then discard it when I'm done. The only difference is that
I load it into objects that are composed with their related objects
instead of in the format of a flat table structure.
Why use composition when a flat structure (result set) is all that is
needed for a *given* task? Queries project/map data into a form more
easily digestable for a given task. Just about the only time I've
needed more than that is when the app language does not support local
created temp tables.
Because I want more control over the data structures that are passed
back from the DB. I may want to use property gets/sets to better
control how the UI designer gets the data. Sometimes I am in projects
where someone else writes the SP (like my current project), so gets/
sets allow me to perform any data formatting or cleanup that I want to
do. And I also like to keep the methods encapsulated along with the
data whenever possible. If a method needs to be shared, I have no
problem encapsulating it into its own class to be shared by other
objects.
It is not *me* being a strawman, but rather the sin of OO'ers not
getting their act together to define what "true OO" really is. Thus, I
resent the straw-man accusation. The problem is youses, not me. You
create slop and then complain when I try to clean it up.
So let me get this straight: You're the victim, and I'm the
perpetrator?
You called my statements "strawman arguments". People will likely get
offended if you do such, you should know.
Your example of the cars with features hardwired into an inheritance
chain was pretty weak in the knees. Even if an "OO" person did come
up with that solution; it's not the correct way to solve the problem,
IMO.
Robert Martin also hard-wires issues into his design that don't need
to be hared wired. My version of his payroll example does not mention
things like union dues, parking fees, sales commission, etc. in the
app code. They *all* come from the DB tables. One table defines the
line-items and related formulas, and another maps those to employees
if they have such items, along with a Value parameter if needed to
store quantities or fee amounts. (i'll release it in a few weeks.)
Thus, is Martin also doing OOD wrong??? He is a programmer acting as a
"glorified product clerk" too.
If the specs say the software needs to account for parking fees, then
that release of code will have a function to calculate parking fees.
If it's a features that is likely to change often, then a
ParkingFeeStrategy could be used to change it on the fly. I know you
don't like this method, so we'll chalk it up to personal preference.
Again, the concept does not directly exist in the code. One table has
the item specification and formula, another contains an employee-
specific value (parameter, if needed). They are joined with an inner
join such that it is not applied to an emp if his/her record does not
have a corresponding record. Thus, one table describes the feature
(parking fees), and another specifies the "sets" of features that a
given paystub has along with a value parameter. (Multiple parameter
values are not really needed because they can be specified with
multiple line item specs that are marked "hidden" or informational.)
It is possible to hard-wire concepts into my solution if the dynamic
approach cannot handle a specific something. The idea is the meta-tize
at least about 80% of what you can so that you only have to hard-wire
about 20% of the concepts. My table-driven approach also allows
multiple languages to supply features or calculation if a client does
not want to use the language the app is shipped with. This is because
other languages can access the spec tables. Other systems can serve as
"feeder systems". It is tough to do this with classes.
Your approach is really cool, and I will definitely experiment with
it. I can image some scenerios where adding / removing features by
adding/removing a row from a linking table would be the deal!
If the application is designed for resale to a large audience with
different needs, this level of flexibility might be the way to go.
However, all of the development I've done so far is custom software to
meet a single companies needs, so there is not a need for that much
startup configuration flexibility. It's easier in that case to hard
code things that are not likely to change, as any changes in will
require a new release anyway.
You could characterize my solution as a "domain-specific spread***"
of sorts. A spread*** is not shipped with concepts such as Regional
Totals, the *** user/programmer adds that. In the payroll case it
may not be the end user who sets up items to be charged, but perhaps a
"configuration expert", sort of like a SAS representative: they don't
directly program, but tweak settings. They may be accounting interns
hired by the payroll software company to set companies up for Payroll.
This reminds me of the cabinet design software I had to use when i
worked in the cabinet business. Since it was designed to work in any
cabinet shop, it shipped with a ton of configuration variables that
had to be setup correctly to fit it to a given shop's construction
standards. This fine level of granularity of configuration allowed
them to sell it to more customers, but it was a pain to set up. And
if you ever had to go back in to modify the settings to meet new
construction techniques, you would almost inevitably introduce new
bugs in the part output because the settings were so interconnected.
Global settings == nightmare!!
So I designed my own software that interfaced with Autocad. It was
much more streamlined because I was able to hardcode our construction
methods into the object model. All cabinet parts (end panels,
drawers, doors, shelves) implemented the IPart interface:
interface IPart
{
void Draw();
}
When it came time to cut the parts, it was simply a matter of:
foreach (Cabinet cabinet in drawing)
{
foreach (IPart part in cabinet)
{
part.Draw();
}
}
This would create a 3D drawing of each part, with CAD/CAM maching
operations built in to the drawing.
The beauty was in the maintainability. When it came time to change
our construction methods, with the old solution I had to research the
hell out of the global settings to make sure I didn't inadvertently
affect the wrong parts when they cut. With my new OO solution, if I
could go straight to the object in my code that was changed and modify
the construction for that individual part. So if we wanted to start
notching the toekick into the end panels, I would just modify the
Draw() routine in the EndPanel class. Or, if we needed a new kind of
end panel, I could just create a new endpanel class that implemented
the IPart interface. Simple.. no more botched parts out in the shop.
Jordan
.
- References:
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: S Perryman
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: topmind
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: S Perryman
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: topmind
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: ggroups
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: topmind
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: Jordan Marr
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: topmind
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: Jordan Marr
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- From: topmind
- Re: Dependency Management (Was: Mixing P/R philosophy with OO)
- Prev by Date: RUP activites across multiple roles?
- Next by Date: dynamic binding on parameters, how ??
- Previous by thread: Re: compilation mechanisms (Was: Dependency Management)
- Next by thread: Re: Mixing P/R philosophy with OO (within J2EE).
- Index(es):