Dynamically create form for super and subclasses - java

Suppose that we have classes:
public class BasicCustomer {
private String name;
private String email;
----getters and setters omited----
}
public class CustomerWithDog extends BasicCustomer{
private String dogName;
private String dogRace;
----getters and setters omited----
}
public class CustomerWithCat extends BasicCustomer{
private String catName;
private String catRace;
----getters and setters omited----
}
Only when customer is logged in, I can deduce which type he is.
Question:
is there a way to dynamically create form with appropriate fields for specific type of customer (CustomerWithCat should see form that have inputs for name, email, catName and catRace)?
If I use java.lang.reflect.Field class to get fields from class, then I should use Field.setAccessible(true) (because fields are private) which, on the other hand violate encapsulation (and gets around getters and setters, which is not what I want).
I look at:
How to create dynamic JSF form fields
solution no.1, but I don't understand how to populate value attributes because if user is BasicCustomer then it can't reference fields from CustomerWithCat even if they are not rendered.

Related

Update a current object given an object of the same type

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

In Java is it correct to allow subclass to alter superclass private fields via public setter method?

Please look at the code below
Class Employee{
private String name;
private String id;
public String getName(){ return name; }
public void setName(String name){ this.name = name; }
public String getId(){ return id; }
public void setId(String id){ this.id = id; }
}
Class Teacher extends Employee{
private double salary;
}
Now my question is If I am creating an object of Teacher , then it does not make sense without the Teacher object having a name and id. I can set the same for teacher object via public setters of Employee but it it correct ?
Teacher t1 = new Teacher();
t1.setName("aaa");
t1.setId("224");
t1.salary = 200.00;
System.out.println(t1.toString());
I am asking this question as my understanding is if the field is private it should be used only via getters . But in the example provided above Teacher object will not make sense without having a Name or Id .
If it is correct then why not make the field public in the first place? What is the advantage in using it private and then allowing access via public setter ?
If it is not correct please provide an example of how the above Employee and Teacher class should be implemented ?
Your question seem to show a confusion between two concepts rather independant:
encapsulation
creation of objects
Encapsulation: it is better design to define private variables. Then you can not corrupt the object from outside. You must use setter to modify your employee.
But, if you trust Teacher, it could modify Employee as a subclass, without setter, it is faster to code (but little risky: if you have to change the setter in employee, Teacher wont get it, ...).
Creation of objects: you should pass certain values to the variables, or they are defined by default (or auto-built ...)
=> you can decide that Teacher have well defined values (default), or that you must give these values (mandatory). It is your design.
After that, you can change them directly or by setters of Employee (=> first concept of encapsulation).
then it does not make sense without the Teacher object having a name and id. I can set the same for teacher object via public setters of Employee but it it correct ?
This is where exactly constructor comes into picture. You need to pass them before you are using it.
Thumbrule : When you want something while building it, you need to force them to pass on constructor.

Different methods need different attributes in one object

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

Should I create new class or use the existing one

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.

Setting different object with same attributes

This is not the first time that I've found myself in a situation in which I have to adapt two objects with almost the same data, for example:
User.java (Object returned from another library)
private String name;
private String surname;
private String email;
private String telephone;
...
getters and setters();
constructor();
MyUser.java
private String name;
private String surname;
private String email;
private String telephone;
...
getters and setters();
constructor();
I usually create a method to convert one object into another one, like this:
User m1 = new User();
MyUser m2 = new MyUser();
m2.setName(m1.getName());
m2.setsurmame(m1.getsurname());
...and so on...
Does anybody know a different way to do this kind of stuff?
Use Object Composition For objects that you create using the other library, create an instance of ExternalUser. But if you want to create them locally, create a BrandNewUser. Then you can just treat them the same way, with one version using the pass-through composition methods, and the ones created by your code using your own internal implementation.
You can create your object like this:
public interface MyUser {
// all the methods you need
String getSurname();
}
public class ExternalUser implements MyUser {
private User _user;
private ExternalUser() { }
public ExternalUser(User u) {
this._user = u;
}
public String getSurname() {
return _user.getSurname();
}
}
public class BrandNewUser implements MyUser {
private String _surname;
public ExternalUser(String name, String surname) {
this._surname = surname;
}
public String getSurname() {
return _surname;
}
}
There is a AutoMapper project in C Sharp.
In the gist of it it provides an easy way of mapping properties from a source instance to a destination instance where the source and destination instances can be of different classes.
this link shares some interesting thoughts about similar projects in Java : Automapper for Java
One thing you can do is pass that User object in a method of MyUser class or constructor of MyUser class and then perform those setters.
Using constructor :
public MyUser(User u){
setName(u.getName());
setSurname(u.getSurname());
...
}
Or creating a seperate method :
public void setMyUser(User u){
setName(u.getName());
setSurname(u.getSurname());
...
}
Then you can use it like this:
User u = new User();
//hope all values are set in User u object
MyUser m = new MyUser(u);
In cases where appropriate, refactor those objects to inherit from each other, rather than duplicate properties and logic.
In cases where the objects must remain distint, you can use any one of a variety of clone tools to perform deep copies from object to object. Here is a decent, non-exhaustive list:
Orika
Dozer
PropertyUtils
Maybe you can use beanutils which provides copy properties function.
http://commons.apache.org/beanutils/

Categories

Resources