As much as I hate to admit it - David’s right :)

Inheritance is useful in some places, but you should really use a different 
pattern when dealing with people, companies, and roles.

One place I DO use inheritance is when Roles have different attributes.  So, I 
might have something like:

Role
        AccountingRole
        SuperuserRole
        PersonnelRole

and those different roles might have different attributes and relationships 
(modeled with single table inheritance).

So, the person has:

Person <->> Role

and now you can easily model people with multiple roles, and those roles can 
have varying pieces of data based on what’s required.

Ken

On Nov 14, 2013, at 8:49 AM, David Avendasora <[email protected]> wrote:

> 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/kenlists%40anderhome.com
> 
> This email sent to [email protected]

 _______________________________________________
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