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

标签 java performance date jakarta-ee time

据说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 标记了这个问题,因为这可能是业务应用程序中的常见问题。

最佳答案

旁白:每当我在问题中看到“良好实践”或“最佳实践”时,我都会觉得提问者正在寻找一种“千篇一律”的解决方案,让他/她能够< em>不去想问题/解决方案。

忽略“良好实践”问题……为“现在”使用多个不同日期实例的真正问题在于它在概念上是错误的。您有两个合乎逻辑的选择。要么将请求的“现在”建模为单个不可分割的时间点,要么将其建模为持续时间;例如对应于您的请求处理的开始和结束。第一种方法更简单,而更复杂的方法几乎不会提供任何实际好处。

基于以上所述,我认为最明智的概念上正确解决方案是让所有 API 方法都具有相同的“现在”。做到这一点的简单方法是让涉及“现在”的所有方法业务逻辑都采用明确的“现在”日期参数。调用者(例如您的 JSP)然后负责创建一个“现在”日期并在所有需要它的方法调用中一致地使用它。

这个解决方案最重要的特性是它是正确的。相比之下,每次您当前的方法之一执行 new Date 时,它都会获得略有不同的时间戳。如果您的应用程序在 Event 开始或结束的“风口浪尖”上运行,那么您可能会遇到意外行为。

我提出的解决方案也会影响性能和可读性......但正确性和可靠性应该胜过其他问题。

关于java - Java 中时间派生属性的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28143490/

相关文章:

javascript - 获取一周中的所有天数

java - CXF拦截器阶段用于清理MDC

javascript - .substr(0,1) 或 .charAt(0) 之间有什么区别?

java - 组织.postgresql.util.PSQLException : ERROR: relation "employee1" does not exist

algorithm - 有什么比蛮力更好的解决方案呢?

multithreading - 为什么线程越多这个程序越慢?

php - 如何将此日期转换为 Y-m-d (PHP)?

java - 如何将 RFC 3339 日期字符串解析为 ZonedDateTime?

java - PHP 客户端和 Java 服务器之间的客户端-服务器网络

java - 将自定义类和 JSP 添加到现有的第三方 Java Web 应用程序