Re: Dependency Management (Was: Mixing P/R philosophy with OO)



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,

P/R does this also

encapsulation, inheritance,
polymorphism,

You haven't shown what you are polymorphing and inheriting off of.
There must be multiple similer "things", what are the similar things?
Are they instances or taxonomies?


Perhaps I am more P/R than I thought. Here is a recent example from a
project that utilizes polymorphism:

A webpage with a datagrid displaying a list of users whose access is
about to expire. For each user, you can select a radio button to
either "approve" or "delete" their access, and then a "process" button
batch uploads the results into the RDBMS. My setup looks like this:
interface IRenewal
{
void CheckRules();
bool IsValid { get; }
RulesCollection GetBrokenRules();
void Update();
}

A "RenewalApproval" object and a "RenewalDelete" object both implement
"IRenewal", each having a different set of properties, and each
updating to a different stored procedure with parameters that match to
their respective properties. They have different properties because
Approvals need to save a new expiration date, and Deletes don't, among
other things. Each renewal object also has its own set of business
validation rules. This rule system is part of a reusable business
framework that is encapsulated in my LayerSuperType object,
"BusinessBase" that my business objects inherit from. This class
encapsulates and delegates to a "BrokenRules" class, and also has
other useful tools common to business apps. This inheritance of a
LayerSuperType (PoEAA - Fowler) allows me to reuse this library in
many projects.
RenewalApprovals have different validations that need to be checked -
for example, expiration dates need to be validated, etc.

When I process the grid, I create a new RenewalApproval or
RenewalDelete, depending on the radio button selected, and then add
the renewal object to my RenewalCollection. Then I have a collection
of IRenewal objects that I can easily loop through, CheckRules() on
each IRenewal, if !renewal.IsValid() display GetBrokenRules(), or if
IsValid() call renewal.Update().

I imagine that this to be an OO approach, as it takes advantage of
inheritance, encapsulation, delegation and polymorphism. It also
encapsulates different behavior into multiple Renewal objects in lieu
of putting it directly into case statements.

There were two renewal pages, and both pages worked similarly and were
able to employ the same set of objects above. Thus, if I add a
validation rule to my RenewalDelete object for example, both pages are
updated.

What does putting set/gets around a result set give you? It is
temporary and local (per task). Encapsulation does not buy anything at
such a small local scale.

Sure it does: it allows me ultimate control over a business object in
my business layer that will be consumed by my UI programmer. I want
my UI programmer (sometimes me, sometimes a junior programmer) to have
ready-made business objects that are as low maintenance as possible.
That they can just plug straight into a datagrid, databind, and that's
it. I want that object to be dummy-proof, encapsulated, formatted,
etc. I want properties to be read only (getters only) by default, and
I want them to return a formatted value. I want to be able to
restrict access to individual properties and methods on an object
according to the logged on user's roles. I want to hide internal
stuff like my broken rules framework, and only expose the stuff that
the UI designer needs. I also want my business objects to employ a
common set of business functionalities (inheritance from the
supertype) that my UI developers can easily recognize and be familiar
with.

I used to do more of this when the tools supported alterable temp/
local tables. (Newer tools stopped allowing such when OO came in favor
because everybody thot objects would do it instead. It became a self-
fullfilling prophecy.) However, since the result set is temporary and
local, one can usually do such while processing the record, such as
with an IF statement. It generally is only used once per task. And one
could emulate a local table with arrays and/or associative arrays just
as well as they could with objects IF they wanted an alterable result
set. I just don't see the need for encapsulation of something with
limited scope and duration. It is a waste of wrappers.

Not when I'm releasing my business objects for other people to consume
outside of the business layer.

The ideal solution is for tools to bring back alterable local temp
tables, like they were doing in the 80's before OO fadding killed that
direction. Thus, if we needed to tweak the result set for the task, we
could. This would greatly reduce any remaining need to build complex
array/pointer/OO structures in app space.

I don't think it's that complex. A purchase order object with a
collection property holding order lines is not going to take up
roughly the same amount of RAM as a dataset structure of the same
data. Only you then have the ability to inherit from a
EntitySuperType object that allows you to reuse an encapsulated
business object framework to process the data. It's just saying
"order.OrderLine[0].Price" instead of "orderLineDataSet[0]["Price"]",
or whatever. In dotnet, if you have a dataset with two related
tables, to get a related orderline you have to first specifiy a
relationship between the two tables in the dataset (specifying the
PK / FK relationship) and then you have to call a .GetRelatedRows()
function (something like that). Yuck. I'd much rather say
"orders.OrderLines". It just makes so much more sense to me!

But since local tweaking of the result set would only help about 5% to
15% of all routines I estimate based on experience, it does not make
much difference, especially if one is good with the vendor's SQL
features so that they can do fancy transformations in the query
itself. It is generally possible to dump/shift more of the work onto
the server end if the client has wimpy table tools.

But consider my situation, where I am not writing any of the stored
procedures. Or consider the situation where you are tapping into a
3rd party database and you don't have access to change the SP output.
In those (common) situations, it makes a lot of sense to modify the
data output in the property getter in the application memory space.
Or, if you are creating the stored procs yourself, you may not want to
format the data for the app if multiple apps will be accessing that
same data and they may not want it pre-formatted in the same way.
Again it makes sense to format at the application level instead of at
the central data store level.

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 I don't care if an OO person did
come up with that solution; it's not the correct way to solve the
problem, IMO.

Well, if you want to define and coin the term "proper OOP" (Poop :-)
so that the reader knows the difference, be my guest. It is not my
fault that publishers allegedly do OO wrong. Give the proper way a
name to distance the "proper" way from them. It is not my job to clean
up OOP. Thus, the strawman accusation is misplaced.

Sorry to offend. It seemed like a strawman to me, but maybe I was
just shooting the messenger. Then again, it's hard to judge any
solution in the absence of REAL design specs. Most of these book
examples do not give design specs and therefore it seems pointless to
try and judge their effectiveness. The OO books that I have read
specifically state that "inheritance is an often oversused feature",
and say that composition should be used instead, as much as possible.
This leads to using patterns like Strategy in lieu of inheritance
whenever possible.

Btw, some books, like Fowlers Patterns of Enterprise Application
Architecture, are much more pragmatic in their approach. This book in
particular doesn't adhere to a strict OO apprach, instead favoring a
sprinkling of different approaches that work..whatever works best for
the situation.


Thus, is Martin also doing OOD wrong??? He is a programmer acting as a
"glorified product clerk" too.

I think there are situations where the job of being a glorified
product clerk is the easiest way to go. It can be a really quick fix
if you know exacly which object to change to affect the production
environment appropriately and without side effects (i.e. changing a
global setting that inadvertently affects the wrong thing)!

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.

So you resign from claiming that the OOP approach is objectively
superior?

What I'd take from this conversation is that the balance of power
between OO frontend software and RDBMS backend should vary between
applications. I think it is too broad to say OO is overkill in
business apps. When I think of business apps, i think of a custom app
written for a single business's needs. OO and a certain amount of
software hardcoding seems to work well here because the specs are very
defined and specific to that business only. Retails apps that are
designed to be sold with a one-size-fits-all approach, may indeed
benefit from better utilizing relational algebra to tailor the
features to each specific business at run-time.

I think design specs are central to all of this. The specs will state
how flexible an app needs to be, then you can design it accordingly.
Building all the flexibility into the DB may be the way to achieve
that flexibility for one-size-fits-all apps.

I must admit, 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 a really slick way to do it!

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.

Agreed, but I am responding to OO'ers who claim OO is easier to
change. I've shown[1] a case where it isn't and you appear to agree.
I've described how to add concepts to paychecks such as union dues and
parking fees without ever touching the app code. You cannot beat
"zero" LOC in this particular code change scenario. I've met my side
of the bargain.

[1] Well, I haven't actually shown it yet, but I will soon. The coding
is done, I just need to document it and have been dragging my feet.

If I was writing a payroll system for one and only one company, I
would probably hard-wire such concepts also.



This would create a 3D drawing of each part, with CAD/CAM maching
operations built in to the drawing.

But isn't the drawing in data? If so, then "part.Draw()" and
"drawPart()" will not be significantly different. CAD/CAM has been
resistent to RDBMS for allegedly performance reasons.

The drawing is actually made by interacting with the Autocad API.

With that said, there was a company who made software very similar to
mine, only it was for resale to the public, and was very RDBMS
oriented. So I wouldn't say it is resistant to the P/R way.

I am not that
familiar with that domain, so I won't comment on it. I never claimed P/
R was for every domain. It just seems to work at least as well for my
domain. If you claim OO works better in CAD/CAM, I will not challenge
that.

I can see that P/R has some very nice benefits indeed.

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.

You managed to slip yet another "shapes" example into this somehow,
didn't you :-)

I'm just describing one side of the elephant! :)

Jordan

PS. Google Groups is F'd up of late. Growing pains?

-T-

Oh good grief yes. My original reply was lost in cyberspace. Now I'm
wise to them and will be saving my responses before sending!
And sorry in advance if this post shows up twice.

Jordan

.



Relevant Pages

  • Re: Dependency Management (Was: Mixing P/R philosophy with OO)
    ... Each renewal object also has its own set of business ... other useful tools common to business apps. ... RenewalDelete, depending on the radio button selected, and then add ... inheritance, encapsulation, delegation and polymorphism. ...
    (comp.object)
  • Re: WWW/Internet 2009: 2nd CFP until 21 September x
    ... If you can decompose the table into multiple tables each of which has no nulls, what you discover is that a null in the combined table corresponds to an absent row in one of the decomposed tables. ... If I knew then what I know now, I would have refused the whole business and gone into a sensible line of work. ... At one time, maybe it was when Dijkstra was active and 'The Psychology of Computer Programming' was a current book, this culture was evident amond C programmers. ... I have some sympathy for Walt's comments on the grounds that I thought more than half of the apps I saw wouldn't have been needed in those businesses if I had been signing the cheques, let alone most of the requirements. ...
    (comp.databases.theory)
  • Re: Access 2010 with Sharepoint 2010
    ... not all of their business processes on systems like eBay. ... Then there's all the hype about social networking and such. ... but these apps are still primitive ... My clients can still operate without the Internet, ...
    (comp.databases.ms-access)
  • Re: WinXP performance, diagnostic and optimization software
    ... What I do in my business is, among other things, design ... custom user and database apps that interface to commercial business software ... such util but I do not trust it; it finds supposed unused DLLs but it ...
    (microsoft.public.windowsxp.general)