When should i use properties instead of object references? - class-design

For example if i have an Author class and a book class independently. We all know an author writes a book.
What i would love to know when it's best to include the book as a reference object in the Author class or just include the book name?
The reason for this question ties mainly to flexibility and easy maintenance.
Update:
What design pattern should i read up that relate to this type of issue?

I would generally store the reference to the book, and the book object is therefore readily accessible from the author. If you store the property (name) in this scenario, then some questions are:
is the name unique ?
is it costly to retrieve the book from the author (e.g. do you have to go to the database) ?
If you don't want the whole book object in memory (perhaps storing all authors with all their books consumes huge amounts of resource), then perhaps you want a book placeholder object referenced from the author class. That placeholder would store the book's unique key and can retrieve the book upon demand. It may implement a book interface and thus be indistinguishable from the real book. The downside is that the book still has to be populated upon, or prior to, a request for info.

The name would be a very bad idea; it's quite possible for two different books to have the same title.
I'd use an object reference (inside some sort of collection, of course, since an author can write more than one book) - that's what they're for. This is certainly flexible and maintainable.
There may be exceptional circumstances where this causes problems, and only then would I consider keeping some sort of unique ID (in the case of books, the ISBN would be the prime candidate) instead of a reference.

It really depends if author is ever going to need access to book information beyond that of just the title. If really never, then ok maybe you only need the title as a String. However, if additional book info is likely to be needed, you need to think about how you are going to access that. In this case it probably makes sense to use a book class.

Having the book name inside the author object will create duplication if a book has many authors. If somehow you need to modify the book name then you will have to go through all the authors collection in order to determine where you need to change.
Having a single book object referenced by all its authors is much simple. Just change the book name in one place and that's all.
In don't think is it easy maintainable or flexible a structure with unneeded duplicates.
EDIT: With duplication of the name you can also get to inconsistencies. Just imagine what happens if a book's titles (with two authors) gets its name modified just for one author.

It depends on what you want to do with the information. Sometimes it might be easier to have your list of book names stored in the author, other times you might need the full book information (ISBN, publisher etc.)
In a database you would have an Author table with all of their details, and a book table with all details of the book, then probably a many-to-many relationship table to tie books to authors and vice-versa.
Oh, and properties / object references aren't really mutually exclusive. A property CAN be an object reference. It sounds more like you are asking if you should store the full obejct information or just the piece you might need immediately.

Option B. Avoid having such references - it will quickly render your program into a mess of dependencies. Keep the two concepts independent, and if you need, some higher-order abstraction to link between the two.
Your question is a part of a complex saga known as "object-relational mappings", there's a lot of material on design patterns for that on the web.

Object-oriented when each object has references to its best friends – not to their names. There are certain downsides to it, like: it is notoriously hard to keep track of back-references.
However, the problem calls for a more general solution than a best-practice pattern.
As long as you're using OO to design your application at all, I'd opt to be consistent and keep direct references to your objects.

It really depends on your domain. Most book store databases have some discrepancies between names of authors between books, and no information whether a given name is shared by more than one author. So in that a book would have a list of author names, and there would be no object identity mapped to that data.
On the other hand, if your domain is a publishing house, you have a very good idea which of the authors John Smith ( client number 19024982 ), J. Henry Smith ( client number 19024982 ) and John Smith ( client number 773829 ) are the same or different authors, and which books those two authors have created, and so using object references for author and book identity would be a good mapping of the domain.

Related

Parse Platform on iOS: Relations, Joins, or Arrays for Large Many-to-Many?

In the Parse.com API reference for Swift on iOS, it is very clear when to use the different kinds of One-to-Many relationships, based on the expected size of the Many side.
But I find it less clear on what kind of Many-to-Many relationships to use when both sides could be very large.
In my case, I have a Charity object that my Users can make small (often one-dollar) contributions to--so each User could conceivably make thousands of these contributions, and each Charity could have thousands of Users making contributions to it.
The Many-to-Many options listed for this kind of thing are Parse Relations, Join Tables, and Arrays, of which the docs explain:
Arrays should be used when the relationship will reliably include under 100 references, which is very clear and helpful guidance that I should not use Arrays.
The docs say Parse Relations could be used, for instance, to connect Books with multiple Authors and Authors with multiple Books--a situation in which a given Book is unlikely to have over 100 Authors, and only rarely will an Author have over 100 Books--so it's unclear if this is appropriate when both sides could be very large, as in my case.
The docs say Join Tables should be used when extra metadata should be attached to each relationship, so for one thing, I don't at present have an explicit need for this, and for another, the docs don't seem to even mention anything about how or if it matters how large each side of the Many-to-Many relationship is.
In the absence of any other information, it looks like I should use Join Tables, but only because the docs don't imply that I shouldn't, and not for the reason the docs say I should.
Which seems like a flimsy rationale.
I would greatly appreciate any guidance anyone can give.
Behind the scenes, when you use Relation, Parse Server automatically creates a Joint Table for you and delivers some APIs for easily managing and fetching its data. So, in terms of performance, it should be very similar.
The downside of the Relation is the impossibility to add new fields to this "Joint Table" it creates. So, if you need, for example, to store the charities that each of the users like, a relation between User and Charity would be a good fit, because you just need to store that the relation exists and do not need to store any extra information.
On the other hand, if you need to store the donations that each user did to each of the charities, I'd create a Joint Table called Donation or UserCharity with a pointer to the User class, a pointer to the Charity class, and the value of the donation. In this case, Relation is not a fit because you need to store the donation value.

Deciding on class responsibility

I know this is an opinionated question. However it comes up often at work.
When creating methods it's often a struggle to know which class should be responsible.
e.g.
bool result = ProductService.CategoryHasSoldOutOfProducts(int categoryId)
vs
bool result = CategoryService.CategoryHasSoldOutOfProducts(int categoryId)
In my opinion, the CategoryService should be responsible, as the method is taking a categoryId and is specific to the Category.
Others at my work say the ProductService should be responsible as the method is dealing with if Products have sold out.
Just trying to develop a better understanding of service architecture and good process. I'm interested in other peoples explanations for why they would choose one over the other.
Thanks
Disclaimer - this is a purely IMHO answer. I am answering this in the spirit of having a design brainstorm.
Based on the OP, it seems the relationship between Category and Product is an optional one to many : Category (0..1) <--------> (*) Product.
Implementation wise, this means that the Category entity probably has a Container of Products, and the Product entity has a reference to a Category which may be NULL.
In this case, I agree with the decision to place CategoryHasSoldOutOfProducts under the responsibility of the Category entity. The method name clearly implies that the Category entity should be responsible for informing its API user on the status of its products.
There is another option, however: An association class/entity. The motivation behind this entity is to describe the relationship between two other entities.
In this case, you can have a functional association entity which we will call ProductContainment for the sake of this example.
ProductContainment will have no internal state, and will hold functions which are provided with Category and/or Product entities as parameters.
It is then the responsibility of the association entity to provide the implementation of functions which relate to how Category and Product relate to one another.
If you end up using ProductContainment - then CategoryHasSoldOutOfProducts should be one of its functions.
Since you're asking for opinions, here is mine:
(Disclaimer: That's probably something you cannot easily implement in the business world)
As you are using the term "class", I assume you want to have something object-oriented. The problem is, a service is nothing a valid object could be created from. Instead, it's just a namespace for functions.
Additionally it's very general. It's like calling a class "Manager". You can put possibly everything inside of it and this class has the potential to grow to have hundreds of functions.
My advice: Create small entities. Small enough to be created without the use of any setters, just by calling the constructor. If you notice your object needs more functionalities, create a decorator that is a little bit smarter and can do the work for you.
I would need a few more details about your environment to be more precise, but I guess in your case, you would have something like a Category class that contains products and knows when it's sold out. Just imagine you have a team of persons and everyone knows something. Ask the right guys to do the stuff and stay away from managers or services.

When to use Core Data relationships in Swift?

I've read through a bunch of tutorials to the best of my ability, but I'm still stumped on how to handle my current application. I just can't quite grasp it.
My application is simply a read-only directory that lists employees by their company, department, or sorted in alphabetical order.
I am pulling down JSON data in the form of:
Employee
Company name
Department name
First name
Last name
Job title
Phone number
Company
Company name
Department
Company name
Department name
As you can see, the information here is pretty redundant. I do not have control over the API and it will remain structured this way. I should also add that not every employee has a department, and not every company has departments.
I need to store this data, so that it persists. I have chosen Core Data to do this (which I'm assuming was the right move), but I do not know how to structure the model in this instance. I should add that I'm very new to databases.
This leads me to some questions:
Every example I've seen online uses relationships so that the information can be updated appropriately upon deletion of an object - this will not be the case here since this is read-only. Do I even need relationships for this case then? These 3 sets of objects are obviously related, so I am just assuming that I should structure it this way. If it is still advised to create relationships, then what do I gain out of creating those relationships in a read-only application? (For instance, does it make searching my data easier and cleaner? etc.)
The tutorials I've looked at don't seem to have all of this redundant data. As you can see, "company name" appears as a property in each set of objects. If it would be advised that I create relationships amongst my entities (which are Employee, Company, Department), can someone show me how this should look so that I may get an idea of what to do? (This is of course assuming that I should use relationships in my model.)
And I would imagine that this would be the set of rules:
Each company has many or no departments
Each department has 1 or many employees
Each employee has 1 company and 1 (or no) department
Please let me know if I'm on the right track here. If you need clarification, I will try my best.
Yes, use relationships. Make them bi-directional.
The redundant information in your feed doesn't matter, ignore it. If you received partial data it could be used to build the relationships, but you don't need to use it.
You say this data comes from an API, so it isn't read-only as far as the app is concerned. Worry more about how you're going to use the data in the app than how it comes from the server when designing your data model.

Class Naming, Should I ,name a class and make an attribute or put that attribute into the classes name

I'm trying to understand the considerations people use to name classes. What are the ways in which you decide between the following.
student = Student.new(:smart)
vs simply using
student = SmartStudent.new
Edit:
I guess there is really no right or wrong answer its just the way I need to decide what I am modeling.
In general I like to name classes at the most general form of the noun that they represent. So in your example the noun is Student. smart is an adjective describing that noun. the adjective represents a Student's intelligence. so my attrribute would be intelligence.
That way I could have:
Bill = new Student
Bill.intelligence = smart
Bob = new Student
Bob.intelligence = stupid
You should ask your self: does the student's attributes make a student really different from another?
If not and if it is possible, I'd suggest you to use the first solution you proposed. Generally is simpler that deploying a hierarchy of student types (see composition vs inheritance), because if your student types grow, then your student classes may proliferate making difficult to proper handle all of them.
On the other hand, if a Smart student class has a really custom behavior, and you want to use method overriding and stuff like that to perform operations on that classes instead of checking each time the student type of that particular class, then inheritance could be an option. I would stay away from that.
You should give us more details for a correct answer. Can't say simple yes or no to your question, because it depends on your design.
EDIT:
consider also this point: can a student have more than an attribute? If that's the case you should definitively used the first approach, other could be impossible (or at least tricky) modeling a student type that has more than one attribute (example: smart and fat).

Copying entities in Core Data

I have a couple of Core Data entities... Student and Exam.
Now, the Exams is initially just one object per exam - Maths Exam 3, English Exam 2 etc.
There is a relationship between Students and Exams in my data model (a student can have several exams). But initially, the Exams are just floating free, and not attached to any students.
How would I make a copy of one of the exams and attach it to a student?
If I do something like:
[student addExamsObject:examObject];
...then I think it simply references the original exam to the student, rather than making a copy.
I need a copy because the Exam has a boolean 'hasTaken', which is YES when the student has taken the exam. But if I set that now, it will make it seem like all the students with that exam have taken it.
Clarification: I would rather not restructure my model. The data is taken from a couple of xml files, one each for Students and Exams, which are parsed into the Core Data store. For instance, an Exam object might look like this:
name:Maths 5
class-id:12
year-id:4
student-id:0
..with a Student object looking like
name: Dave
class-id:12
year=id:4
student-id:222
Various rules are meant to guide which exams get attached to which students... for instance if all the Exam's ids are 0 then all students take the exam. If class-id and year-id match, and student-id is 0, then the Exam gets added to students with the same class and year. If the student-ids match, then just that student takes the Exam. etc etc.
I cannot change the way the xml is outputted from the server.
Another issue is that Exam has too-many relationship to a Question entity... in other words, the questions in the Exam. And I have to store answers to the questions that each student gives in an exam.
Edit: I wish people would try to answer my question rather than tell me to restructure my whole program. There are reasons why the data model has been structured like it is.
Edit2: Maybe I will have restructure....
Exam shouldn't have a hasTaken property. Think about it in the real world. An Exam would not know about who has taken it because many people could have taken it. The instance of taking an exam, then, should be a first-class concept in your model.
Consider this:
Exam has many TakenExams, TakenExams belongs to Student http://yuml.me/6627495d
Now the concept of taking an exam is a real object, you can then model assocation metadata as well, such as dateTaken, score, and so on.
Also remember that Core Data expects you to have all of your inverse associations set up as well.
You don't usually copy an entity. (I'm not sure what happens if you call copy on an NSManagedObject... it's not explained in the documentation, as far as I know. Experts can correct me. )
Just create another entity, or write a method which does just that.
I think another way is to make many-to-many relationships between Exam and Student:
create relationships in Exam called studentsToTakeThisExam and studentsWhoTookThisExam.
create relationships in Student called examsToTake and examsAlreadyTaken.
and set up the inverse relationships accordingly.
I would not argue (as You requested) if your modeling is correct or not. The procedure to copy an entity is, in general, quite complex, owing to the fact that, besides attributes, you also need to deal with the entity's relationships and copy them. I can not post here a huge amount of source code showing how to accomplish this, however, I can point you to a book where this issue is described in detail, with all of the source code you need. The book is the one from Marcus Zarra, "Core Data Apple’s API for Persisting Data on Mac OS X" by "The Pragmatic Programmers".
You really don't want to copy an Exam in this situation. You'd end up with lots of identically named Exams which didn't have a relationship with each other, and then you'd be forced to group them together (if you wanted to) by their name.
I'd recommend a new entity (perhaps "ExamSitting"?) which represents a Student sitting an Exam. You could then a to-many from Student to ExamSitting, and a to-many from Exam to ExamSitting. This enables you to have as many attributes on the ExamSitting as you like then (hasTaken, grade and so on).
Edit
Okay, given your clarification, I have a point or two to add (although they may not be what you're looking for). I understand that you're loading from files with a particular structure, but that doesn't necessarily have to dictate your structure.
With the XML files laid out as you now describe, I would still use an Exam - Student - ExamSitting model. If I were to implement it, I'd load all the Students, and then, for each record in the Exams file, I'd create one Exam object, and then a number of ExamSitting objects, one for each Student that fits the criteria defined in the record. As I mention above, this enables you to store more information about each event, such as mark, takenDate and so on.
If you're sure there's no requirement to be able to store additional information at this granularity, you could just create a to-many relationship studentsTakingExam. This could be populated as you load each exam record by querying the loaded Student entities.