Inheritance?

0 views
Skip to first unread message

Ryan

unread,
Dec 18, 2006, 8:55:15 AM12/18/06
to transfer-dev
Is there a way to extend Transfer objects? I have a fairly common
scenario. I have a base User transfers object decorated with a
mycompany.User cfc. The decorator adds authentication logic as well as
some other features. I would like to extend User having a Client.cfc,
Vendor.cfc, etc.

I would like to be able to create some type of User factory that would
return the correct class based on a type. Basic polymorphism. I'm
haveing trouble adapting this common OO model to transfer.

Would this be the best way to do it?
* Extend the decorator User cfc, creating client.cfc, vendor.cfc
* Create multiple transfer objects (via config): Client, Vendor, etc.
each pointing to the User table (assuming Single Table Inheritance
(STI) right now).
* Add the appropriate decorator to each object
* Create a factory method in a UserService that would return the
correct User subclass based on type?

I'm just thinking out loud. Any other suggestions on how to accomplish
this with transfer?

--Ryan

Mark Mandel

unread,
Dec 18, 2006, 8:45:11 PM12/18/06
to transf...@googlegroups.com
Ryan,

The short answer to your question is - well, you kinda can't. The
model you've shown is one way of doing it - but that doesn't stop you
from making a Vendor you really mean to be Client through your API.

The long answer to your question really is - this is somewhere where
you should be using Composition, and not Inheritence.

In actuality, all the objects you have are Users, but you are just
doing different things to them, depending on their Type.

Head First Design Patterns actually covers this really, really well.

I woudl say your authentication logic should sit outside the User
object, IMHO, a user doesn't know how to Authenticate, an
Authentication service should know, and it should do the right thing
depending on the type.

Or another way would be to have a Authentication object that you can
add to the User, depending on what the type is, as a comopiste.

I have found that using inheritence in this way leaves you very restricted.

Does that help?

Mark


--
E: mark....@gmail.com
W: www.compoundtheory.com

Jaime Metcher

unread,
Dec 18, 2006, 9:44:51 PM12/18/06
to transf...@googlegroups.com
Hi,

Without commenting on the composition vs inheritance decision for this
particular example:

This sort of single table inheritance pattern is where a decorator factory
would be handy ;-) But I think there comes a point where you have to admit
that transfer can't implement every domain model, although it could be the
DAO layer for any domain model. It just handles simple Active Record domain
models soooo nicely it's tempting to to keep pushing it.

OTOH, Concrete Table Inheritance works very nicely with decorators.

Jaime

Ryan Wood

unread,
Dec 19, 2006, 8:45:27 AM12/19/06
to transf...@googlegroups.com
Thanks Mark. Composition over inheritance makes sense. I'll look into
an Authentication Service as well. That would be a better option.

I'm still not quite sure how to implement composition with transfer.
For a slightly different example, how would you go about implementing
a User object composed with an Address object (assuming different db
tables and a 1:1 correlation). Since there is no "onetoone" mapper,
would you use the "onetomany"?

It seems I might be missing something simple...

--Ryan

Mark Mandel

unread,
Dec 19, 2006, 6:57:02 PM12/19/06
to transf...@googlegroups.com
On 12/20/06, Ryan Wood <ryan...@gmail.com> wrote:
>
> Thanks Mark. Composition over inheritance makes sense. I'll look into
> an Authentication Service as well. That would be a better option.

On the other side, Jaime is correct, doing STI with transfer is a bit
of PITA. It can be done, but you have to manage it well because of
the caching layer.

>
> I'm still not quite sure how to implement composition with transfer.
> For a slightly different example, how would you go about implementing
> a User object composed with an Address object (assuming different db
> tables and a 1:1 correlation). Since there is no "onetoone" mapper,
> would you use the "onetomany"?

You would use a <manytone> mapping in this situation. A 1:1
relationship is really only a a managed m:1 relationship.

Hopefully that makes sense, 'cause we had our xmas party last night,
and my brain isn't working so well.

Mark

Ryan

unread,
Dec 20, 2006, 9:31:10 AM12/20/06
to transfer-dev
> You would use a <manytone> mapping in this situation. A 1:1
> relationship is really only a a managed m:1 relationship.

The issue is that I have three tables linked by the same key (userID).
If I add the following to my user object:

<manytoone name="Details">
<link to="identity.Contact" column="userID" />
</manytoone>
<manytoone name="Preferences">
<link to="identity.Preference" column="userID"/>
</manytoone>

I get the error upon saving the User because it is trying to add two
userID columns to the update. The only way I've found to get around
this is to use two <onetomany> relationships and override
getDetails(index) with getDetails(), returning the first element, in my
decorator.

The <manytoone> creates the object in the structure I want (basically a
nested object rather than an array) but I just can't save it. Any other
suggestions?

Thanks for your help and patience.

--Ryan

Mark Mandel

unread,
Dec 20, 2006, 5:16:33 PM12/20/06
to transf...@googlegroups.com
Ryan - Any chance we can see the relevent parts of your schema? or a
similar case?

Mark

Ryan Wood

unread,
Dec 21, 2006, 9:31:46 AM12/21/06
to transf...@googlegroups.com
Unfortunately, I don't have a visual of it, but it's fairly simple.

userLogin table (PK: userID (identity)): has a bunch of login & account fields
userDetail table (PK: userID) has a bunch of personal contact info
fields for a user
userPreference table (PK: userID) has a bunch of app preference fields
for a user

All three are connected by the userID PK and have a 1:1 relationship.
It's not the ideal scenario, but it's what I need to work with.

Does that help?

--Ryan

Mark Mandel

unread,
Dec 21, 2006, 5:02:00 PM12/21/06
to transf...@googlegroups.com
Ryan,

Looking at this, looks like my other email was correct.

In terms of mapping with Transfer, they either need to be mapped as a
onetomany from UserLogin -> UserDetail, or as a manytoone from
UserDetail->User

That being said - there is no hard and fast rule that says you HAVE to
use composition. You can quite happily have thos foreign keys as
properties, and manage them that way.

Mark

Reply all
Reply to author
Forward
0 new messages