Hi Ted,

Here’s my opinion (hey, you did ask for it!):

I believe the kinds of inheritance being suggested here are all the wrong way 
to model it. It is almost always better to model an association as “has-a” 
rather than “is-a”. (keep reading to see what I mean by that)

I, personally, avoid inheritance in the EOModel if at all possible. Not because 
it is bad or hard to work with, but because in most cases it is not the *right* 
thing to do. Just like if I write non-UI code that uses “instance of” I know 
that I’m almost certainly doing something wrong. Not always, but often enough 
that I will stop and take a step back and REALLY look at how it is architected.

If you model the Person/Client correctly you will have no problem with how to 
model the relationship to Address. That issue will solve itself.

Okay, let’s get started:

>>>> Except    Clients tend to be businesses with EINs instead of SSNs. So 
>>>> there really are Clients.

Bzzzzzt.  Tend to be?! If you are going to use a structure as inflexible as 
inheritance on this they MUST ALWAYS BE, or there must be a very important 
business rule that keeps them separate. Is it really true that you never, ever, 
ever have a client that is just one guy and he doesn’t have an EIN? Or have a 
Person that has a relationship to other People? Those are perfectly legitimate 
concepts, yet you are forcing it to not be workable.

I think being a client is a role that an Object has (has-a) not what it is 
(is-a). Sometimes it acts like a “Client", at other times it could act like a 
“Vendor” and maybe, just maybe, if the Organization is a very simple one, it 
acts like a “Person"

I think Marcus’ suggestion of LegalEntity is great, I’ve also used “Actor” in 
the past. “Entity" would be ideal, but well, that’s a bit overloaded here in 
WOWorld! :-)

But! Instead of extending LegalEntity with subclasses for Person, Client, 
Vendor, WOGod, etc. You have a “Role” table that has one row for each of those. 
Now instead of a LegalEntity needing to be (is-a) one *and only one* of those 
subclasses, it can take-on any (has-a) Role (LegalEntity <<=> Role)s or even 
have multiple *simultaneous* roles (LegalEntity <<=>> Role)! So a Person could 
also be a Client and would have all the attributes and behaviors of both. 

This allows your to abstract away all the behaviors and such that are 
Person-specific, Client-specific or Vendor-specific to delegate classes for 
each Role. The delegate classes are where you have the role-specific 
implementations.

For example, LegalEntity's method taxIdentifier() simply asks the delegate for 
the value.

public String taxIdentifier() {
        return delegate().taxIdentifier();
}

The CLIENT delegate’s implementation of taxIdentifier() is:

public String taxIdentifier() {
        return employerIdentificationNumber();
}

The PERSON delegate’s implementation is:

public String taxIdentifier() {
        return socialSecurityNumber();
}

Now imagine something much more complicated such as “exportAllContactInfo” 
where “Client” needs to iterate over all the employees parse their contact 
info, flag which ones may perform a specific role and add them all individually 
to to a single .vcf file that holds multiple contacts. The Person simply writes 
writes out their own contact info into the .vcf. Each implementation goes in 
the delegate and the LegalEntity doesn’t know anything about what it takes to 
put each one together. It’s totally encapsulated in the delegate.

You can enforce what actions a delegate must be able to perform by creating 
Interfaces that both the LegalEntity and Delegate implement. The LegalEnity’s 
action() implementation will simply be to call delegate().action()

The biggest drawback to this architecture is the level of abstraction is much 
higher and therefore can be more complicated to get setup, but it is soooo much 
more flexible and much more future-proof.

The art of software architecture is knowing when to stop adding levels of 
abstraction. I think this level of abstraction is always preferable to 
Inheritance.

Now, back to Address (finally)

You are left with: LegalEntity =>> Address

Easy, no?

(you can model the back pointing relationship if you need a delete rule other 
than “nullify” when you delete an Address.

Now for some un-asked-for advice! :-)

Do NOT normalize Address! It does not matter if the same address is both 
billing and shipping. Put it in there twice - even if UI makes it look like it 
is just one.

This avoids the problem of someone wanting to change only their shipping 
address but because that one record was both, they end up editing their Billing 
address too. The UI design needed to deal with one Address with multiple 
“types" is much more complicated than the UI design needed to manage multiple 
identical ones.

Dave


On Nov 13, 2013, at 11:37 PM, Ray Kiddy <[email protected]> wrote:

> 
> On Sep 16, 2013, at 9:51 AM, Joel M. Benisch <[email protected]> wrote:
> 
>> Markus:
>> 
>> As per the private email I sent you over the weekend, which you can most 
>> certainly send to the list if you like, I believe that you are confusing 
>> things that occur in nature (Organizations, People and Addresses) with the 
>> "Roles" that they play in your (or any) environment and implementation.
>> 
>> Have an Entity Object/Table that can contain two types of objects, People 
>> and Organizations.  A variable in the object will tell you which type "this" 
>> object happens to be.
>> 
>> Have an object/table that defines the role that any Entity is "playing" in 
>> any given situation.  You can therefore have in infinite number of Role 
>> Types.
>> 
>> Than have an "EntityAggregate" object/table if you need it.  This would be 
>> used to relate multiple Entities together into any type of group you may 
>> need.  Include an AggregateType variable and you can have an infinite number 
>> of aggregate types.  This allows you to handle Departments, Offices, 
>> Spouses, Families or any other type of combination of people you may need.  
>> It also allows you to aggregate organizations should you need to do that, 
>> like all Vendors of a given type, or all Clients that are serviced by a 
>> given employee, or whatever.
>> 
> 
> The entire bit above can be summarized as "use single-table inheritance". 
> Just FYI. Different sub-entities, even if in the same table, can have 
> different attributes, and it is simple if the attributes are not mandatory.
> 
>> Then you have an Address Object/Table.  Addresses can then be associated 
>> with any member of the Entity Table, or any number of members of the Entity 
>> Table, and you're all set.  When an employee or Vendor or Client moves, you 
>> don't delete or change the existing (now old/obsolete) address from the 
>> table, you add the new one and flag it as "current" if you want.  This way, 
>> old data will still display and associate to the correct old address that 
>> was valid at the time the invoice, or purchase order, or whatever was 
>> processed.  It also allows you to use the "old" address on another Entity 
>> when some other Client or Vendor happens to rent the same space that had 
>> previously been occupied by the first one.
>> 
> 
> I tend to add a deletedDate attribute here. Then, adding a "and the 
> deletedDate is null" qualifier whenever I fetch objects ensures I only see 
> the current ones.
> 
>> We work in the Insurance Industry.  This approach has stood the test of time 
>> (three decades) quite well.
>> For instance, a person can be a Client, and also a spouse of another Client, 
>> and also the Parent of another Client, and therefor a member of a Family 
>> Aggregate.  That same person can be a Driver on an Auto Policy, an Insured 
>> on various policies, an officer of a Client that is an Organization Entity, 
>> etc.  These are all Roles that this Person Entity is playing.
>> 
> 
> Wow. Why can't my insurance company do this? My insurer has an idea that my 
> wife is primary on the account and they can't figure out how I relate there. 
> We kept separate last names. What were we thinking. :-)
> 
> 
>> The person appears once in the Entity Table, but can be used for an 
>> unlimited number of Roles.
>> 
> 
> Just remember, entity inheritance can be your friend, especially if done 
> right.
> 
> - ray
> 
> 
>> Hope this helps,
>> Joel
>> 
>> On Sep 16, 2013, at 8:59 AM, Markus Ruggiero wrote:
>> 
>>> 
>>> On 15.09.2013, at 06:28, Theodore Petrosky <[email protected]> wrote:
>>> 
>>>> Except    Clients tend to be businesses with EINs instead of SSNs. So 
>>>> there really are Clients. But sometimes in accounting an employee is a 
>>>> vendor because you need to draw a check outside of the normal employee 
>>>> employer relationship.
>>>> 
>>>> I am trying to normalize this structure. Maybe I shouldn't. I would love 
>>>> to hear other people's solutions. but to reiterate, Clients need 
>>>> addresses, People need addresses. if I create a table Address, I could 
>>>> relate it back to Client, and relate it to Person.
>>>> 
>>>> So maybe I should change the name to:
>>>> 
>>>> Business
>>>> Person
>>>> 
>>>> Person  will have two booleans 'isEmployee', and 'isClient', with a SSN 
>>>> Business will have two booleans 'isClient', and 'isVendor' with an EIN
>>>> 
>>>> both will have a to-many to Address and each address will have a type (i 
>>>> guess a business address will not be a 'love-nest').
>>>> 
>>>> I just never created an Entity that related back to two other Entities. So 
>>>> does that mean 
>>>> 
>>>> Business <=>> Addresses
>>>> Person <=>> Addresses   
>>>> 
>>>> and because of the structure, the relations have to be optional. although 
>>>> an address will always be related to either a Business or a Person.
>>>> 
>>>> 
>>>> Or how about an Entity Address and a subclass PersonAddress and another 
>>>> subclass BusinessAddress?
>>>> 
>>>> Opinions?
>>>> 
>>> 
>>> 
>>> I would model this like so:
>>> 
>>> Entity "LegalEntity" with "Client" extending "LegalEntity" and "Business" 
>>> extending "LegalEntity". Both, Client and Business share many common 
>>> attributes like name etc, Both can have individual attributes like SSN for 
>>> Clients and EIN for Businesses. 
>>> Now the addresses: How to model these depends on the answer to the 
>>> following question: Can the same address be used for different purposes? 
>>> If no:
>>> Create an entity "Address" and have one attribute called "addressType" or 
>>> some such. AddressType is one out of "home", "work", "love nest" etc. and 
>>> model "LegalEntity" <-->> "Address"
>>> if yes:
>>> Create an entity "Address" without a type specifier. Create an intermediate 
>>> entity like "LegalEntityAddress" with an attribute to specify the type. 
>>> Model the following relationships:
>>> "LegalEntity" <-->> "LegalEntityAddress" <<-> "Address"
>>> 
>>> Hope this helps.
>>> Have fun
>>> ---markus---
>>> 
>>> 
>>>> 
>>>> On Sep 14, 2013, at 10:29 PM, Ramsey Gurley <[email protected]> 
>>>> wrote:
>>>> 
>>>>> Personally, I would look more closely at your person class. Is a client 
>>>>> actually a person too? It sounds like it. If so, I would not have a 
>>>>> client entity. I would simply make a person entity and assign each person 
>>>>> one or more roles. A person might have a client role, a vendor role, and 
>>>>> a customer role. Then you simply have a relationship between person and 
>>>>> address.
>>>>> 
>>>>> 
>>>>> On Fri, Sep 13, 2013 at 9:29 PM, Theodore Petrosky <[email protected]> 
>>>>> wrote:
>>>>> I need an opinion about relationships.
>>>>> 
>>>>> I want to have an entity  Person with a to-many to address. a Person 
>>>>> could have many addresses (home, second home, weekend place, love nest).
>>>>> 
>>>>> And I have clients. a Client needs addresses too (billing, main office, 
>>>>> act rep, etc)
>>>>> 
>>>>> how would you model this?
>>>>> 
>>>>> a person entity with a to-many relationship to address
>>>>> a client entity with a to-many relationship to address
>>>>> 
>>>>> or would you create a subclass of address and map that to the clients.
>>>>> 
>>>>> is it 'bad' to have two to-many relations to an entity, (both person, and 
>>>>> client mapped to entity address).
>>>>> 
>>>>> Ted
>>>>>   
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list      ([email protected])
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/webobjects-dev/webobjects%40avendasora.com
> 
> This email sent to [email protected]


—————————————————————————————
WebObjects - so easy that even Dave Avendasora can do it!™
—————————————————————————————
David Avendasora
Senior Software Abuser
Nekesto, Inc.





 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to