- 对于类:
如果我们使用工厂方法,我们必须将创建的实现作为已实现接口(interface)的类型返回。
public class Factory {
public Product getProduct() {
return new ProductA();
}
}
public interface Product {
}
class ProductA implements Product {
}
为了避免客户端将返回的产品转换为产品的具体实现{A、B、C...等},我们必须:
- 分别打包客户端和工厂的代码(比如
com.example.client
和com.example.factory
) - 声明具有默认(“包”)访问权限的具体实现(对工厂可见,对客户端不可见)
package com.example.client;
...
public class Client {
public static void main(String[] args) {
Product i = new Factory().getProduct();
ProductA a = (ProductA) i; // the type of ProductA isn't visible.
}
}
- 对于方法:
例如我们需要使用隐藏方法的同一个工厂
public class Factory {
public Product getProduct() {
return new ProductA();
}
Product[] getCreatedProducts() {
...
}
}
我在这里看到两个问题:
- 错误的包结构:隐藏的类和方法必须与调用代码位于同一个包中。
- 糟糕的代码:缺乏直观性和可理解性。将 java 文件替换为另一个包很容易中断。
最佳答案
“默认”访问并不能保证任何事情,因为任何流氓程序员都可以在您的包中声明他们的类。此外,无论您的包结构如何,在 Java 中,您几乎总是可以进行“实例”检查,然后向下转换为“实例”类型。因此,如果您的目标是防止任何向下转换,则必须使用 private
关键字。例如,您可以将 Product
接口(interface)的具体实现声明为 private static
或作为 Factory
中的匿名内部类。事实上,在 Bloch 的“如何设计一个好的 API”一文中,他提出了一个观点,即您应该“最小化所有内容的可访问性”。
也就是说,我认为您在这里有点偏执。如果有人沮丧,对你来说真的那么重要吗?您编写的任何代码都可能被滥用,当然,如果您包含一个文档齐全的工厂,那么您已经提供了有关如何正确使用 API 的明确信息。此外,如果您构建一个真正的工厂方法,它接受参数并具有明确的方法名称,而不是这个不接受参数的玩具 Factory
示例,那么我认为您会发现您正在广播正在创建的内容的公开相关部分。
关于java - 这是使用 "default"Java 访问对客户端隐藏类和方法的好做法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6775894/