Unless, of course, you need to add/remove roles at runtime. Then you might use 
something like ERRole and role based permissions provided in ERAuth :-)

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

> On Nov 15, 2013, at 7:47 AM, Ken Anderson <[email protected]> wrote:
> 
>> As much as I hate to admit it - David’s right :)
> 
> I understand the feelings of discomfort and outright-filthiness that such a 
> statement has caused you in writing it, and everyone who read it. I hope that 
> someday I can do something to make up for it. Maybe I can make today that 
> day! :-)
> 
>> 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
> 
> Yeah, once you’ve abstracted the different properties and behaviors to 
> different Roles, those can all inherit from a common Role superclass, but 
> that is only really useful if there are attributes and relationships that you 
> need to save in the database that the different subclasses all have in 
> common, otherwise you are again forcing an architecture on something that 
> doesn’t really need it, and could become a limitation in the future.
> 
> If Role is an abstract superclass, then just make it an Interface instead. 
> You can add an abstract “DefaultImplimentation” inner class to the Interface 
> that has any common business logic for the defined interface so you don’t 
> have to write duplicate code (since an interface can’t have method 
> implementations). DefaultImplimentation would itself extend 
> “ERXGenericRecord”.
> 
> In this situation, AccountRole, SuperuserRole, etc. would implement IRole, 
> and extend IRole.DefaultImplementation. The hardest part about doing this is 
> that you’ll have to modify the EOGenerator templates to make this work 
> because the EOModel has no understanding of Interfaces, or that some EOs 
> might extend something other than another Entity or EOGenericRecord.
> 
> Then, of course, there is the “opportunity" to use Generics so you aren't 
> constantly casting IRole object into one of its implementors...
> 
> But, this could be an example of too much abstraction… in which case, maybe 
> now you’ll sleep better, Ken!
> 
> Dave
> 
> 
>> 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]
> 
> 
> —————————————————————————————
> 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/rgurley%40smarthealth.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