Let's say I have a list of Person with some attributes. For each object in this list I want to create a new Person object but only based on some of its attributes.
The Person object has the following attributes : age, name, disease.
I want to create a new Person only on its age and name. The disease attribute must be confidential.
How could I do that ?
Thanks in advance !
You very easily could do this by creating a new object entirely which does not hold that information. For example, you could make a class such as this
public class PersonNoDisease {
private int age;
private String name;
...
}
If you want to make sure that PersonNoDisease still has many of the same methods that the original person class did, you should create an interface that they both implement to ensure that they both have the methods which you think they should both have. If you don't have getters in the Person class, you should make those so that it will be easier to initialize this new class.
Related
I am trying to make this example as natural as possible to make it simple.
Lets say I have groups of items. eg item1, item2, item3, item4 etc.
Currently item is represented by struct:
// only contains data
struct item{
string name;
std::vector<string> parts_name;
std::vector<double> parts_price;
std::vector<string> item_color;
...
};
itemx item1, item2...
Then I have class called items
class items{
public:
// return name of all items
vector<string> get_all_item();
// return price of all parts
vector<double> get_all_parts_price();
private:
// hold vector of item
vector<shared_ptr<item>> list_of_items;
// name of item and its parts price
// eg: <item_1_part_1, $1.3>
// eg: <item_1_part_2, $2.3>
// eg: <item_2_part_1, $4.3>
map<string, double> parts_prices;
};
The problem with my current items class is that it is growing really huge,
as feature of item increases.
My solution: make struct item contain function which distributes load
to struct item from class items.
Is there any other better way or any design pattern that is meant for this kind of problem?
It is hard to tell you how to "design" your application based on your input - and I think you are focusing on the wrong aspect here. Your item struct contains vectors. That implies plural. But still, the class is called item.
In that sense: don't think about patterns here. Instead, step back and have a much closer look at the "real world things" you intend to model. You see, the core point of objects and classes is to built a model of the domain you are dealing with.
So a non-answer here: carefully look into the "real-world" relation that your objects have, and then focus on creating a OO model that is helpful to do work flows you intend to implement.
The OData standard is pretty straight forward when it comes to doing queries and aggregations on fields, but I am having trouble wrapping my head around querying/aggregating against a field that is a collection or map.
For instance, lets say I have the following random class:
public class Teacher{
public String name;
public String city;
public List<Class> classes;
public Set<TeachingAssistant> TAs;
public Map<Class,List<Student>> studentsPerClass;
public Teacher(...){
//init all variables
}
}
Now, this is just an example. For the purpose of this example, the teacher class is the only way to get at students, Tas, and Classes. So, all of my queries and aggregations will need to be run off a collection of teachers. With that in mind, I have some questions:
How do I do aggregations on the list of classes? Like if I wanted to know the number of classes offered by a teacher, how would I do that in an OData query?
For instance, I would like to do something like:
.../Teachers?$apply=aggregate(classes with CountDistinct as totalClasses)
or maybe:
.../Teachers?$apply=aggregate(classes(*) with CountDistinct as totalClasses)
Would either of these be the correct way?
If I want to query a specific item in a list or set, how do I access it? A Set in java is not ordered and does not have anything for me to access it like setName('<value>'). For lists, would I just have to say listName('<num_index>')?
Edit: I called it association because in my head it should be this, but it seems that I implement it as an aggregation... This can be also discussed...
Context
What you learn in IT is that when you do associations, you should use pointers.
For example: You have 2 objects: Person and Movie. One Person can do several Movie and one Movie can be done by/with several Person. You would then have:
class Person
{
public:
Person::Person();
int id;
vector<Movie*> movies;
};
class Movie
{
public:
Movie::Movie();
int id;
};
main()
{
Person person;
Movie *movie = new Movie;
person.movies.push_back(movie); // With a setter it would be better but...
}
or something like this (please correct me if I do something wrong =D)
Where the troubles appear
Now you have many persons and movies and you want to save it somewhere: in a database.
You get your person
You get all the movies it is associated with in order to construct the whole object.
But how do you get them?
Do you reconstruct a new pointer of Movie for each Person concerned that you associate ?
You lose then the association property that allow the objects to be linked but live their own life.
Do you load all the database in RAM and... ok forget this
What is the way to do it cleverly? What is the proper way given by documentations?
I'm interested in simplified/pseudo code as examples, dissertation... Thx a lot !
Your question is very broad, and there's a number of approaches, how to bind database tables (and represent their foreign key connections).
It's not really only how to represent/handle that kind of Domain Model snippet, you're presenting in your code sample here.
#Martin Fowler provided the EAA pattern catalogue you could reasonably research, and apply appropriate patterns for these kind of object <-> relational mapping problems you address.
i'm currently working on a project and something came up on the design.
I have a class named Key which is composed of several Fields. This Field class it's a mother class and their sons like Age, Name, etc implement Field. Inside the Key class there's an attribute which is an array of Fields, to hold different kinds of Fields.
class Key {
private:
Field * fieldList;
}
I'm working on a team and a design choice came up that i couldn't defend cause i didn't knew how to answer to the following problem... or maybe the lack of it? I trust that you'll be able to open my mind on this.
The purpose of this Key class is to hold several fields. The existence of this class is because i'm going to handle data of this kind.
(Name, Age....)
This is how i thought it would look already implemented:
Key myKey = Key();
Age newAge = Age(50);
myKey.add(newAge);
This is what the prototype of the add method of the Key class would look like:
void Key::add(Field);
As you may have assumed, since the Key class has an array of Field's this method receives a Field and since Age is also Field, cause of inheritance, then this works like a charm. Same can be said of the Name class and other classes that could come up in the future.
This is the same idea as in a database where you have rows with data and the columns belong to the attributes, so a same column has the same type of attribute.
We would also like to compare 2 Key's only by one of the Fields, for example:
Let's say i have 2 Key's with this data:
(John, 50) <- myKey1
(Paul, 60) <- myKey2
My method to do this would look like this:
myKey1.compareTo(myKey2, 2)
This would answer if the 2nd attribute of the first myKey1 is bigger, equal or less than the one on the second myKey2.
There's a problem with this. When i used the add method, i randomly added Field's of different types, say Age first, then Name second, etc to the Key object. My Key object added them to it's internal array by order of appearance.
So when i use the compareTo method, nothing is assuring me that inside both objects, the 2nd elements of their arrays will have a Field say, the Name Field, and therefore if that were not to be true, it could be comparing a Name with Age, cause inside it only holds an array of Field's, that are equal type as long the Key class knows.
This was my approach to my solution, but what i couldn't answer is, how to fix this problem.
Another member of my team proposed, that we implement a method for the key class for each of the existing fields, that is:
myKey.addAge(newAge);
myKey.addName(newName);
Inside it would still have the Field array but this time, the class can assure you that Age will go in the 1st place of the array, and that Name would go in the 2nd position of the array, cause each method would make sure of it.
The obvious problem with this, is that i would have to add a method for each type of Field that exists. That means that if in the future i wish to add say "born date" and so creating the new Date class, i'll have to add a method addDate, and so on and so on...
Another reason my team member gave me is that, "we can't trust an exterior user that he will add the Fields the way they're supposed to be ordered" when pointing why my approach was bad.
So to conclude:
On the first approach, the Key class depends on the programmer that added Fields, to make sure they have the order they should, but as a benefit no need to add a method for each type of field.
On the second approach, the Key class makes sure the order is the right one, by implementing a method for each type Field that exists, but then, by each type of new Field created, the class would grow bigger and bigger.
Any ideas with this? is there a workaround for this?
Thanks in advance, and i apologize if i wasn't clear with it, i'll add new details if needed.
Expanding on #tp1's excellent idea of an ID field in the Field class and an enum, you can actually make it very flexible. If you are comfortable limiting the number of field types to 32, you could even take a set of flags as the ID in CompareTo. Then you could compare multiple fields at the same time. Does that approach make sense?
I have a many to one relationship and I am trying to persist a child entity.
public class Office
{
public int id;
public int grades;
#OneToMany
public set<Employee> employees;
}
public class Employee{
#GeneratedValue(strategy=GeneratedValue.identity)
public int empid;
#ManyToOne(cascade=cascadeType.ALL)
public Office office;
}
Office Id is already present in the database. But employee is not.
Now if i am adding an employee and his grades must go into the office database.
When i do the following operation,grades are not getting saved
Office office = new Office();
office.setId(23);
office.setGrades(5);
employee.setOffice(office);
em.persist(employee);
How to save grades into the office table in a single operation
First, fix your mapping.
The association is bidirectional, and one of the side (the one side) must be marked as the inverse of the other using the mappedBy attribute:
#OneToMany(mappedBy = "office")
public set<Employee> employees;
The employee is only one of the employees of the office. Do you really want to delete the entire office when you delete a single employee? If not, why do you put a cascade=cascadeType.ALL on the #ManyToOne? Those annotations have consequences. Don't use them without understanding them.
Now to really answer the question. If the office already exists in the database, you should not build a new one. Go fetch it from the database and update it:
Office office = em.find(Office.class, 23);
// office is now attached, and any change you make on the entity will be written to the database
office.setGrade(5);
Now you may also attach the office to the new employee. But since it's a bidirectional relationship, you should also initialize the other side of the association to keep the object graph coherent:
employee.setOffice(office);
office.addEmployee(employee);
em.persist(employee);