How to extend object with no setters to obtain superclass state - java

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.

Related

Using Template Method (Design Pattern) for differentiate fields

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");
}
}

Determine which fields of a POJO are being accessed in a code

I have a huge (parent) POJO which is being used in some component. The POJO has individual fields as well as nested POJOs as well. Is it possible to determine what all fields/ nested fields from this POJO are being accessed in that component?
I was thinking about JUnits/ aspects but not sure if either would work. I've tried looking through SF/ and Google but could not find any relevant thread for this thing.
Say following is a sample POJO:
public class Student {
private String name;
private Date date;
private Subject subject;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Subject getSubject() {
return subject;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
}
It has three fields name, date and subject, not all of which would be in use in my component. So I need to determine which are actually being used.
Edit:
Thanks Sharon for pointing out that the getter/setters were protected. I had just generated the class on the fly for the purpose of question and didn't notice the issue. Corrected now.
How the class is initialised: For the purpose of the component, objects will be created from Json/XML data and would have only getters being called.
As for static vs runtime analysis, I'd prefer to achieve it through static code analysis if that's possible otherwise runtime also is fine with me if that's easier.
As for using Decorator pattern, do we have anything without requiring existing code change? That's why I was thinking if JUnits could do this.
First of all, it is odd to see getter/setter methods that are protected. seems to me they need to be public?
Anyway, I would utilize the Decorator design pattern.
From the linked article:
The decorator design pattern allows us to dynamically add
functionality and behavior to an object without affecting the behavior
of other existing objects in the same class.
So, our decorated Student should inherit from the target class. All methods can log their usage and call super to invoke target operation. You didn't say how Student
is initialized, but anyway, you will want to modify that to create instances of LogUsageStudent
public class LogUsageStudent extends Student {
protected String getName() {
// log usage of getName()
return super.getName();
}
// etc
}

How to expose an enum to public API without the implementation?

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

How to produce immutable DTOs without explicitly using a constructor?

Suppose I have a DTO class:
public class SomeImmutableDto {
private final String someField;
private final String someOtherField;
public SomeImmutableDto(String someField, String someOtherField) {
// field setting here
}
// getters here
}
This is a nice immutable DTO. But what if I have 20 fields? It leads to the proliferation of a lot of unreadable constructors and unmaintainable code.
There is a solution for this problem however, the Builder pattern:
public class SomeImmutableDto {
private final String someField;
private final String someOtherField;
private SomeImmutableDto(Builder builder) {
// field setting here
}
public static class Builder {
private String someField;
private String someOtherField;
// setters here
public SomeImmutableDto build() {
// building code here
}
}
// getters here
}
Now I can do something like this:
SomeImmutableDto dto = new SomeImmutableDto.Builder()
.setSomeField(/* ... */)
*setSomeOtherField(/* ... */)
.build();
Now I have an immutable dto which does not have an abundance of ugly constructors.
My problem is that I need a dto which has public setters AND immutable because there are some legacy code in the project which cannot be refactored at the moment and it requires the presence of public setters in order to initialize dto objects.
Is there some pattern which is usable here or this won't work? I'm thinking about the Proxy pattern but I'm not sure it can be applied in a way it is not looking like an ugly hack.
I think if you need to be legacy-code-compliant, the best way is to use a non modifiable wrapper just like in Collections.unmodifiableList method it is done.
It is "hack", but I think it is forced by legacy code and it is "not so bad" :)

Can I use jackson mixIns to modify "getters" behavior?

I'm in the need of do some clean up of some invisible characters (\r\n) and html tags for specific getters on my entities.
I've been trying to use mixIns to modify what's returned from the entity but I'm not sure how can I reference the target class in my MixIn so I can add the clean up logic there. From the my tests seems that not even my method is called.
This is what I have so far, but it never gets called
public abstract class BookMixIn {
#JsonProperty
public String getTitle() {
return StringUtils.deleteWhitespace(getTitle());
}
}
public class Book {
private String title;
// getter/setters omitted...
}
And the ObjectMapper config:
mapper.getSerializationConfig().addMixInAnnotations(com.company.Book.class,
com.company.BookMixIn.class);
mapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
String tmp = mapper.writeValueAsString(book);
log.info(tmp);
Can this be accomplished via MixIns?
Thanks
Jackson mix-ins are purely for associating annotations; they are not used for adding behavior (code).
So they would not help you here.
But the simple way that would work (possibly using mix-in too) is to add annotation for using custom serializer, which can use whatever filtering is needed:
#JsonSerialize(using=MyCoolSerializer.class) public String getTitle() { }
so either add that to POJO, if possible; but if not, associate it using mix-in.
If you are running Jackson 1.9, this works:
BookCleaner cleanBook = new BookCleaner(book);
mapper.getSerializationConfig().addMixInAnnotations(Book.class, BookMixIn.class);
mapper.writeValueAsString(cleanBook);
#JsonSerialize
class BookCleaner {
private Book book;
public BookCleaner(final Book book) { this.book = book; }
#JsonUnwrapped
public Book getBook() { return book; }
#JsonProperty("title")
public String getCleanTitle() { return cleanup(getBook().getTitle()); }
}
public interface BookMixIn {
#JsonIgnore public String getTitle();
}
I don't think it works like this; the class or interface is just used as a signature.
You could use AspectJ to modify the return value, but it might be easier to just create a decorator and serialize that instead of the underlying object.
Alternatively, you could create specific getters for the "safe" versions of things and use the #JsonProperty annotation to give it the name you need, and use #JsonIgnore on the "non-safe" getters.

Categories