I have a system that operates with real-time events. The user can interject custom events at a specified interval. The real-time engine uses java.time.Duration to time the events. The user is presented a menu via jsp that has a specification of the Duration in (whole) seconds. The event list is serialized as Long values. So I have three ways of using the same value. I have created a value object that performs the conversions on each access so I don’t have to scatter the conversions throughout the code. I’m wondering whether there is a better way to accomplish this scenario. Here is my VO.
import java.time.Duration; public class PeriodicCommandVO { private String id; private String command; private Duration duration; private Long interval; private Long frequency; private boolean active; public String getCommand() { return command; } public void setCommand(String command) { this.command = command; } public Long getInterval() { if (interval == null) { if (duration != null) interval = duration.toMillis(); else { if (frequency != null) interval = frequency*1000; } } return interval; } public void setInterval(Long interval) { this.interval = interval; this.duration = Duration.ofMillis(interval); this.frequency = (interval+500)/1000; } public Duration getDuration() { if (duration == null) { if (interval != null) duration = Duration.ofMillis(interval); else { if (frequency != null) duration = Duration.ofMillis(frequency*1000); } } return duration; } public void setDuration(Duration duration) { this.duration = duration; this.interval = duration.toMillis(); this.frequency = (interval+500)/1000; } public Long getFrequency() { if (frequency == null) { if (duration != null) frequency = (duration.toMillis()+500)/1000; else { if (interval != null) frequency = (interval+500)/1000; } } return frequency; } public void setFrequency(Long frequency) { this.frequency = frequency; this.interval = frequency*1000; this.duration = Duration.ofSeconds(frequency); } public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
Advertisement
Answer
Moved the seconds-to-duration conversion logic to the constructor for the VO, so the VO can remain immutable. The jsp now can use the seconds value without conversion, and the controller will receive the value in seconds via the POST in the form. Reduced the variables in the VO to only store Duration (it’s the most general implementation). My VO now looks like this
import java.time.Duration; public class PeriodicCommandVO { private String id; private String command; private Duration duration; private boolean active; public PeriodicCommandVO (PeriodicCommandForm form) { this.id = form.getId(); this.command = form.getCommand(); this.duration = Duration.ofSeconds(form.getFrequency()); } public String getCommand() { return command; } public void setCommand(String command) { this.command = command; } public Duration getDuration() { return duration; } public void setDuration(Duration duration) { this.duration = duration; } public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
Additionally, I changed the serialization logic to store the Duration object using ObjectOutputStream.writeObject(), rather than the milliseconds using ObjectOutputStream.writeLong(). The result is that the only conversion between the different representations is in the VO constructor.