QR code

File.exists or Files.fileExists?

  • Translated by to

你会如何设计一个抽象类,比如说,表示具有特定属性的磁盘上的文件?假设你需要能够检查文件是否存在于磁盘上或已被删除。你会首先创建一个对象,然后调用其exists()方法吗?还是你会首先调用Disk.fileExists(),只有在返回TRUE的情况下才创建File类的实例并继续使用它?这可能听起来像是一种品味问题,但实际上并不那么简单。

让我们看看如何在不同的编程语言及其SDK中检查文件是否存在于磁盘上:

基本上有两种不同的设计决策:要么您首先创建一个 File 对象,然后询问它在磁盘上是否存在,要么您询问磁盘文件是否存在,然后才创建 File 类的实例。哪种设计更好?让我们暂时忘记静态方法是不好的,想象一下 Files 不是一个实用类,而是一个磁盘的抽象。如果您是为新编程语言设计新 SDK 的设计师,您将如何设计 exists() 方法?

要回答这个问题,我们必须回答一个更基本的问题:通过将 exists() 方法放在 File 上还是放在 Disk 上,SDK 将向程序员传达什么信息?

对于一位经验丰富的程序员来说,这可能听起来像一个琐碎而表面的问题,但让我说服您这并非如此。考虑数据库中的付款账单列表的设计。账单可以是“已付款”或“尚未付款”,程序员可以通过 paid() 方法进行检查。第一个设计选择是这样的(这是 Java):

第二个选择是以下内容:

第一个片段中的信息是什么?我认为是这样的:“账单可能已支付,也可能未支付。”第二个设计选项中的信息是什么?是这样的:“如果账单存在,则已支付。”换句话说,在第一个片段中,账单的两个特性(“我存在”和“我已支付”)共存,而在第二个片段中,它们被合并为一个(“我已支付”)。

在持久层,这种特性的二分法可能意味着在SQL数据库表中的一个可空列paid,或者一个具有NOT NULL约束的列。第一个片段可能会返回一个在数据库中存在为一行的bill对象,但paid列被设置为NULL。使用您设计的程序员可以轻松理解账单的“已支付”状态的概念:它并不同于其存在的状态。程序员必须先获取账单,然后再检查其付款状态。程序员还期望可能出现两个失败点—账单可能不存在,或账单可能未支付—会抛出不同的异常或返回不同类型的结果。

正如您所看到的,这个问题不只是表面问题,而是非常存在的:BillBills方法的设计有助于程序员了解账单存在的条件。

现在,关于文件的exists()方法的原始问题的答案很容易找到。在磁盘上找到文件是第一个任务,它检查文件名是否正确,文件在磁盘上可能存在。

然后,检查文件在磁盘上的存在情况:

我们现在可以得出结论,Python、JS、Ruby等许多编程语言让我们检查硬盘上文件是否存在的方法是错误的。JDK 6是正确的,但JDK 8的发明者却毁了它(很可能是为了性能考虑)。

顺便说一句,在许多其他编程语言中还有许多不同的“文件检查”设计决策的例子

Translated by ChatGPT gpt-3.5-turbo/42 on 2024-07-08 at 05:14

sixnines availability badge   GitHub stars