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]