Not too sure how to explain this one, but here goes…
I’m building an object structure for my data (in Objective-C) to have the following:
- A
Companiescollection class- which contains many
Companyobjects- each one of these has a
Userscollection class- which contains many
Userobjects
- which contains many
- each one of these has a
- which contains many
The aim is to have data on the objects (i.e. companyID, companyName), and methods on the collection classes (addCompany:, deleteCompany:).
What I really want to do is to structure the classes so that I can make the following call:
[[companies getCompanyWithID:1] addUserWithName:@"Duncan"];
But to do that, I would need to put the method addUserWithName: on the companies collection class.
To me that doesn’t make sense – the methods to add/amend/delete/get users should be on the Users collection class, not on the Companies collection class.
If I put those function on their relevant collection classes, I then have to write the same statement like this:
[[companies getCompanyWithID:1].users addUserWithName:@"Duncan"];
But then it doesn’t read as nicely – because it has a nasty .users lurking in the middle.
Am I being really dumb and missing something obvious (I never went to techie school, so it’s likely I missed something fundamental which you guys all know about).
Any help, much appreciated guys. Thanks a lot.
I may be misunderstanding your concern, but I don’t think this is an issue. Your user management methods would be on
Company, notCompanies, and that’s generally an acceptable pattern.Let’s go with the assumption that you have four classes:
Companies/CompanyandUsers/User. Now we can define a method:This says that the
Companiesclass can get you back aCompanyby its ID. (Side note: in Objective-C, we rarely use theget...prefix for accessor methods – just start the method with the thing that you want, in this casecompany....)The traditional thing to do from here would be to have your
Companyclass expose a good chunk of public API for managing users. You might do something like:In turn, the
Companyclass will be responsible for knowing about the inner workings of theUserscollection, including modifying it as necessary. With that in mind, you could write:This way, you avoid exposing the
.usersto external clients of theCompanyclass – you just pass theadd...message forward.You could even take this strategy further and say that the
Userscollection class is an implementation detail and never needs to be exposed to clients of theCompanyclass. Instead, you could provide accessors to yourUserscollection in terms of a more standard system collection object:The absolute extreme of this thought process would lead you to get rid of your
Usersclass altogether and just use system classes to manage the collection of users directly on yourCompanyclass. On one hand, this would let Xcode infer and suggest (through autocompletion) certain methods that fit this pattern well – take a look at the KVC compliance section of the Key-Value Coding Programming Guide for such methods. On the other hand, you may have more complexity that doesn’t show up in your question, so theUsersclass may be necessary for your use case.