Calling Methods in Java Constructor For Boolean Value - java

I'm currently doing dev on an inherited Spring boot app, part of it is sending an API POST request with the boolean of whether a soccer match is finished or not (resulted). I noticed that the design of the class was such:
//parent class
public class Fixture {
private final FixtureType type;
private final Team homeTeam;
private final Team awayTeam;
public Fixture(#JsonProperty("type") final FixtureType type,
#JsonProperty("homeTeam") final Team homeTeam,
#JsonProperty("awayTeam") final Team awayTeam
) {
this.type = type;
this.homeTeam = homeTeam;
this.awayTeam = awayTeam;
}
public boolean isResulted() {
return false;
}
/*
other methods
*/
}
//child class
public class Result extends Fixture {
private final Outcome outcome;
public Result(#JsonProperty("type") final FixtureType type,
#JsonProperty("homeTeam") final Team homeTeam,
#JsonProperty("awayTeam") final Team awayTeam,
#JsonProperty("outcome") final Outcome outcome) {
super(type, homeTeam, awayTeam);
this.outcome = outcome;
}
#Override
public boolean isResulted() {
return true;
}
/*
other methods
*/
}
In the Swagger documentation, the request specifies that "resulted": true needs to be a field in the JSON POST request. Now I can add that field into the constructor, but that would mean changing a load of tests and code that calls this constructor. My solution was to call the isResulted() method in the constructor itself. I've never done this before, but this works. Is there any reason that this design below would create issues in the long run?
public class Result extends Fixture {
private final boolean resulted;
public Result (){
super();
resulted = isResulted();
}
#Override
#JsonProperty("resulted")
public boolean isResulted() {
return true;
}
}

I don't understand what's the purpose of having a private field that is not used anywhere. I'm also not sure I understand the problem you'd like to have solved.
There's a possible approach that is both more flexible and compatible with your previous code:
public class Result extends Fixture {
private final boolean resulted;
public Result (boolean resulted){
super();
this.resulted = resulted;
}
public Result (){
this(true); // sets the default value
}
#Override
#JsonProperty("resulted")
public boolean isResulted() {
return resulted;
}
}

Related

Question on diamond operator for design pattern strategy

Small question regarding the diamond operator and design pattern strategy for Java, please.
I would like to implement a very specific requirement:
there are some objects to store (in my example called MyThingToStore)
and the requirement is to store them with different kinds of data structures, for comparison.
Therefore, I went to try with a strategy pattern, where each of the strategies is a different way to store, I think this pattern is quite lovely.
The code is as follows:
public class MyThingToStore {
private final String name;
public MyThingToStore(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyThingToStore that = (MyThingToStore) o;
return Objects.equals(name, that.name);
}
#Override
public int hashCode() {
return Objects.hash(name);
}
#Override
public String toString() {
return "MyThingToStore{" +
"name='" + name + '\'' +
'}';
}
}
public class MyStorage {
private final StorageStrategy storageStrategy;
public MyStorage(StorageStrategy storageStrategy) {
this.storageStrategy = storageStrategy;
}
public void addToStore(MyThingToStore myThingToStore) {
storageStrategy.addToStore(myThingToStore);
}
public int getSize() {
return storageStrategy.getSize();
}
}
public interface StorageStrategy {
void addToStore(MyThingToStore myThingToStore);
int getSize();
}
public class StorageUsingArrayListStrategy implements StorageStrategy {
private final List<MyThingToStore> storeUsingArrayList = new ArrayList<>();
#Override
public void addToStore(MyThingToStore myThingToStore) {
storeUsingArrayList.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingArrayList.size();
}
}
public class StorageUsingHashSetStrategy implements StorageStrategy{
private final Set<MyThingToStore> storeUsingHashSet = new HashSet<>();
#Override
public void addToStore(MyThingToStore myThingToStore) {
storeUsingHashSet.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingHashSet.size();
}
}
public class Main {
public static void main(String[] args) {
final StorageStrategy storageStrategy = new StorageUsingArrayListStrategy();
final MyStorage myStorage = new MyStorage(storageStrategy);
myStorage.addToStore(new MyThingToStore("firstItem"));
myStorage.addToStore(new MyThingToStore("duplicatedSecondItem"));
myStorage.addToStore(new MyThingToStore("duplicatedSecondItem"));
System.out.println(myStorage.getSize()); //changing strategy will return a different size, working!
}
}
And this is working fine, very happy, especially tackled the requirement "easy to change the data structure to do the actual store".
(By the way, side question, if there is an even better way to do this, please let me know!)
Now, looking online at different implementations of strategy patterns, I see this diamond operator which I am having a hard time understanding:
MyThingToStore stays the same.
public class MyStorage {
private final StorageStrategy<MyThingToStore> storageStrategy; //note the diamond here
public MyStorage(StorageStrategy<MyThingToStore> storageStrategy) {
this.storageStrategy = storageStrategy;
}
public void addToStore(MyThingToStore myThingToStore) {
storageStrategy.addToStore(myThingToStore);
}
public int getSize() {
return storageStrategy.getSize();
}
#Override
public String toString() {
return "MyStorage{" +
"storageStrategy=" + storageStrategy +
'}';
}
}
public interface StorageStrategy<MyThingToStore> {
//note the diamond, and it will be colored differently in IDEs
void addToStore(MyThingToStore myThingToStore);
int getSize();
}
public class StorageUsingArrayListStrategy implements StorageStrategy<MyThingToStore> {
private final List<MyThingToStore> storeUsingArrayList = new ArrayList<>();
#Override
public void addToStore(MyThingToStore myThingToStore) {
storeUsingArrayList.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingArrayList.size();
}
}
public class StorageUsingHashSetStrategy implements StorageStrategy<MyThingToStore> {
private final Set<MyThingToStore> storeUsingHashSet = new HashSet<>();
#Override
public void addToStore(MyThingToStore myThingToStore) {
storeUsingHashSet.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingHashSet.size();
}
}
public class Main {
public static void main(String[] args) {
final StorageStrategy<MyThingToStore> storageStrategy = new StorageUsingArrayListStrategy();
final MyStorage myStorage = new MyStorage(storageStrategy);
myStorage.addToStore(new MyThingToStore("firstItem"));
myStorage.addToStore(new MyThingToStore("duplicatedSecondItem"));
myStorage.addToStore(new MyThingToStore("duplicatedSecondItem"));
System.out.println(myStorage.getSize()); //changing strategy will return a different size, working!
}
}
And both versions will yield the same good result, also be able to answer requirements.
My question is: what are the differences between the version without a diamond operator, and the version with the diamond operator, please?
Which of the two ways are "better" and why?
While this question might appear to be "too vague", I believe there is a reason for a better choice.
I think the confusion comes from how you named type parameter for StorageStrategy in your 2nd example.
Let's name it T for type instead. T in this case is just a placeholder to express what type of objects your StorageStrategy can work with.
public interface StorageStrategy<T> {
void addToStore(T myThingToStore);
int getSize();
}
E.g.
StorageStrategy<MyThingToStore> strategy1 = // Initialization
StorageStrategy<String> strategy2 = // Initialization
strategy1.addToStore(new MyThingToStore("Apple"));
// This works fine, because strategy2 accepts "String" instead of "MyThingToStore"
strategy2.addToStore("Apple");
// Last line doesn't work, because strategy1 can only handle objects of type "MyThingToStore"
strategy1.addToStore("Apple");
To make it work properly, you need to change your different StorageStrategy implementations to also include the type parameter.
public class StorageUsingHashSetStrategy<T> implements StorageStrategy<T> {
private final Set<T> storeUsingHashSet = new HashSet<>();
#Override
public void addToStore(T myThingToStore) {
storeUsingHashSet.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingHashSet.size();
}
}
And lastly you also want to have a type paremeter for MyStorage
public class MyStorage<T> {
private final StorageStrategy<T> storageStrategy;
public MyStorage(StorageStrategy<T> storageStrategy) {
this.storageStrategy = storageStrategy;
}
public void addToStore(T myThingToStore) {
storageStrategy.addToStore(myThingToStore);
}
public int getSize() {
return storageStrategy.getSize();
}
}
Now you can create a MyStorage and can use it to store essentially any object into it and not just MyThingToStore. Whether that is something you want or not is up to you.
In the second code sample in the declaration of the interface StorageStrategy<MyThingToStore>, MyThingToStore is a Type Variable.
I.e. it's not the actual type, only a placeholder for a type, like T. The common convention is to use single-letter generic type variables (T, U, R, etc.), otherwise it might look confusing like in this case.
Note that in the class declarations, like:
public class StorageUsingArrayListStrategy
implements StorageStrategy<MyThingToStore>
MyThingToStore is no longer a type variable, but the name of the class MyThingToStore because in this case parameterized interface is implemented by a non-parameterized class (i.e. the actual type known to the compile is expected to be provided).

How to initialize a value when creating an object in a static block

When creating the Racing class in ApplicationTest, I want to hand over the FixNumberBehavior class to the argument.
As shown below, to pass the argument to initialize FixNumberBehavior, but cannot pass the class field value to the static block.
The error message is as follows.
Variable 'isMove' might not have been initialized
FixNumberBehavior.java
public class FixNumberBehavior implements CarMoveBehavior {
private final boolean isMove;
private static FixNumberBehavior fixNumberBehavior;
static {
fixNumberBehavior = new FixNumberBehavior(); //error
}
public FixNumberBehavior(final boolean isMove) {
this.isMove = isMove;
}
#Override
public boolean moveBehavior() {
return isMove;
}
}
Racing.java
public class Racing {
private List<Car> cars;
private CarMoveBehavior carMoveBehavior;
public Racing(List<Car> cars, final CarMoveBehavior carMoveBehavior) {
this.cars = cars;
this.carMoveBehavior = carMoveBehavior;
}
public List<Car> getCars() {
return cars;
}
public void drive() {
cars.stream()
.forEach(car -> racingCondition(car));
}
private void racingCondition(Car car) {
if (carMoveBehavior.moveBehavior()) {
car.moveForward();
}
}
}
ApplicationTest
#ParameterizedTest
#CsvSource({"a,aa,aaa"})
void fixRandomNumberTest(String one, String two, String three) {
final List<Car> cars = Arrays.asList(new Car(one), new Car(two), new Car(three));
Racing racing = new Racing(cars, new FixNumberBehavior(true));
racing.drive();
racing.drive();
assertAll(
() -> assertThat(cars.get(0).getStep()).isEqualTo(2),
() -> assertThat(cars.get(1).getStep()).isEqualTo(2),
() -> assertThat(cars.get(2).getStep()).isEqualTo(2)
);
}
How can I initialize an object in the static block?
The problem is FixNumberBehavior has a final field that must be set in the constructor, or in an assignment on the field definition line.
While there is a constructor that takes a value for that field, the static block is not using that constructor, but instead a no-arg constructor.
Pass the value for that final field (isMove) in the new statement.
I am not sure why you want to overcomplicate things by
providing no-argument constructor when you already have constructor in which you let client decide if created instance of FixNumberBehavior will set isMove to true or false.
changing (in your answer) isMove from being final to being static. Those two keywords have different purpose:
final prevents reassigning new value to it
static makes this field a class field, not instance field, so even if you create two instances of FixNumberBehavior there will be only one isMove variable which they both will use (so you can't preserve in one instance state like isMove=true and in other state isMove=false).
What you are looking for is probably simply
public class FixNumberBehavior implements CarMoveBehavior {
private final boolean isMove;
private static FixNumberBehavior fixNumberBehavior = new FixNumberBehavior(true);
//set value you want here ^^^^
public FixNumberBehavior(final boolean isMove) {
this.isMove = isMove;
}
#Override
public boolean moveBehavior() {
return isMove;
}
}
I solved it by attaching static to the field.
Objects created in the static block are not identified when compiling. Therefore, the argument value to be transferred to the object you create in the static block must also be processed statistically.
package racingcar.model.domain;
public class FixNumberBehavior implements CarMoveBehavior {
private static boolean isMove;
private static FixNumberBehavior fixNumberBehavior;
static {
fixNumberBehavior = new FixNumberBehavior(isMove);
}
private FixNumberBehavior() {
}
public static FixNumberBehavior getInstance(){
return fixNumberBehavior;
}
public FixNumberBehavior(final boolean isMove) {
this.isMove = isMove;
}
#Override
public boolean moveBehavior() {
return isMove;
}
}

Accessing child variables from super workaround

I have the following classes.
public abstract class Thing {
private String appearance;
public void setAppearance(String appearance) {
this.appearance = appearance;
}
}
public abstract class MovableThing extends Thing {
// ASCII representation of MovableThing moving right.
private static String FACE_RIGHT;
// ASCII representation of MovableThing moving left.
private static String FACE_LEFT;
private boolean goingRight;
public MovableThing() {
setAppearance(FACE_RIGHT);
goingRight = true;
// Some other things
public void turnAround() {
goingRight = !goingRight;
if (goingRight) {
setAppearance(FACE_RIGHT);
} else {
setAppearance(FACE_LEFT);
}
}
public class Bird extends MovableThing() {
private static String FACE_RIGHT = "/'/>";
private static String FACE_LEFT = "<\\'\\";
public Bird() {
super();
// Some other things
}
}
I know that this is currently incorrect because in MovableThing, FACE_RIGHT doesn't get assigned anything so when I call super() in Bird, the appearance just gets set to null. How can I work around this? I have multiple animals with different left/right ASCII representations but I'm not sure how to do all of this in an OOP kind of way.
Edit: Meant to say Bird() instead of Chicken().
Here is what I would do with your code to model your scenario:
public abstract class Thing {
private String appearance;
// Require subclasses of Thing to have a defined "going left" and "going right"
// method.
public abstract void setGoingLeft();
public abstract void setGoingRight();
protected final void setAppearance(String appearance) {
this.appearance = appearance;
}
}
public abstract class MovableThing extends Thing {
private boolean goingRight;
public MovableThing() {
setGoingRight();
// Some other things
}
// Require subclasses to define a method that gives me a String showing which
// way they're facing, when I tell them what way they're facing. This allows
// subclasses (like Bird) to each return their own appearances depending on the
// way they are facing.
protected abstract String getAppearance(boolean right);
// Override the "going left" and "going right" methods (and make them final so
// subclasses can't change them). These also modify the "goingRight" field of a
// MovableThing correctly.
#Override
public final void setGoingLeft() {
goingRight = false;
getAppearance(false);
}
#Override
public final void setGoingRight() {
goingRight = true;
getAppearance(true);
}
public void turnAround() {
// If they're going right, turning them around will make them go left and vice
// versa.
if (goingRight)
setGoingLeft();
else
setGoingRight();
}
}
public class Bird extends MovableThing {
private static final String FACE_RIGHT = "/'/>";
private static final String FACE_LEFT = "<\\'\\";
// This method is called by the super class.
#Override
protected String getAppearance(boolean right) {
// If the super class asks for a Bird's appearance when facing right, return
// "FACE_RIGHT". Otherwise, return "FACE_LEFT". (Other animals can return
// different things depending on the way they're facing.)
return right ? FACE_RIGHT : FACE_LEFT;
}
}

How to consume Page<Entity> response using Spring RestTemplate

I'm using spring data (mongoDb) and I've got my repository:
public interface StoriesRepository extends PagingAndSortingRepository<Story, String> {}
Then i have a controller:
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Page<StoryResponse>> getStories(Pageable pageable) {
Page<StoryResponse> stories = storiesRepository.findAll(pageable).map(StoryResponseMapper::toStoryResponse);
return ResponseEntity.ok(stories);
}
Everything works fine, but I can't consume my endpoint using RestTemplate getForEntity method:
def entity = restTemplate.getForEntity(getLocalhost("/story"), new TypeReference<Page<StoryResponse>>(){}.class)
What class should I provide to successfully deserialize my Page of entities?
new TypeReference<Page<StoryResponse>>() {}
The problem with this statement is that Jackson cannot instantiate an abstract type. You should give Jackson the information on how to instantiate Page with a concrete type. But its concrete type, PageImpl, has no default constructor or any #JsonCreators for that matter, so you can not use the following code either:
new TypeReference<PageImpl<StoryResponse>>() {}
Since you can't add the required information to the Page class, It's better to create a custom implementation for Page interface which has a default no-arg constructor, as in this answer. Then use that custom implementation in type reference, like following:
new TypeReference<CustomPageImpl<StoryResponse>>() {}
Here are the custom implementation, copied from linked question:
public class CustomPageImpl<T> extends PageImpl<T> {
private static final long serialVersionUID = 1L;
private int number;
private int size;
private int totalPages;
private int numberOfElements;
private long totalElements;
private boolean previousPage;
private boolean firstPage;
private boolean nextPage;
private boolean lastPage;
private List<T> content;
private Sort sort;
public CustomPageImpl() {
super(new ArrayList<>());
}
#Override
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
#Override
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
#Override
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
#Override
public int getNumberOfElements() {
return numberOfElements;
}
public void setNumberOfElements(int numberOfElements) {
this.numberOfElements = numberOfElements;
}
#Override
public long getTotalElements() {
return totalElements;
}
public void setTotalElements(long totalElements) {
this.totalElements = totalElements;
}
public boolean isPreviousPage() {
return previousPage;
}
public void setPreviousPage(boolean previousPage) {
this.previousPage = previousPage;
}
public boolean isFirstPage() {
return firstPage;
}
public void setFirstPage(boolean firstPage) {
this.firstPage = firstPage;
}
public boolean isNextPage() {
return nextPage;
}
public void setNextPage(boolean nextPage) {
this.nextPage = nextPage;
}
public boolean isLastPage() {
return lastPage;
}
public void setLastPage(boolean lastPage) {
this.lastPage = lastPage;
}
#Override
public List<T> getContent() {
return content;
}
public void setContent(List<T> content) {
this.content = content;
}
#Override
public Sort getSort() {
return sort;
}
public void setSort(Sort sort) {
this.sort = sort;
}
public Page<T> pageImpl() {
return new PageImpl<>(getContent(), new PageRequest(getNumber(),
getSize(), getSort()), getTotalElements());
}
}
I know this thread is a little old, but hopefully someone will benefit from this.
#Ali Dehghani's answer is good, except that it re-implements what PageImpl<T> has already done. I considered this to be rather needless. I found a better solution by creating a class that extends PageImpl<T> and specifies a #JsonCreator constructor:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.company.model.HelperModel;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import java.util.List;
public class HelperPage extends PageImpl<HelperModel> {
#JsonCreator
// Note: I don't need a sort, so I'm not including one here.
// It shouldn't be too hard to add it in tho.
public HelperPage(#JsonProperty("content") List<HelperModel> content,
#JsonProperty("number") int number,
#JsonProperty("size") int size,
#JsonProperty("totalElements") Long totalElements) {
super(content, new PageRequest(number, size), totalElements);
}
}
Then:
HelperPage page = restTemplate.getForObject(url, HelperPage.class);
This is the same as creating a CustomPageImpl<T> class but allows us to take advantage of all the code that's already in PageImpl<T>.
As "pathfinder" mentioned you can use exchange method of RestTemplate. However instead of passing ParameterizedTypeReference<Page<StoryResponse>>() you should pass ParameterizedTypeReference<PagedResources<StoryResponse>>(). When you get the response you could retrieve the content - Collection<StoryResponse>.
The code should look like this:
ResponseEntity<PagedResources<StoryResponse>> response = restTemplate.exchange(getLocalhost("/story"),
HttpMethod.GET, null, new ParameterizedTypeReference<PagedResources<StoryResponse>>() {});
PagedResources<StoryResponse> storiesResources = response.getBody();
Collection<StoryResponse> stories = storiesResources.getContent();
Apart from the content storiesResources holds page metadata and links too.
A more step-by-step explanation is available here: https://stackoverflow.com/a/46847429/8805916
If you use spring-cloud-openfeign you can use PageJacksonModule.
Just register PageJacksonModule in your object mapper:
final ObjectMapper mapper = new ObjectMapper()
mapper.registerModule(new PageJacksonModule());
If you looking at this thread, and if you try this answer
https://stackoverflow.com/a/44895867/8268335
You will meet the 2nd problem:
Can not construct instance of org.springframework.data.domain.Pageable
Then I find the perfect solution from here:
https://stackoverflow.com/a/42002709/8268335
I create the class RestPageImpl from the answer above and problem solved.
You can probably use exchange method of restTemplate and get the body from it..
Check the following answer https://stackoverflow.com/a/31947188/3800576.
This might help you

is my implementation of builder violates mutability

I'd like to know whether my implementation of QuestionBuilder violates mutability.
public class Question<T extends Serializable> implements Serializable {
private QuestionHolder<T> questionHolder;
private Question(QuestionHolder<T> questionHolder) {
this.questionHolder = questionHolder;
}
public String getId() {
return questionHolder.id;
}
public int getOrder() {
return questionHolder.order;
}
public QuestionType getType() {
return questionHolder.type;
}
public boolean isImmediate() {
return questionHolder.immediate;
}
public boolean isMandatory() {
return questionHolder.mandatory;
}
public List<T> getSelectedValues() {
return questionHolder.selectedValues;
}
public List<T> getPossibleValues() {
return questionHolder.possibleValues;
}
private static final class QuestionHolder<T extends Serializable> {
private String id;
private int order = 0;
private QuestionType type;
private boolean immediate;
private boolean mandatory;
private List<T> selectedValues;
private List<T> possibleValues;
}
public static final class QuestionBuilder<T extends Serializable> implements Builder<Question<T>> {
private QuestionHolder<T> questionHolder;
public QuestionBuilder(String id) {
questionHolder = new QuestionHolder<>();
questionHolder.id = id;
}
public QuestionBuilder withOrder(int order) {
questionHolder.order = order;
return this;
}
public QuestionBuilder withType(QuestionType questionType) {
questionHolder.type = questionType;
return this;
}
public QuestionBuilder withImmediate(boolean immediate) {
questionHolder.immediate = immediate;
return this;
}
public QuestionBuilder withMandatory(boolean mandatory) {
questionHolder.mandatory = mandatory;
return this;
}
public QuestionBuilder withSelectedValues(List<T> selectedValues) {
questionHolder.selectedValues = selectedValues;
return this;
}
public QuestionBuilder withPossibleValues(List<T> possibleValues) {
questionHolder.possibleValues = possibleValues;
return this;
}
public Question<T> build() {
Question<T> question = new Question<>(questionHolder);
questionHolder = null;
return question;
}
}
}
Or what should I adjust in order to resolve mutability issue. Any suggestions?
If you're worried about thread safety, then your code here is not necessarily thread safe.
It is possible that one thread calls build() and returns a Question pointing to a QuestionHolder. Even though build() sets the holder to null, another thread might not see that null, but instead see the old value of the field. If that other thread called any of your setters, it would potentially mutate the Holder that the Question class had already accessed.
In a single threaded application you would be fine.
As far as I can see, you are mutating the QuestionHolder with each builder call.
What I would do is:
1) Make all properties inside QuestionHolder private and don't create any setters at all.
2) Store each property inside the builder instance and create a new instance of QuestionHolder in the build method of the builder.
For example:
public Question<T> build() {
// DO ALL THE VALIDATIONS NEEDED
QuestionHolder holder = new QuestionHolder(id, order, type, inmediate, mandatory, selectedValues, possibleValues);
return new Question<>(questionHolder);
}
With these approach, you will be mutating the Builder, but that's ok for the Builder Pattern. You will obviously need to create a new Builder instance each time you want to create a Question. If you want to use the same Builder over and over again you will probably need to store some kind of structure inside it (a Map identified by Id, for example).

Categories

Resources