I have a Java class called Project. It has three properties (among others): goal
, amountRaised
and percentageRaised
.
goal
is the amount of money the project aims to raise; amountRaised
is as the name implies amount raised so far; and percentageRaised
is the percentage of money raised relative to the goal.
I want percentageRaised
to be updated anytime either goal
or amountRaised
changes.
My question is, if I declare a setter method (private) for percentageRaised
, is it going to be calculated automatically or do I need to call it somewhere?
Alternatively, would it be bad practice to add the logic on initialisation like so:
public class Project {
@JsonProperty
private String id;
@NotBlank(message = "Please specify the amount of money you intend to raise")
@JsonProperty
private double goal;
@JsonProperty
private double amountRaised = 0;
@JsonProperty
private int percentageRaised = (int) ((amountRaised/goal) * 100);
}
CodePudding user response:
the easiest way is to execute a calculation method in the setter of both attributes.
public class Project {
@JsonProperty
private String id;
@NotBlank(message = "Please specify the amount of money you intend to raise")
@JsonProperty
private double goal;
@JsonProperty
private double amountRaised = 0;
@JsonProperty
private int percentageRaised = (int) ((amountRaised/goal) * 100);
public void setGoal(double goal) {
this.goal = goal;
this.calculatePercentageRaised();
}
public void setAmountRaised(double amountRaised) {
this.amountRaised = amountRaised;
this.calculatePercentageRaised();
}
private void calculatePercentageRaised() {
//check not null
if (amountRaised!=null && goal!=null && goal != 0) {
this.percentageRaised = (int) ((amountRaised/goal) * 100);
}
}
}
CodePudding user response:
This can be achieved with help of basic java beans PropertyChangeListener
package p1;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
public class Project implements PropertyChangeListener, Serializable {
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private String id;
private double goal = 1;
private double amountRaised = 0;
private double percentageRaised = 0;
public Project() {
pcs.addPropertyChangeListener(this);
}
public static void main(String[] args) {
Project project = new Project();
project.setAmountRaised(20);
System.out.printf("\n1: now, amountraised= is %f, goal is %f, percent is %f",
project.amountRaised, project.goal, project.percentageRaised);
project.setGoal(50);
System.out.printf("\n2: now, amountraised= is %f, goal is %f, percent is %f",
project.amountRaised, project.goal, project.percentageRaised);
project.setGoal(100);
System.out.printf("\n3: now, amountraised= is %f, goal is %f, percent is %f",
project.amountRaised, project.goal, project.percentageRaised);
}
public void setGoal(double goal) {
var old = this.goal;
this.goal = goal;
pcs.firePropertyChange("goal", old, goal);
}
public void setAmountRaised(double amountRaised) {
var old = this.amountRaised;
this.amountRaised = amountRaised;
pcs.firePropertyChange("amountRaised", old, amountRaised);
}
public void updatePercentageRaised() {
this.percentageRaised = ((amountRaised / goal) * 100);
;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
updatePercentageRaised();
}
}
Output:
1: now, amountraised= is 20.000000, goal is 1.000000, percent is 2000.000000
2: now, amountraised= is 20.000000, goal is 50.000000, percent is 40.000000
3: now, amountraised= is 20.000000, goal is 100.000000, percent is 20.000000
Ref: https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html.
https://kodejava.org/how-do-i-listen-for-beans-property-change-event/
CodePudding user response:
This is a simple approach for you.
You don't have to declare a field to record the percentageRaised
value:
// remove it
@JsonProperty
private int percentageRaised
just calculate it when you need it, like this:
@JsonGetter("percentageRaised")
public int getPercentageRaised() {
return (int) ((amountRaised/goal) * 100);
}
Thus, you don't need to care about dynamic update issue anymore. The percentageRaised
is always latest.