I have been using a Create Request as shown below and needed to implement an Update Request with some fields non-required.
#Data
public class CreateRequest extends BaseRequest {
#NotEmpty
private String token;
#NotEmpty
private String secret;
}
#Data
public class UpdateRequest extends BaseRequest {
private String token;
private String secret;
}
There are some relations and interfaces that should be used by both request. I think of using Template Design pattern by keeping the shared fields of these requests. Is that suitable for this scenario? Or, what would you suggest?
This may have been what you were getting at in your thoughts on the best approach, but I think your best bet is to have whatever fields/behavior are required for both request types in a shared parent class, and have their individual needs/different fields in a child class.
I am not sure exactly how your optional fields are meant to work conceptually, but if they are optional because of "default" values, then you can have the class with optional fields extend from the one with mandatory fields, and just implement a constructor which calls a super constructor with the default values. For instance if subClass extends parentClass and the constructor of the parent class is two strings, the second of which has a "default" in the child class, something like the following could be done:
public subClass extends parentClass {
subClass(String arg1) {
super(arg1, "default arg2");
}
}
Related
I've got a Kotlin class, similar to
data open class MyDto (
var property: String? = null
// ...
)
and a Java class extending this class, similar to
class MySpecificDto extends MyDto {
private String field;
// getter/setter for "field"
public MySpecificDto(final MyDto prototype)
{
super(prototype);
}
}
What is missing in Kotlin's DTO for the "super(prototype)" statement to compile?
MyDto's constructor takes a single parameter of type String, and you are trying to pass it a MyDto.
I think you are looking for --
super(prototype.getProperty());
Data classes seem a like logical base for a hierarchy of DTOs. Unfortunately, they do not play well with inheritance, so doing so is not a good idea. See this answer.
Update to address comment --
For a Kotlin side solution, you need to remember Kotlin classes only allow for a single constructor. For data classes, the format of that constructor is already defined, so you cannot just pass an object and have it work, or define a different constructor. Also, as noted by #bashor in comment to your original question, there is no copy constructor. You can, however, create a separate function to initialize your object if you want --
data open class MyDto (var property: String? = null //...) {
fun init(dto: MyDto) {
property = dto.property
//... rest of the properties
}
}
and the in your Java constructor call init instead of super.
public class MySpecificDto extends MyDto {
private String field;
public MySpecificDto(final MyDto prototype)
{
init(prototype);
}
}
The caveat on this solution is that your data class must provide default values for all of its properties because there is an implicit call to the constructor with zero parameters.
The main objective is to avoid duplication of fields with best inheritance model on existing stuff:
I have following class hierarchy:
class A
{
private String fieldA1;
private String fieldA2
// getters and setters
}
Class B extends A
{
private String fieldB1;
private String fieldB2;
// getters and setters
}
A 'User' class will either extend A or B having its own fields.
Assume existing API's uses above data models.
Now there is a requirement to add new fields in Class A for new set of API's.
I have certain restriction not to modify existing data models since it exposes or breaks existing API's with these new fields . So new data models need to be created by extending existing ones such that new API's uses them with all existing fields + new fields. I have below solution which may not be the best approach as it adds duplication of fields.
class A
{
private String fieldA1;
private String fieldA2
// getters and setters
}
Class B extends A implements Common
{
private String fieldB1;
private String fieldB2;
// getters and setters
}
Class NewA extends A
{
private String fieldNewA;
// getters and setters
}
Class NewB extends NewA implements Common
{
private String fieldB1;
private String fieldB2;
private String fieldNewB;
// getters and setters
}
Interface Common
{
//marker interface
}
Please suggest if there is any better approach.
Thanks...
I think you need to take a step back and look at what is it that is causing you to keep adding new fields to your existing classes. Maybe you should just have one field which is a collection of property and values. This way any new field will just be another property/value in your collection. You won't have to then worry about adding new fields frequently.
Your example is not great, for example sub-classes cannot access private fields and it is not clear what you intend your subclasses to achieve.
If you wish to inherit state, your example should use either protected or public fields, or show getter and setter methods being inherited. When inheriting state, implementing an interface like Common is redundant. More detail may help clarify your intent.
That aside, yes you can extend your data models as you describe in order to add data types to an existing class. An example of wanting to do this might be wishing to create a Square class from a Triangle class, requiring adding a new point. And also requiring changing behaviour to make use of the new field.
I am extending a class to store some extra fields that I need to my application, but the class I am extending has no setter methods, and just a default constructor.
http://restfb.com/javadoc/com/restfb/types/Post.html#Post()
I am using a framework that requires the getters to be in a correct naming format as the fields in the type. However, as I cannot set the fields from the constructor, or from setters, I have kept a local copy of the initial object that I wish to store in my new object.
I then have overridden the methods to pull the data from the initial object as follows:
#Override
public String getMessage() {
return initialPost.getMessage();
}
This does not seem like a good way to do things, one annoying reason being that I would have to override every method if I wish to use all fields.
What is the best way to solve this issue? Would this be a use case for composition over inheritance?
I think I may have tried to combine both here, which seems incorrect!
public class MyPost extends Post{
private String postId;
private Post initialPost;
private PostType type;
private Brand brand;
private Product product;
private List<Photo.Image> postImages;
Thanks for all advice.
You indeed combined both composition and inheritance; which is a pretty confusing situation. I would go with inheritance since you are extending the behaviour of an object with a more specific purpose to just that object.
This also solves your problem because a public method from the Post class is also available as a public method from its subclasses (and as such, the framework can happily use getMessage() without you having to redefine it).
From my comment below:
Post is essentially an immutable object so it is not intended to be constructed by you. You could override the methods from Post in MyPost and add your own getters/setters, but you should reflect whether or not this is an approach you want to take.
An example of how you would implement this:
class Post {
private String body;
public String getBody() {
return body;
}
}
class MyPost extends Post {
private String body;
public void setBody(String body) {
this.body = body;
}
#Override
public String getBody() {
return body;
}
}
Now the getBody() method from the Post class is overridden by the selfdefined one from MyPost.
I have a class which has a property whose type is an Enum. Example:
enum CarType {
TOYOTA("Japan"),
AUDI("Germany"),
BMW("Germany");
public final String country;
private CarType(String country) { this.country = country; }
}
class Car {
private CarType type;
public CarType getType() { return type; }
}
The class Car is part of a library, and I would like to expose its functionality, so I create an interface which will be part of the public API, and have the class Car implement it:
interface ICar {
CarType getType();
}
class Car implements ICar {
private CarType type;
#Override public CarType getType() { return type; }
}
The problem with this approach is that this would require the whole CarType enum to be published. The CarType enum might contain additional attributes and methods which I do not want to expose / publish (country in this example).
What can I do if I want to hide the implementation of CarType but I still want to expose the possible values (the declared enum values) in a way so that the API users can reference them in switch and if statements like this:
ICar car = ...; // Get an instance somehow.
if (car.getType() == CarType.TOYOTA) System.out.println("It's Toyota.");
Making the additional attributes and methods protected or private is not a good solution because then other parts of the library would also not be able to reference to them.
Are there any good alternatives to this problem if I want to keep using Enums?
Although a late one wanted to add my thoughts -
enums can also implement an interface where you can expose only the require details:
public enum CarType implements ICarType {
...
public String getTypeName(){
return name();
}
}
public interface ICarType {
public String getTypeName();
}
So that you plan to use it in if()/switch
ICarType carType; //Not referencing the enum
if("TOYOTA".equalsIgnoreCase(carType.getTypeName())){
print("Toyota....");
}
You can provide Enum for public API, and convert it to another Enum for private usage.
E.g. use a Map, where key is public Enum instance and value - private Enum instance.
The problem is that you have to convert data each time the API is called. May require change in many places.
protected, private and package-private are the main tools you are provided with for this. If you think about your class hierarchy enough you can probably do something using them.
You should consider composition. Have a TypeDetails class, and have each member of the CarType contain a TypeDetails member. You can then restrict access to the TypeDetails getter to only those people who are supposed to access it while having the TypeDetails itself visible to all the parts of your library.
If it is strictly necessary to hide the country attribute to user code, you can go for standard visibility (attributes declared without public, protected or private qualifier, those attributes would only be visible for classes in the same package). I hope this to be useful, but I am aware that is only a patch.
Anyway I cannot fully understand your design and necessities, so probably you have no other option, but maybe what you need is a redesign with encapsulation in mind if you want to protect your code from API misuse
//Interface DAO
public abstract class BaseDAO<T extends BaseDTO> {
public void update(T t) throws DBException {
Field[] fieldsToInsert = t.getClass().getDeclaredFields();
//code to update database object academic or event
}
public Integer create(T t) throws DBException {
Field[] fieldsToInsert = t.getClass().getDeclaredFields();
//code to create academic or event in database
}
}
//Concrete DAOs
public class AcademicDAO extends BaseDAO<AcademicDTO> {
//provide implementation
}
public class EventDAO extends BaseDAO<EventDTO> {
//provide implementation
}
//Transfer object
public class AcademicDTO extends BaseDTO {
String title;
String surname;
//getters and setters
}
public class BaseDTO {
protected Integer ID;
public Integer getID() {
return ID;
}
public void setID(Integer ID) {
this.ID = ID;
}
}
Hello Guys, I have a sample code on me that follows the above structure to create a small java application to manage academics and events. It is leniently following this pattern
1- You experts are familiar with this pattern more than me. I would like to understand why generics are used in this case so DAOs can extend and implement a generic base class. It would be great if one can show how generics here may be advantageous using an example.
2 - I have also witnessed the use of java Fields. Is there a link between generics and Fields?
I would like to document DAO pattern in an academic report, but I am finding difficult to understand how Generics and Reflect Field play a part here. Do they support flexibility and loose coupling?
The code you've provided is reusable set of logic to load and persist entities. Many times, in an application of non-trivial size, you'll wind up persisting many different types of objects. In this example, you can define as many objects as necessary, but only define the logic to actually save and load once. By asking the DTO what Field objects are there, it can get at the data to help construct queries for loading and saving.
Generics allow you to use this pattern while maintaining type safety. AcademicDAO can only handle AcadmeicDTO. You can't use AcademicDAO to store EventDTO. Generics allow the instance of the class to rely on a more specific type when dealing with the Field objects. If you didn't have generics, the BaseDAO would take Object, and you wouldn't be able to access any methods except those that Object provides because the JVM wouldn't know what class is provided, so it has to limit it's knowledge to that of Object. Using getClass().getDeclaredFields() bypasses that limitation because getClass() returns the actual class of the Object parameter.
Field is just a way to use reflection to access the values of the properties in each DTO. If you had to access the fields directly, with getTitle(), you couldn't reuse a generic base class to do your persistence. What would happen when you needed to access EventDTO? You would have to provide logic for that. Field allows you to skip that logic.
Edit:
To explain what I mean by accessing getID, you could do the following within BaseDAO because T is known to be a BaseDTO with a getID() method defined:
public abstract class BaseDAO<T extends BaseDTO> {
public boolean update(T t) throws DBException {
Integer id = t.getID();
Field[] fields = t.getClass().getDeclaredFields();
// Assuming you have a db object to execute queries using bind variables:
boolean success = db.execute("UPDATE table SET ... WHERE id = ?", id.intValue());
return success;
}
}
If you had this instead (in a non-generic class):
public boolean update(Object o) throws DBException {
// This line doesn't work, since Object doesn't have a getID() method.
Integer id = t.getID();
Field[] fields = o.getClass().getDeclaredFields();
boolean success = db.execute("UPDATE table SET ... WHERE id = ?", id.intValue());
return success;
}
You'd have to look through those Field objects, or ask for the ID field and assume it existed.
For question 1. The use of generics allows the same implementations of update and create to be used regardless of the type of the DTO. Consider if you didn't use generics. Then the best you could do for the parameter type of update would be BaseDTO, but then you could call
academicDAO.update( eventDTO )
which doesn't make sense. With the code as you have it, this would be a type error. So the main advantage is: better type checking.
For question 2. The use of Fields allows a single implementation of update and create to work on DTO object of various concrete types.