首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中时间派生属性的最佳实践

Java中时间派生属性的最佳实践
EN

Stack Overflow用户
提问于 2015-01-26 09:08:09
回答 1查看 100关注 0票数 1

据说Java应用程序有过度请求当前时间的习惯。这是我十多年前写的一段代码:

代码语言:javascript
复制
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层的外观,其中应用了抽象和隐藏思想的实现:

代码语言:javascript
复制
<% 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标记了这个问题,因为这可能是业务应用程序中的常见问题。

EN

回答 1

Stack Overflow用户

发布于 2015-01-26 09:47:21

我想,如果你有某种想要的分辨率(比如5到10秒),你基本上可以创建一个单例对象,它将为你提供当前时间,并每5到10秒缓存一次。下面是对此的快速尝试。

代码语言:javascript
复制
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);
    }

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28143490

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档