据说Java应用程序有过度请求当前时间的习惯。这是我十多年前写的一段代码:
public class Event {
public String name;
public Date startTime;
public Date eventStartTime;
public Date presaleStopTime;
public Date presaleStartTime;
/** Specific start time set? */
public boolean isPresaleNotYetStarted() {
if (presaleStartTime == null) { return false;}
Date now = new Date();
return now.before(presaleStartTime);
}
/** Specific end time set? If not, presale starts immediately */
public boolean isPresaleTerminated() {
if (presaleStopTime == null) { return false; }
Date now = new Date();
return now.after(presaleStopTime);
}
Date getLatestPossibleShipmentDate() {
Date now = new Date();
Calendar c = Calendar.getInstance();
c.setTime(eventStartTime);
c.add(Calendar.DAY_OF_MONTH, -5);
return c.getTime();
}
/** The ticket can still be delivered to the customer */
public boolean isShipmentPossible() {
Date now = new Date();
return now.before(getLatestPossibleShipmentDate());
}
public boolean isTicketInPresale() {
return isShipmentPossible()
&& !isPresaleNotYetStarted()
&& !isPresaleTerminated();
}
}虽然这是一段关于可读性的完美制作的代码,但它显然在可测试性、一致性和性能方面存在一些问题。
为了使故事完整,下面是web层的外观,其中应用了抽象和隐藏思想的实现:
<% Event event = ...; %>
<% if (event.isTicketInPresale()) { %>
... display order button...
<% } else {
// display some meaningful reason to the customer,
// why ordering is not possible
if (event.isPresaleTerminated()) {
%>Sorry, presale is terminated<%
} else if (!event.isShipmentPossible() && new Date().before(event.startTime)) {
%>Sorry, shipment of the tickets is not possible any more.<%
} else if (!event.isPresaleNotYetStarted()) {
%>Presale not yet started, come back later<%
}
}
%>当这段代码运行时,它将请求当前时间大约8次,在最坏的情况下。
这方面的最佳实践解决方案或实现模式是什么?
我还用J2EE标记了这个问题,因为这可能是业务应用程序中的常见问题。
发布于 2015-01-26 09:47:21
我想,如果你有某种想要的分辨率(比如5到10秒),你基本上可以创建一个单例对象,它将为你提供当前时间,并每5到10秒缓存一次。下面是对此的快速尝试。
public class CacheDate {
private static final CacheDate instance = new CacheDate();
public static final long CACHE_INTERVAL = 10_000;
private final AtomicBoolean finished = new AtomicBoolean(false);
private volatile Date curDate;
private final Thread updateTime = new Thread() {
@Override
public void run() {
while (!finished.get()) {
try {
curDate = new Date();
Thread.sleep(CACHE_INTERVAL);
} catch (InterruptedException ex) {
}
}
}
};
private CacheDate() {
startUpdatingTime();
}
public static CacheDate getInstance() {
return instance;
}
public void stopUpdatingTime() {
finished.set(true);
updateTime.interrupt();
}
public void startUpdatingTime() {
finished.set(false);
updateTime.start();
}
public long getTime() {
return curDate.getTime();
}
public boolean after(Date when) {
return curDate.after(when);
}
public boolean before(Date when) {
return curDate.before(when);
}
}https://stackoverflow.com/questions/28143490
复制相似问题