I have an object that I want to populate with information. I retrieve the information from a number of different services. I made a helper class that has one public method and then has a number of private methods that do the work to call the services. What I have written works fine but I'm not sure if it is the correct way to do this.
You may be wondering why I need an object holding all this information. I need it all in one object because I create a json object from this java object and pass that to the javascript layer.
What is wrong with my approach and is there a programming paradigm I should be following to do something like this?
Example:
Person object with getters and setters for firstName, lastName, age, height, weight, list of favourite foods, list of favourite countries, list of comments.
Service 1 gives firstName, lastName, age, height and weight
Service 2
gives list of favourite countries and list of favourite foods
Service
3 gives a list of the comments made by the person
I have a personHelper class that looks like this:
public class PersonHelper{
public Person getPerson(userDetails){
Person person = new Person();
this.setPersonDetails(person, userDetails);
this.setFavourites(person, userDetails);
this.setComments(person, userDetails);
return person;
}
private Person setPersonalDetails(Person person, UserDetails userDetails){
returnedObj = callToService1(userDetails);
person.setFirstName(returnedObj.getFirstName());
person.setLastName(returnedObj.getLastName());
person.setAge(returnedObj.getAge());
person.setHeight(returnedObj.getHeight();
person.setWeight(returnedObj.getWeight());
return person;
}
private Person setFavourites(Person person, UserDetails userDetails){
<List>favsList = callToService2(userDetails);
person.setFavourites(returnedObj.getFavs(favsList));
return person;
}
private Person setComments(Person person, UserDetails userDetails){
<List>commentsList = callToService3(userDetails);
person.setComments(returnedObj.getComments(commentsList));
return person;
}
}
and then in my controller I call
person = personHelper.getPerson(userDetails);
jsonResponse = jsonProcessor.writeAsString(person);
return jsonResponse; // returns the ajax response to js
Thanks in advance for any help or suggestions.
EDIT: After more research I found that the object I am populating is referred to as a Data Transfer Object and I am populating it using the Java Bean method.
There's a trend these days to limit the mutability of objects so your setter-based approach, although workable, is sometimes not seen as the best way to create an object, even a data transfer type of object. One other thing to consider is how many objects know about each other and how much they know - it seems your PersonHelper class needs to know pretty much everything about UserDetails and Person. So if you add a field to Person, you need to add it to UserDetails and also add to PersonHelper to get that field populated.
For your type of object, you might find the Builder pattern useful. A builder is a short-term transient object designed to gather data for construction. Often the builder will have a fluent API, and gets passed to the (private) constructor of the transfer class. That means that all your code responsible for building the object is clear that that is its responsibility because it works with a Builder. Meanwhile, the constructed transfer object is effectively immutable and it becomes significantly easier to reason about the thread-safety of your code and to understand what values something might have at different parts.
public class Person {
private final String firstName;
private final String lastName;
private Person(final PersonBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
}
... usual getters etc ...
public static class PersonBuilder {
private String firstName;
private String lastName;
private PersonBuilder() {
}
public PersonBuilder withFirstName(final String name) {
this.firstName = name;
return this;
}
public PersonBuilder withLastName(final String name) {
this.lastName = name;
return this;
}
public Person build() {
return new Person(this);
}
}
public static PersonBuilder newPerson() {
return new PersonBuilder();
}
}
In this example the builder is a little over-wieldy, but when you've got twenty or thirty different pieces of data which are somehow optional it can make sense and makes for very easy to read construction code...
Person.newPerson().withFirstName("Sam").withLastName("Spade").build()
It seems to me that your 'UserDetails' object could be turned into a kind of builder. And so your 'PersonHelper' class would end up just calling userDetails.build() rather than knowing all about what fields the Person object (and userDetails object) contains.
There is no general paradigm for your question, but here are a few tips for your design:
It seems that your person data (names, favourites) is distributed among several data stores and you have to gether it all in your PersonHelper class. I don't know if this services are used anywhere else, but from the controller point of view this helper should be a service too.
Since your service invocations are independent, you can execute them in parallel
For some kind of applications it can be even better if you expose these services for UI level. For example, if data is presented in different UI blocks, client can make several asynchronous requests and display the data as soon as responses are received.
Related
Let us suppose we have the following class:
class Credentials implements ICredentials{
String name;
String surname;
String email;
public void update(ICredentials updatedCredentials){
// do stuff here
}
}
I would like to update the fields of the current class (the strings above) , using an object of the same type, without using getters or setters. Is there a way?
PS: noob here.
You could pass the object that you want to update to a ICredentials method that updates its content : updateParam(Credentials).
Add this method in the interface and Credentials that implements it could use private fields of the parameters as an instance of a class can access to private fields without getters.
class Credentials implements ICredentials{
public void update(ICredentials updatedCredentials){
updatedCredentials.updateParam(this);
}
#Override
public void updateParam(Credentials credentialsToUpdate){
credentialsToUpdate.name= name;
credentialsToUpdate.surname = surname;
credentialsToUpdate.email= email;
}
}
But this is convoluted enough.
The real issue in your actual logic is that you want to pass ICredentials as parameter that is not necessary a Credentials. In these conditions, the interface needs to provide a way to extract the name, surname and email information.
You don't have to consider these methods strictly as getters but as methods required to fulfill the interface contract.
Without it, to extract data from the interface you should do convoluted things or downcasting from the interface to the subclass or still worse...
Assuming that updatedCredentials is the same instance of Credential, one way is that you can directly assign
public void update(ICredentials updatedCredentials){
Credentials cred = (Credentials) updatedCredentials;
this.name = cred.name;
//rest of it
}
Remember you need to declare the variable as public. But this process is very ugly. If you can use getter and setter that could be nice solution and it is the best practice
I was going through below link to figure out differentiation between Composition and Aggregation.
https://www.geeksforgeeks.org/association-composition-aggregation-java/
I am able to understand that Composition implies a relationship where the child cannot exist independent of the parent while Aggregation implies a relationship where the child can exist independently of the parent. But not able to understand how can i differentiate that programmatically . Below is an example of Aggregation and Composition as given in link.In both cases the classes are same in structure except that Student and Department class has an extra variable "name" .As in Composition "child cannot exist independent of the parent ",but here I can create a separate object of Book and use it without adding it to Library.
Aggregation
// student class
class Student
{
String name;
int id ;
String dept;
Student(String name, int id, String dept)
{
this.name = name;
this.id = id;
this.dept = dept;
}
}
/* Department class contains list of student
Objects. It is associated with student
class through its Object(s). */
class Department
{
String name;
private List<Student> students;
Department(String name, List<Student> students)
{
this.name = name;
this.students = students;
}
public List<Student> getStudents()
{
return students;
}
}
Composition
class Book
{
public String title;
public String author;
Book(String title, String author)
{
this.title = title;
this.author = author;
}
}
// Libary class contains
// list of books.
class Library
{
// reference to refer to list of books.
private final List<Book> books;
Library (List<Book> books)
{
this.books = books;
}
public List<Book> getTotalBooksInLibrary()
{
return books;
}
}
As far as I can tell (and maybe somebody else can give a better answer), you can't evaluate if the relationship is aggregation or composition just by looking at Java code. It's the other way around.
First you create a conceptual model of the world. Libraries have books, and cars have wheels. Then you think - does it make sense for a book to exist without a library, or for a wheel to exist without a car, in the context I'm working in. So for example if you are writing a car racing game, you will have no use of wheels outside of cars. But if you are writing some auto-repair application, you will deal with wheels independently of some particular car.
So first you decide if you need aggregation or composition, and then implement it in your code. The implementation could be that object Car has List<Wheel> but you can't tell if it's composition or aggregation just from that. The key is that you interpret the code (implementation) based on your conceptual model and then use it according to that.
If it's composition, the usage it might have some restrictions:
No object other than Car will hold a reference to Wheel.
Wheel might even be a private or package-private class.
If Car is saved in database, when you delete it, you also automatically delete all of its Wheels.
But it's up to you to enforce these restrictions if you decide it's composition.
In the real world, a book can indeed exist in its own right without being owned by a library. But what if, instead, you had a LibraryBook class with fields like dateAcquired and currentBorrower? Using your design, you would still be able to create a LibraryBook instance without a library.
This is where languages like C++ can be more explicit about composition: in C++, an object can hold its parts by value. In Java, every object is handled by a pointer (OK, Java people don't call them pointers; they call them references instead.) This makes it more difficult to differentiate between composition and aggregation. In Java, you do it using careful design.
For example, we can make the LibraryBook class only instantiable through a method of Library:
class Library {
class LibraryBook {
private LibraryBook() {/*private constructor prevents independent instantiation*/}
}
LibraryBook createBook(String title, etc...);
}
Furthermore, if we make LibraryBook's mutator methods only accessible to the Library class, we can ensure that the book remains part of its owning library.
I have a given web service. (This is only an example, the real one is more complex, but it has the same problem.) The service has three methods and all three methods have a person as parameter and need other things from it. (I can't change the entity or methods.)
Entity (Person) (It has only a default constructor):
private String name;
private int age;
private Address address;
private List<String> hobbies;
private List<Person> friends;
Method1 needs name and age.
Method2 needs address name and age.
Method3 needs all.
I need to fill the object from my own objects. I need to write a "converter". What is the best practice for it?
My solutions:
Builder Pattern with builds for three methods.
Set all attributes and send unhandled overhead (bad solution in my eyes).
Creating a builder that sets only required fields sounds good.
You can inherit from this class for each of your needs and implement your own constructors
public class Target {
// fields
}
public class Purpose1 extends Target {
public Purpose1(String name, int age) {
// set fields or do whatever you wish
}
}
public class Purpose2 extends Target {
public Purpose2(String address, String name, int age) {
// set fields or do whatever you wish
}
}
public class Purpose3 extends Target {
public Purpose3(...) {
// set fields or do whatever you wish
}
}
And then you may use instances of subclasses where class Target is required.
I think you can get what you want with a suitable usage of decorator pattern:
https://en.wikipedia.org/wiki/Decorator_pattern
Sorry for the ambiguous title. I'll edit when if someone has a better way to explain this.
Let's say I have a class that I create many instance of and that has many attributes that get filled by different methods. Is it bad practice to pass the object around and fill the attributes in the methods ? I'll try to explain with an example that I tried to make simple:
public class User {
private String surname;
private String name;
public String getSurname() {
return surname;
}
public void setSurname( String surname ) {
this.surname = surname;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}
// Passing the object as parameter and returning the object in each methods
// In this case getNameFromSomewhere returns a User object
public User getUser(){ //edit: my mistake here
User user= new User();
user = getNameFromSomewhere(user);
user = getSurnameFromSomewhere(user);
return user;
}
In my case, getNameFromSomewhere does a search on a server, I was wondering if I should change all my methods so it returns a string just like the attribute and then just do :
// Alternative ?
public User getUser(){ //edit: my mistake here
User user= new User();
user.setName(getNameFromSomewhere()); // getNameFromSomewhere return string
user.setName(getSurnameFromSomewhere());
return user;
}
*note: I have string, int, list attributes to fill.
edit: I wrote an alternative, I'm simply wondering, performance wise, if it's good to pass a User as parameter and then return it filled with 1 attribute for every attribute or if I should just use the User.set method to fill the attribute and have my methods return the attribute type. (is this a bit more clear?)
The problem with your code is that User class exposes its internals through the setter methods, breaking the information hiding principle. Your approach could lead to an unmaintainable code base, i.e. it will be difficult to trace all the components that could modify a User object.
I think a better approach is to have a constructor that takes directly the information needed to build a User.
public class User {
private String surname;
private String name;
public User(String name, String surname) {
this.name = name;
this.surname = surname;
}
public String getSurname() {
return surname;
}
public String getName() {
return name;
}
}
Then, you can build a user in the following way:
public User getUser() {
User user = new User(getNameFromSomewhere(),
getSurnameFromSomewhere());
return user;
}
In this way you're sure where your user came from and that it cannot be modified anywhere else. Moreover, this code is compliant to the single responsibility principle, because the methods getNameFromSomewhere and getSurnameFromSomewhere have the only responsibility to retrieve the name / surname.
The optimal approach should be the one that use an immutable implementation of the User class. That means that every time you need to modify an object, you create a copy from it with the desired information changed. This way the whole testing process becomes simpler.
yes, it is better to have getNameFromSomewhere() return the value instead of having it accept a user Object and call the setter. There are two reasons for that:
You want to decouple the interface that User class exposes. so when you refactor surname into familyname, you dont need to change getNameFromSomewhere()
it is possible that getNameFromSomewhere() will be used to fill attribute of some other bean, besides User.
I have the following BO which is already there in the system
public class userBO
{
private String userId;
private String password;
private String firstName;
private String midName;
private String lastName;
private String userType;
private String userDepartment;
private String userAuthority;
//There are some more fields
//getter and setter
}
Now I want to built a dropdown in which I will display Name (firstName + lastName) and will use userId as value. So for that I will make a list of object.
So my question is should I use the existing userBO class or should I create new class something like below
public class userDropDwonBO
{
private String userId;
private String firstName;
private String lastName;
//getter and setter
}
I want to know the answer from Good Architect point of view and also performance point of view, Will there be any better performance if I user new userDropDownBO
userDropDownBO object will definitely use less memory than the above class.
It is because all your members are private intance variable, everytime a constructor is invoked, a set of all private variables will be created on stack and will be initialized to their default values so will consume more memory and initialization time.
But it solely depend on your requirement:
If other fields are required other than these three fields go for the userBO class.
If other fields are unnecessary but no of objects to be created are small in number, go for userBO.
If other fields are unnecessary but no of objects to be created are very large in number, go for userDropDownBO.
Its a personal opinion and rest is your choice.
If you are going to create a new class beside the existing one named UserBO just for the sake of binding it to the JComboBox, that will definitely be a waste of memory and waste of time as well and also you will need to provide an additional logic to map your original object of type UserBO to the the object of type UserDropDownBO.
I would say that your approach maybe applicable in case the BO itself is so complex in dealing with, so that you need to create a separate model to be used in the drop down box.